From 3195bcd9e4e7e5a2486c68b4555742118377ee4d Mon Sep 17 00:00:00 2001 From: Uladzimir Dzmitrachkou Date: Wed, 18 Dec 2024 10:38:57 +0100 Subject: [PATCH] enable promise rules --- .eslintrc.cjs | 12 +++++- src/ErrorElement.tsx | 3 +- src/components/ExperimentalBanner.tsx | 3 +- .../Layout/ActivityBar/HelpButton.tsx | 6 +-- .../ActivityBar/ProxyStatusIndicator.tsx | 5 +-- .../Layout/Sidebar/Sidebar.hooks.ts | 5 ++- src/components/Settings/LogsSettings.tsx | 6 +-- src/components/Settings/SettingsDialog.tsx | 5 +-- .../Settings/UsageReportSettings.tsx | 3 +- src/components/WebLogView/Group.tsx | 2 +- .../WebLogView/ResponseDetails/Font.tsx | 22 +++++----- src/hooks/useScriptPreview.ts | 2 + src/main.ts | 43 +++++++++++-------- src/preload.ts | 6 +-- src/views/Generator/Generator.hooks.ts | 2 +- src/views/Generator/Generator.utils.ts | 6 +-- src/views/Generator/ValidatorDialog.tsx | 2 + src/views/Validator/Validator.tsx | 4 +- 18 files changed, 70 insertions(+), 67 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index be5d497e..47a4e076 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -47,8 +47,16 @@ module.exports = { argsIgnorePattern: '^_', }, ], - '@typescript-eslint/no-floating-promises': 'off', - '@typescript-eslint/no-misused-promises': 'off', + '@typescript-eslint/no-floating-promises': [ + 'error', + { + ignoreIIFE: true, + }, + ], + '@typescript-eslint/no-misused-promises': [ + 'error', + { checksVoidReturn: false }, + ], }, parserOptions: { diff --git a/src/ErrorElement.tsx b/src/ErrorElement.tsx index 2434ef1a..cf05abae 100644 --- a/src/ErrorElement.tsx +++ b/src/ErrorElement.tsx @@ -10,11 +10,10 @@ import { css } from '@emotion/react' import GrotCrashed from '@/assets/grot-crashed.svg' import { ArrowLeftIcon } from '@radix-ui/react-icons' -const handleCreateIssue = () => { +const handleCreateIssue = () => window.studio.browser.openExternalLink( 'https://github.com/grafana/k6-studio/issues' ) -} const handleOpenLogs = () => { window.studio.log.openLogFolder() diff --git a/src/components/ExperimentalBanner.tsx b/src/components/ExperimentalBanner.tsx index 294fc01c..2a6145a0 100644 --- a/src/components/ExperimentalBanner.tsx +++ b/src/components/ExperimentalBanner.tsx @@ -1,11 +1,10 @@ import { ExclamationTriangleIcon } from '@radix-ui/react-icons' import { Flex, Text, Link } from '@radix-ui/themes' -const handleLinkClick = () => { +const handleLinkClick = () => window.studio.browser.openExternalLink( 'https://github.com/grafana/k6-studio/issues' ) -} export function ExperimentalBanner() { return ( diff --git a/src/components/Layout/ActivityBar/HelpButton.tsx b/src/components/Layout/ActivityBar/HelpButton.tsx index b0caa5e1..fe38730a 100644 --- a/src/components/Layout/ActivityBar/HelpButton.tsx +++ b/src/components/Layout/ActivityBar/HelpButton.tsx @@ -2,17 +2,15 @@ import { QuestionMarkCircledIcon } from '@radix-ui/react-icons' import { DropdownMenu, IconButton, Tooltip } from '@radix-ui/themes' export function HelpButton() { - const handleOpenDocs = () => { + const handleOpenDocs = () => window.studio.browser.openExternalLink( 'https://grafana.com/docs/k6-studio/' ) - } - const handleReportIssue = () => { + const handleReportIssue = () => window.studio.browser.openExternalLink( 'https://github.com/grafana/k6-studio/issues' ) - } const handleOpenApplicationLogs = () => { window.studio.log.openLogFolder() diff --git a/src/components/Layout/ActivityBar/ProxyStatusIndicator.tsx b/src/components/Layout/ActivityBar/ProxyStatusIndicator.tsx index b1b6a483..7521a709 100644 --- a/src/components/Layout/ActivityBar/ProxyStatusIndicator.tsx +++ b/src/components/Layout/ActivityBar/ProxyStatusIndicator.tsx @@ -18,11 +18,10 @@ export function ProxyStatusIndicator() { const setProxyStatus = useStudioUIStore((state) => state.setProxyStatus) useEffect(() => { - async function fetchProxyStatus() { + ;(async function fetchProxyStatus() { const status = await window.studio.proxy.getProxyStatus() setProxyStatus(status) - } - fetchProxyStatus() + })() return window.studio.proxy.onProxyStatusChange((status) => setProxyStatus(status) diff --git a/src/components/Layout/Sidebar/Sidebar.hooks.ts b/src/components/Layout/Sidebar/Sidebar.hooks.ts index dc71dbc5..fc0ab5d8 100644 --- a/src/components/Layout/Sidebar/Sidebar.hooks.ts +++ b/src/components/Layout/Sidebar/Sidebar.hooks.ts @@ -26,13 +26,14 @@ function useFolderContent() { const setFolderContent = useStudioUIStore((s) => s.setFolderContent) useEffect(() => { - window.studio.ui.getFiles().then((files) => { + ;(async () => { + const files = await window.studio.ui.getFiles() setFolderContent({ recordings: toFileMap(files.recordings), generators: toFileMap(files.generators), scripts: toFileMap(files.scripts), }) - }) + })() }, [setFolderContent]) useEffect( diff --git a/src/components/Settings/LogsSettings.tsx b/src/components/Settings/LogsSettings.tsx index 34b1c637..83ee165f 100644 --- a/src/components/Settings/LogsSettings.tsx +++ b/src/components/Settings/LogsSettings.tsx @@ -17,13 +17,11 @@ export function LogsSettings() { // retrieve the current content of the log file useEffect(() => { - async function fetchLogContent() { + ;(async function fetchLogContent() { const content = await window.studio.log.getLogContent() setLogContent(content) scrollToLastLine() - } - - fetchLogContent() + })() }, [scrollToLastLine]) // subscribe to log changes diff --git a/src/components/Settings/SettingsDialog.tsx b/src/components/Settings/SettingsDialog.tsx index bea6ff6f..c53b6565 100644 --- a/src/components/Settings/SettingsDialog.tsx +++ b/src/components/Settings/SettingsDialog.tsx @@ -46,11 +46,10 @@ export const SettingsDialog = ({ open, onOpenChange }: SettingsDialogProps) => { const [selectedTab, setSelectedTab] = useState('proxy') useEffect(() => { - async function fetchSettings() { + ;(async function fetchSettings() { const data = await window.studio.settings.getSettings() setSettings(data) - } - fetchSettings() + })() }, []) const formMethods = useForm({ diff --git a/src/components/Settings/UsageReportSettings.tsx b/src/components/Settings/UsageReportSettings.tsx index 170e827b..3ff2a9aa 100644 --- a/src/components/Settings/UsageReportSettings.tsx +++ b/src/components/Settings/UsageReportSettings.tsx @@ -6,11 +6,10 @@ import { AppSettings } from '@/types/settings' export const UsageReportSettings = () => { const { control, register } = useFormContext() - const handleLinkClick = () => { + const handleLinkClick = () => window.studio.browser.openExternalLink( 'https://grafana.com/docs/k6-studio/set-up/usage-collection/' ) - } return ( diff --git a/src/components/WebLogView/Group.tsx b/src/components/WebLogView/Group.tsx index 24b42edc..46220f9a 100644 --- a/src/components/WebLogView/Group.tsx +++ b/src/components/WebLogView/Group.tsx @@ -95,7 +95,7 @@ export function Group({ useClickAway(headerRef, () => { if (!group.isEditing) return - handleSubmit(submit)() + return handleSubmit(submit)() }) const isValidName = (value: string) => { diff --git a/src/components/WebLogView/ResponseDetails/Font.tsx b/src/components/WebLogView/ResponseDetails/Font.tsx index 17f387c3..0310f57b 100644 --- a/src/components/WebLogView/ResponseDetails/Font.tsx +++ b/src/components/WebLogView/ResponseDetails/Font.tsx @@ -6,19 +6,17 @@ export function Font({ url }: { url: string }) { const [isReady, setIsReady] = useState(false) const [name, setName] = useState('') - async function addFontFace(url: string) { - const name = uniqueId('font-') - const font = new FontFace(name, `url(${url})`) - - await font.load() - document.fonts.add(font) - setIsReady(true) - setName(name) - } - useEffect(() => { - setIsReady(false) - addFontFace(url) + ;(async function addFontFace(url: string) { + setIsReady(false) + const name = uniqueId('font-') + const font = new FontFace(name, `url(${url})`) + + await font.load() + document.fonts.add(font) + setIsReady(true) + setName(name) + })(url) }, [url]) if (!isReady) { diff --git a/src/hooks/useScriptPreview.ts b/src/hooks/useScriptPreview.ts index c68eaf7d..7b20e2b9 100644 --- a/src/hooks/useScriptPreview.ts +++ b/src/hooks/useScriptPreview.ts @@ -30,6 +30,8 @@ export function useScriptPreview() { }, 100) // Initial preview generation + // TODO: https://github.com/grafana/k6-studio/issues/277 + // eslint-disable-next-line @typescript-eslint/no-floating-promises updatePreview(useGeneratorStore.getState()) const unsubscribe = useGeneratorStore.subscribe((state) => diff --git a/src/main.ts b/src/main.ts index 2e033de0..6beec69f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -158,9 +158,9 @@ const createWindow = async () => { // and load the index.html of the app. if (MAIN_WINDOW_VITE_DEV_SERVER_URL) { - mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL) + await mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL) } else { - mainWindow.loadFile( + await mainWindow.loadFile( path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`) ) } @@ -195,16 +195,21 @@ const createWindow = async () => { return mainWindow } -app.whenReady().then(async () => { - await initSettings() - appSettings = await getSettings() - nativeTheme.themeSource = appSettings.appearance.theme +app.whenReady().then( + async () => { + await initSettings() + appSettings = await getSettings() + nativeTheme.themeSource = appSettings.appearance.theme - await sendReport(appSettings.usageReport) - await createSplashWindow() - await setupProjectStructure() - await createWindow() -}) + await sendReport(appSettings.usageReport) + await createSplashWindow() + await setupProjectStructure() + await createWindow() + }, + (error) => { + log.error(error) + } +) // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits @@ -228,14 +233,14 @@ app.on('before-quit', async () => { // stop watching files to avoid crash on exit appShuttingDown = true await watcher.close() - stopProxyProcess() + return stopProxyProcess() }) -ipcMain.handle('app:change-route', (_, route: string) => { +ipcMain.on('app:change-route', (_, route: string) => { currentClientRoute = route }) -ipcMain.handle('app:close', (event) => { +ipcMain.on('app:close', (event) => { console.log('app:close event received') wasAppClosedByClient = true @@ -567,10 +572,10 @@ ipcMain.on('splashscreen:close', (event) => { ipcMain.handle('browser:open:external:link', (_, url: string) => { console.info('browser:open:external:link event received') - shell.openExternal(url) + return shell.openExternal(url) }) -ipcMain.handle('log:open', () => { +ipcMain.on('log:open', () => { console.info('log:open event received') openLogFolder() }) @@ -593,7 +598,7 @@ ipcMain.handle('settings:save', async (event, data: AppSettings) => { // don't pass fields that are not submitted by the form const { windowState: _, ...settings } = data const modifiedSettings = await saveSettings(settings) - applySettings(modifiedSettings, browserWindow) + await applySettings(modifiedSettings, browserWindow) sendToast(browserWindow.webContents, { title: 'Settings saved successfully', @@ -714,7 +719,7 @@ function showWindow(browserWindow: BrowserWindow) { browserWindow.focus() } -function trackWindowState(browserWindow: BrowserWindow) { +async function trackWindowState(browserWindow: BrowserWindow) { const { width, height, x, y } = browserWindow.getBounds() const isMaximized = browserWindow.isMaximized() appSettings.windowState = { @@ -725,7 +730,7 @@ function trackWindowState(browserWindow: BrowserWindow) { isMaximized, } try { - saveSettings(appSettings) + await saveSettings(appSettings) } catch (error) { log.error(error) } diff --git a/src/preload.ts b/src/preload.ts index 45f202e4..be844c84 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -161,16 +161,16 @@ const app = { return createListener('app:close', callback) }, closeApplication: () => { - ipcRenderer.invoke('app:close') + ipcRenderer.send('app:close') }, changeRoute: (route: string) => { - return ipcRenderer.invoke('app:change-route', route) + return ipcRenderer.send('app:change-route', route) }, } as const const log = { openLogFolder: () => { - ipcRenderer.invoke('log:open') + ipcRenderer.send('log:open') }, getLogContent: (): Promise => { return ipcRenderer.invoke('log:read') diff --git a/src/views/Generator/Generator.hooks.ts b/src/views/Generator/Generator.hooks.ts index af6d1e1f..448f5038 100644 --- a/src/views/Generator/Generator.hooks.ts +++ b/src/views/Generator/Generator.hooks.ts @@ -52,7 +52,7 @@ export function useSaveGeneratorFile(fileName: string) { return useMutation({ mutationFn: async (generator: GeneratorFileData) => { await writeGeneratorToFile(fileName, generator) - queryClient.invalidateQueries({ queryKey: ['generator', fileName] }) + await queryClient.invalidateQueries({ queryKey: ['generator', fileName] }) }, onSuccess: () => { diff --git a/src/views/Generator/Generator.utils.ts b/src/views/Generator/Generator.utils.ts index 7a92cae1..412a5ad8 100644 --- a/src/views/Generator/Generator.utils.ts +++ b/src/views/Generator/Generator.utils.ts @@ -22,17 +22,13 @@ export async function generateScriptPreview( return prettify(script) } -export function saveScript(script: string, fileName: string) { - window.studio.script.saveScript(script, fileName) -} - export async function exportScript(fileName: string) { const generator = selectGeneratorData(useGeneratorStore.getState()) const filteredRequests = selectFilteredRequests(useGeneratorStore.getState()) const script = await generateScriptPreview(generator, filteredRequests) - saveScript(script, fileName) + await window.studio.script.saveScript(script, fileName) } export const scriptExists = async (fileName: string) => { diff --git a/src/views/Generator/ValidatorDialog.tsx b/src/views/Generator/ValidatorDialog.tsx index 7ab0c1bf..3aedd1b4 100644 --- a/src/views/Generator/ValidatorDialog.tsx +++ b/src/views/Generator/ValidatorDialog.tsx @@ -58,6 +58,8 @@ export function ValidatorDialog({ useEffect(() => { if (!open) return + // TODO: https://github.com/grafana/k6-studio/issues/277 + // eslint-disable-next-line @typescript-eslint/no-floating-promises handleRunScript() }, [open, handleRunScript]) diff --git a/src/views/Validator/Validator.tsx b/src/views/Validator/Validator.tsx index 85e614f1..2085ae4c 100644 --- a/src/views/Validator/Validator.tsx +++ b/src/views/Validator/Validator.tsx @@ -60,7 +60,7 @@ export function Validator() { navigate(getRoutePath('home')) } - function handleRunScript() { + async function handleRunScript() { if (!scriptPath) { return } @@ -68,8 +68,8 @@ export function Validator() { resetProxyData() resetLogs() resetChecks() - window.studio.script.runScript(scriptPath, isExternal) setIsRunning(true) + await window.studio.script.runScript(scriptPath, isExternal) } function handleStopScript() {