From 3e56bc925f6dcc66cdd3ad9bc63f6aa86ed6da76 Mon Sep 17 00:00:00 2001 From: Glary-Bot Date: Wed, 20 May 2026 05:34:54 +0000 Subject: [PATCH] lint: enable oxlint func-style rule and convert function expressions Enables eslint/func-style in oxlint with declaration mode to enforce function declarations over function expressions and arrow expressions assigned to variables. Vendored litegraph is excluded via override. Converts existing function expressions and variable-initialized arrow functions to function declarations across src/, browser_tests/, apps/, packages/, and scripts/. Adjusts a handful of let-reassignable callback placeholders, narrowed variable patterns, and typed widget constructors to keep type safety intact. Pre-existing type-aware oxlint errors (no-console, no-floating-promises, no-explicit-any) are unchanged from main. --- .oxlintrc.json | 7 + .storybook/preview.ts | 2 +- apps/desktop-ui/.storybook/preview.ts | 2 +- .../tabs/terminal/BaseTerminal.vue | 4 +- .../src/components/common/UrlInput.vue | 13 +- .../install/DesktopSettingsConfiguration.vue | 2 +- .../install/InstallLocationPicker.vue | 16 +- .../components/install/MigrationPicker.vue | 4 +- .../components/maintenance/TaskListItem.vue | 2 +- .../components/maintenance/TaskListPanel.vue | 4 +- .../maintenance/TerminalOutputDrawer.vue | 6 +- .../bottomPanelTabs/useTerminal.ts | 6 +- .../bottomPanelTabs/useTerminalBuffer.ts | 10 +- .../src/constants/desktopMaintenanceTasks.ts | 2 +- .../src/stores/maintenanceTaskStore.ts | 12 +- .../src/utils/electronMirrorCheck.ts | 2 +- .../src/views/DesktopDialogView.vue | 2 +- .../src/views/DesktopUpdateView.vue | 2 +- apps/desktop-ui/src/views/DownloadGitView.vue | 4 +- .../src/views/InstallView.stories.ts | 5 +- apps/desktop-ui/src/views/InstallView.vue | 10 +- .../src/views/MaintenanceView.stories.ts | 12 +- apps/desktop-ui/src/views/MaintenanceView.vue | 4 +- .../src/views/ManualConfigurationView.vue | 4 +- .../src/views/MetricsConsentView.vue | 2 +- .../desktop-ui/src/views/NotSupportedView.vue | 6 +- apps/desktop-ui/src/views/ServerStartView.vue | 18 +- apps/desktop-ui/src/views/WelcomeView.vue | 2 +- apps/website/e2e/demos.spec.ts | 5 +- apps/website/e2e/responsive.spec.ts | 6 +- .../src/components/careers/RolesSection.vue | 4 +- .../components/product/local/HeroSection.vue | 4 +- apps/website/src/composables/useParallax.ts | 2 +- apps/website/src/composables/usePinScrub.ts | 2 +- .../pages/cloud/supported-nodes/[pack].astro | 2 +- apps/website/src/pages/customers/[slug].astro | 2 +- apps/website/src/pages/demos/[slug].astro | 2 +- .../src/pages/p/supported-models/[slug].astro | 2 +- .../zh-CN/cloud/supported-nodes/[pack].astro | 2 +- .../src/pages/zh-CN/customers/[slug].astro | 2 +- .../src/pages/zh-CN/demos/[slug].astro | 2 +- apps/website/src/scripts/snakeGame.ts | 41 ++-- browser_tests/fixtures/helpers/AssetHelper.ts | 2 +- .../fixtures/helpers/AssetsHelper.ts | 2 +- .../fixtures/helpers/NodeReplacementHelper.ts | 2 +- .../fixtures/helpers/SubgraphHelper.ts | 2 +- .../fixtures/helpers/TemplateHelper.ts | 2 +- .../fixtures/sharedWorkflowImportFixture.ts | 4 +- .../fixtures/utils/litegraphUtils.ts | 2 +- browser_tests/tests/actionbar.spec.ts | 6 +- .../tests/canvasLayoutSettings.spec.ts | 29 +-- .../tests/canvasModeSelector.spec.ts | 14 +- browser_tests/tests/canvasSettings.spec.ts | 11 +- browser_tests/tests/changeTracker.spec.ts | 6 +- .../tests/defaultKeybindings.spec.ts | 5 +- browser_tests/tests/dialog.spec.ts | 2 +- browser_tests/tests/groupCopyPaste.spec.ts | 5 +- browser_tests/tests/groupNode.spec.ts | 12 +- browser_tests/tests/imageCompare.spec.ts | 2 +- browser_tests/tests/interaction.spec.ts | 26 ++- .../tests/load3d/gizmoControls.spec.ts | 5 +- browser_tests/tests/load3d/load3d.spec.ts | 4 +- browser_tests/tests/nodeHelp.spec.ts | 2 +- browser_tests/tests/nodeSearchBox.spec.ts | 4 +- browser_tests/tests/nodeSearchBoxV2.spec.ts | 15 +- .../tests/nodeSearchBoxV2Extended.spec.ts | 4 +- browser_tests/tests/painter.spec.ts | 5 +- .../errorsTabMissingMediaRuntime.spec.ts | 4 +- .../tests/queueNotificationBanners.spec.ts | 4 +- browser_tests/tests/remoteWidgets.spec.ts | 12 +- browser_tests/tests/selectionToolbox.spec.ts | 17 +- .../tests/selectionToolboxSubmenus.spec.ts | 5 +- .../sidebar/sidebarSplitterWidth.spec.ts | 5 +- .../tests/subgraph/subgraphBreadcrumb.spec.ts | 2 +- .../tests/subgraph/subgraphPromotion.spec.ts | 12 +- .../subgraph/subgraphSerialization.spec.ts | 9 +- .../tests/subgraph/subgraphZeroUuid.spec.ts | 2 +- .../tests/versionMismatchWarnings.spec.ts | 4 +- .../tests/vueNodes/groups/groups.spec.ts | 2 +- .../links/linkInteraction.spec.ts | 5 +- .../vueNodes/interactions/node/move.spec.ts | 27 ++- .../tests/vueNodes/widgets/legacy.spec.ts | 5 +- .../text/multilineStringWidget.spec.ts | 12 +- browser_tests/tests/widget.spec.ts | 10 +- .../tests/workflowPersistence.spec.ts | 10 +- browser_tests/utils/backupUtils.ts | 8 +- .../shared-frontend-utils/src/formatUtil.ts | 25 ++- .../shared-frontend-utils/src/networkUtil.ts | 2 +- scripts/check-unused-i18n-keys.ts | 5 +- scripts/collect-i18n-general.ts | 2 +- scripts/size-report.js | 4 +- src/App.vue | 2 +- src/base/common/downloadUtil.ts | 2 +- src/base/credits/comfyCredits.ts | 65 +++--- src/base/wheelGestures.ts | 11 +- src/components/MenuHamburger.vue | 2 +- src/components/TopMenuSection.test.ts | 8 +- src/components/TopMenuSection.vue | 2 +- src/components/actionbar/BatchCountEdit.vue | 19 +- .../actionbar/ComfyActionbar.test.ts | 6 +- src/components/actionbar/ComfyActionbar.vue | 18 +- .../ComfyRunButton/ComfyQueueButton.vue | 2 +- src/components/bottomPanel/BottomPanel.vue | 8 +- .../tabs/shortcuts/ShortcutsList.vue | 4 +- .../tabs/terminal/BaseTerminal.vue | 4 +- .../tabs/terminal/CommandTerminal.vue | 4 +- .../tabs/terminal/LogsTerminal.test.ts | 7 +- .../tabs/terminal/LogsTerminal.vue | 4 +- .../breadcrumb/SubgraphBreadcrumb.vue | 2 +- .../breadcrumb/SubgraphBreadcrumbItem.vue | 11 +- src/components/builder/AppModeWidgetList.vue | 4 +- .../builder/useAppModeWidgetResizing.ts | 7 +- src/components/card/Card.stories.ts | 48 ++-- .../common/BackgroundImageUpload.vue | 8 +- src/components/common/CustomizationDialog.vue | 4 +- src/components/common/DeviceInfo.vue | 2 +- src/components/common/ExtensionSlot.vue | 2 +- src/components/common/FormImageUpload.vue | 6 +- src/components/common/InputKnob.vue | 4 +- src/components/common/InputSlider.vue | 2 +- src/components/common/LazyImage.vue | 4 +- src/components/common/TreeExplorer.vue | 27 +-- .../common/TreeExplorerTreeNode.vue | 7 +- src/components/common/TreeExplorerV2Node.vue | 2 +- src/components/common/UrlInput.vue | 13 +- src/components/common/UserAvatar.vue | 2 +- src/components/common/UserCredit.test.ts | 2 +- .../widget/WorkflowTemplateSelectorDialog.vue | 23 +- .../dialog/UnloadWindowConfirmDialog.vue | 2 +- .../dialog/content/ApiNodesSignInContent.vue | 2 +- .../content/ConfirmationDialogContent.vue | 22 +- .../dialog/content/ErrorDialogContent.vue | 6 +- .../dialog/content/SignInContent.vue | 10 +- .../dialog/content/UpdatePasswordContent.vue | 2 +- .../content/setting/CurrentUserMessage.vue | 2 +- .../content/setting/LegacyCreditsPanel.vue | 10 +- .../dialog/content/setting/UsageLogsTable.vue | 6 +- .../dialog/content/signin/ApiKeyForm.vue | 2 +- .../dialog/content/signin/SignInForm.vue | 4 +- src/components/graph/CanvasModeSelector.vue | 4 +- src/components/graph/DomWidgets.vue | 2 +- src/components/graph/GraphCanvas.vue | 2 +- src/components/graph/GraphCanvasMenu.vue | 4 +- src/components/graph/NodeContextMenu.vue | 2 +- src/components/graph/NodeTooltip.vue | 2 +- src/components/graph/TitleEditor.vue | 4 +- .../graph/modals/ZoomControlsModal.vue | 12 +- .../graph/selectionToolbox/BypassButton.vue | 2 +- .../selectionToolbox/ColorPickerButton.vue | 11 +- .../selectionToolbox/ConfigureSubgraph.vue | 2 +- .../selectionToolbox/ExecuteButton.test.ts | 2 +- .../graph/selectionToolbox/ExecuteButton.vue | 6 +- .../graph/selectionToolbox/InfoButton.test.ts | 4 +- .../graph/selectionToolbox/InfoButton.vue | 2 +- .../selectionToolbox/Load3DViewerButton.vue | 2 +- .../selectionToolbox/MaskEditorButton.test.ts | 5 +- .../selectionToolbox/MaskEditorButton.vue | 2 +- .../selectionToolbox/NodeOptionsButton.vue | 2 +- .../graph/selectionToolbox/SubmenuPopover.vue | 8 +- src/components/graph/widgets/DomWidget.vue | 4 +- .../graph/widgets/TextPreviewWidget.test.ts | 6 +- .../helpcenter/HelpCenterMenuContent.vue | 31 ++- src/components/load3d/Load3DControls.vue | 18 +- src/components/load3d/Load3dViewerContent.vue | 2 +- .../load3d/controls/CameraControls.vue | 2 +- .../load3d/controls/GizmoControls.vue | 6 +- .../load3d/controls/PopupSlider.vue | 4 +- .../load3d/controls/SceneControls.vue | 14 +- .../load3d/controls/ViewerControls.vue | 2 +- .../controls/viewer/ViewerExportControls.vue | 2 +- .../controls/viewer/ViewerSceneControls.vue | 8 +- src/components/maskeditor/BrushCursor.test.ts | 23 +- .../maskeditor/BrushSettingsPanel.test.ts | 41 ++-- .../maskeditor/BrushSettingsPanel.vue | 4 +- .../ColorSelectSettingsPanel.test.ts | 5 +- .../maskeditor/ColorSelectSettingsPanel.vue | 14 +- .../ImageLayerSettingsPanel.test.ts | 18 +- .../maskeditor/ImageLayerSettingsPanel.vue | 12 +- .../maskeditor/MaskEditorContent.test.ts | 15 +- .../maskeditor/MaskEditorContent.vue | 4 +- .../PaintBucketSettingsPanel.test.ts | 5 +- .../maskeditor/PaintBucketSettingsPanel.vue | 4 +- src/components/maskeditor/PointerZone.test.ts | 15 +- src/components/maskeditor/PointerZone.vue | 18 +- src/components/maskeditor/ToolPanel.test.ts | 12 +- src/components/maskeditor/ToolPanel.vue | 4 +- .../controls/DropdownControl.test.ts | 4 +- .../maskeditor/controls/DropdownControl.vue | 2 +- .../maskeditor/controls/SliderControl.test.ts | 6 +- .../maskeditor/controls/SliderControl.vue | 2 +- .../maskeditor/controls/ToggleControl.test.ts | 4 +- .../maskeditor/controls/ToggleControl.vue | 2 +- .../maskeditor/dialog/TopBarHeader.test.ts | 9 +- .../maskeditor/dialog/TopBarHeader.vue | 20 +- src/components/node/NodePreview.vue | 5 +- .../queue/JobHistoryActionsMenu.test.ts | 5 +- .../queue/JobHistoryActionsMenu.vue | 6 +- .../queue/QueueNotificationBanner.stories.ts | 9 +- .../queue/QueueOverlayActive.test.ts | 5 +- src/components/queue/QueueOverlayExpanded.vue | 8 +- .../queue/QueueOverlayHeader.test.ts | 5 +- src/components/queue/QueueProgressOverlay.vue | 12 +- .../queue/dialogs/QueueClearHistoryDialog.vue | 4 +- .../queue/job/JobAssetsList.test.ts | 34 +-- .../queue/job/JobContextMenu.test.ts | 29 +-- .../queue/job/JobDetailsPopover.vue | 11 +- src/components/queue/job/JobFilterActions.vue | 15 +- src/components/queue/job/JobFilterTabs.vue | 2 +- .../queue/job/useJobErrorReporting.test.ts | 9 +- .../queue/job/useJobErrorReporting.ts | 8 +- .../queue/job/useQueueEstimates.test.ts | 32 +-- src/components/queue/job/useQueueEstimates.ts | 11 +- .../errors/swapNodeGroups.test.ts | 4 +- .../errors/useErrorGroups.test.ts | 4 +- .../errors/useErrorReport.test.ts | 3 +- src/components/rightSidePanel/shared.test.ts | 20 +- src/components/searchbox/NodeSearchBox.vue | 14 +- src/components/searchbox/NodeSearchFilter.vue | 4 +- .../v2/NodeSearchCategorySidebar.test.ts | 5 +- .../v2/NodeSearchCategorySidebar.vue | 4 +- .../searchbox/v2/NodeSearchContent.test.ts | 12 +- .../searchbox/v2/NodeSearchFilterBar.test.ts | 5 +- src/components/sidebar/ComfyMenuButton.vue | 20 +- src/components/sidebar/SideToolbar.vue | 4 +- .../SidebarBottomPanelToggleButton.vue | 2 +- src/components/sidebar/SidebarLogoutIcon.vue | 2 +- .../sidebar/SidebarSettingsButton.vue | 2 +- .../sidebar/SidebarShortcutsToggleButton.vue | 2 +- .../sidebar/SidebarTemplatesButton.vue | 2 +- .../tabs/AssetsSidebarListView.test.ts | 17 +- .../sidebar/tabs/AssetsSidebarTab.vue | 30 +-- .../tabs/BaseWorkflowsSidebarTab.test.ts | 19 +- .../sidebar/tabs/BaseWorkflowsSidebarTab.vue | 15 +- .../sidebar/tabs/JobHistorySidebarTab.vue | 8 +- .../sidebar/tabs/ModelLibrarySidebarTab.vue | 4 +- .../sidebar/tabs/NodeLibrarySidebarTab.vue | 18 +- .../tabs/modelLibrary/DownloadItem.vue | 19 +- .../tabs/modelLibrary/ModelTreeLeaf.vue | 6 +- .../nodeLibrary/NodeBookmarkTreeExplorer.vue | 48 ++-- .../tabs/nodeLibrary/NodeTreeFolder.vue | 4 +- .../sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue | 12 +- .../sidebar/tabs/queue/MediaLightbox.test.ts | 2 +- .../tabs/workflows/WorkflowTreeLeaf.vue | 2 +- src/components/tab/TabList.stories.ts | 2 +- .../thumbnails/CompareSliderThumbnail.test.ts | 4 +- .../thumbnails/HoverDissolveThumbnail.test.ts | 2 +- .../toast/RerouteMigrationToast.vue | 2 +- src/components/topbar/CurrentUserButton.vue | 4 +- .../topbar/CurrentUserPopoverLegacy.vue | 16 +- src/components/topbar/LoginButton.vue | 6 +- src/components/topbar/TopbarBadge.vue | 2 +- src/components/topbar/WorkflowTab.vue | 16 +- src/components/topbar/WorkflowTabPopover.vue | 8 +- src/components/topbar/WorkflowTabs.vue | 24 +- .../ui/search-input/AsyncSearchInput.test.ts | 5 +- .../ui/select/SelectDropdown.stories.ts | 4 +- src/components/ui/slider/Slider.vue | 2 +- .../widget/layout/BaseModalLayout.stories.ts | 208 +++++++++--------- .../widget/layout/BaseModalLayout.vue | 4 +- src/components/widget/nav/NavItem.vue | 2 +- src/components/widget/nav/NavTitle.vue | 2 +- src/components/widget/panel/LeftSidePanel.vue | 2 +- src/composables/auth/useAuthActions.ts | 8 +- src/composables/auth/useCurrentUser.ts | 18 +- src/composables/billing/useBillingContext.ts | 4 +- .../bottomPanelTabs/useLogsTerminal.ts | 4 +- .../bottomPanelTabs/useShortcutsTab.ts | 2 +- .../bottomPanelTabs/useTerminal.ts | 6 +- .../canvas/useSelectedLiteGraphItems.ts | 16 +- .../canvas/useSelectionToolboxPosition.ts | 10 +- .../element/useAbsolutePosition.ts | 4 +- .../element/useCanvasPositionConversion.ts | 8 +- src/composables/element/useDomClipping.ts | 10 +- .../element/useOverflowObserver.ts | 18 +- .../functional/useChainCallback.test.ts | 4 +- .../graph/contextMenuConverter.test.ts | 5 +- src/composables/graph/contextMenuConverter.ts | 2 +- src/composables/graph/useCanvasRefresh.ts | 2 +- src/composables/graph/useFrameNodes.ts | 2 +- src/composables/graph/useGraphNodeManager.ts | 24 +- src/composables/graph/useGroupMenuOptions.ts | 144 ++++++------ src/composables/graph/useImageMenuOptions.ts | 10 +- src/composables/graph/useMoreOptionsMenu.ts | 2 +- src/composables/graph/useNodeArrangement.ts | 4 +- src/composables/graph/useNodeCustomization.ts | 13 +- src/composables/graph/useNodeMenuOptions.ts | 140 ++++++------ .../graph/useSelectedNodeActions.ts | 10 +- .../graph/useSelectionMenuOptions.ts | 90 ++++---- .../graph/useSelectionOperations.ts | 10 +- src/composables/graph/useSelectionState.ts | 11 +- .../graph/useSubgraphOperations.ts | 15 +- src/composables/graph/useVueNodeLifecycle.ts | 8 +- src/composables/maskeditor/splineUtils.ts | 6 +- .../maskeditor/useBrushPersistence.test.ts | 4 +- .../maskeditor/useCanvasHistory.test.ts | 4 +- .../maskeditor/useCanvasHistory.ts | 16 +- .../maskeditor/useCanvasManager.ts | 12 +- src/composables/maskeditor/useCanvasTools.ts | 58 +++-- .../maskeditor/useCanvasTransform.test.ts | 14 +- .../maskeditor/useCanvasTransform.ts | 22 +- .../maskeditor/useCoordinateTransform.test.ts | 6 +- .../maskeditor/useCoordinateTransform.ts | 4 +- src/composables/maskeditor/useImageLoader.ts | 2 +- .../maskeditor/useKeyboard.test.ts | 6 +- src/composables/maskeditor/useKeyboard.ts | 12 +- .../maskeditor/useMaskEditor.test.ts | 7 +- src/composables/maskeditor/useMaskEditor.ts | 2 +- .../maskeditor/useMaskEditorLoader.ts | 2 +- .../maskeditor/useMaskEditorSaver.ts | 2 +- src/composables/maskeditor/usePanAndZoom.ts | 46 ++-- .../maskeditor/useToolManager.test.ts | 6 +- src/composables/maskeditor/useToolManager.ts | 12 +- src/composables/node/useNodeBadge.ts | 4 +- src/composables/node/useNodeDragAndDrop.ts | 24 +- src/composables/node/useNodeImage.ts | 42 ++-- src/composables/node/useNodeImageUpload.ts | 21 +- src/composables/node/useNodePaste.ts | 6 +- src/composables/node/useNodePricing.test.ts | 32 +-- src/composables/node/useNodePricing.ts | 147 +++++++------ src/composables/node/useNodeProgressText.ts | 10 +- src/composables/node/usePriceBadge.ts | 2 +- src/composables/node/useWatchWidget.test.ts | 4 +- src/composables/node/useWatchWidget.ts | 4 +- src/composables/queue/useJobList.test.ts | 42 ++-- src/composables/queue/useJobList.ts | 35 +-- src/composables/queue/useJobMenu.test.ts | 46 ++-- src/composables/queue/useJobMenu.ts | 30 +-- .../queue/useQueueClearHistoryDialog.ts | 4 +- .../queue/useQueueNotificationBanners.test.ts | 21 +- .../queue/useQueueNotificationBanners.ts | 67 +++--- .../queue/useQueueProgress.test.ts | 22 +- .../queue/useResultGallery.test.ts | 36 +-- .../sidebarTabs/useAssetsSidebarTab.ts | 2 +- .../sidebarTabs/useJobHistorySidebarTab.ts | 2 +- .../sidebarTabs/useModelLibrarySidebarTab.ts | 2 +- .../tree/useTreeFolderOperations.ts | 10 +- src/composables/useBrowserTabTitle.ts | 2 +- src/composables/useCachedRequest.test.ts | 2 +- src/composables/useCachedRequest.ts | 14 +- src/composables/useCanvasDrop.ts | 2 +- src/composables/useContextMenuTranslation.ts | 6 +- src/composables/useCopy.ts | 2 +- src/composables/useCoreCommands.test.ts | 19 +- src/composables/useCoreCommands.ts | 15 +- src/composables/useCurveEditor.test.ts | 13 +- src/composables/useCurveEditor.ts | 19 +- src/composables/useDismissableOverlay.test.ts | 4 +- src/composables/useDismissableOverlay.ts | 12 +- src/composables/useErrorHandling.ts | 32 +-- src/composables/useExternalLink.ts | 4 +- src/composables/useFeatureFlags.ts | 5 +- src/composables/useGlobalLitegraph.ts | 2 +- src/composables/useHelpCenter.ts | 8 +- src/composables/useImageCrop.ts | 30 +-- src/composables/useIntersectionObserver.ts | 6 +- src/composables/useLazyPagination.test.ts | 7 +- src/composables/useLazyPagination.ts | 4 +- src/composables/useLoad3d.ts | 58 ++--- src/composables/useLoad3dViewer.ts | 41 ++-- src/composables/useModelSelectorDialog.ts | 2 +- src/composables/usePaste.ts | 2 +- src/composables/usePragmaticDragAndDrop.ts | 6 +- src/composables/useProgressFavicon.ts | 2 +- src/composables/useRangeEditor.test.ts | 11 +- src/composables/useRangeEditor.ts | 19 +- src/composables/useRefreshableSelection.ts | 15 +- src/composables/useServerLogs.ts | 24 +- src/composables/useTemplateFiltering.test.ts | 9 +- src/composables/useTemplateFiltering.ts | 12 +- src/composables/useTooltipConfig.ts | 26 ++- src/composables/useTreeExpansion.ts | 10 +- src/composables/useUpstreamValue.test.ts | 4 +- src/composables/useUpstreamValue.ts | 2 +- src/composables/useWorkflowActionsMenu.ts | 8 +- .../useWorkflowTemplateSelectorDialog.ts | 2 +- src/composables/useZoomControls.ts | 6 +- .../graph/subgraph/promotedWidgetView.test.ts | 10 +- src/core/graph/subgraph/promotionUtils.ts | 5 +- src/core/graph/widgets/dynamicWidgets.ts | 2 +- .../components/ActiveMediaAssetCard.test.ts | 20 +- .../components/ActiveMediaAssetCard.vue | 2 +- .../components/AssetBrowserModal.stories.ts | 12 +- .../components/AssetBrowserModal.test.ts | 39 ++-- .../assets/components/AssetCard.stories.ts | 32 +-- .../components/AssetFilterBar.stories.ts | 2 +- .../assets/components/MediaAssetCard.vue | 6 +- .../assets/components/MediaAssetFilterBar.vue | 4 +- .../components/MediaAssetFilterMenu.vue | 2 +- .../assets/components/MediaVideoTop.vue | 6 +- .../modelInfo/ModelInfoPanel.test.ts | 34 +-- .../assets/composables/media/useAssetsApi.ts | 8 +- .../composables/useAssetBrowser.test.ts | 28 +-- .../useAssetBrowserDialog.stories.ts | 12 +- .../composables/useAssetBrowserDialog.ts | 6 +- .../composables/useMediaAssetActions.ts | 24 +- .../composables/useMediaAssetFiltering.ts | 4 +- .../composables/useMediaAssetGalleryStore.ts | 4 +- src/platform/assets/services/assetService.ts | 8 +- src/platform/auth/session/useSessionCookie.ts | 6 +- .../cloud/onboarding/CloudAuthTimeoutView.vue | 2 +- .../onboarding/CloudForgotPasswordView.vue | 4 +- .../cloud/onboarding/CloudLoginView.vue | 10 +- .../cloud/onboarding/CloudSignupView.vue | 10 +- .../CloudSubscriptionRedirectView.test.ts | 11 +- .../cloud/onboarding/CloudSurveyView.vue | 2 +- .../cloud/onboarding/UserCheckView.vue | 2 +- .../onboarding/components/CloudSignInForm.vue | 2 +- .../onboarding/components/CloudTemplate.vue | 2 +- .../onboarding/survey/DynamicSurveyField.vue | 12 +- .../survey/DynamicSurveyForm.test.ts | 9 +- .../onboarding/survey/DynamicSurveyForm.vue | 8 +- .../onboarding/survey/defaultSurveySchema.ts | 7 +- .../cloud/onboarding/survey/surveySchema.ts | 43 ++-- .../onboarding/utils/previousFullPath.ts | 8 +- .../subscription/components/PricingTable.vue | 57 ++--- .../components/SubscribeButton.vue | 2 +- .../components/SubscribeToRun.vue | 2 +- .../components/SubscriptionPanel.vue | 4 +- .../SubscriptionRequiredDialogContent.vue | 15 +- .../composables/useBillingPlans.test.ts | 37 ++-- .../composables/useBillingPlans.ts | 4 +- .../composables/useSubscription.test.ts | 2 +- .../composables/useSubscription.ts | 95 ++++---- .../composables/useSubscriptionActions.ts | 8 +- ...useSubscriptionCancellationWatcher.test.ts | 8 +- .../useSubscriptionCancellationWatcher.ts | 8 +- .../composables/useSubscriptionDialog.ts | 2 +- .../utils/subscriptionCheckoutTracker.ts | 101 ++++----- .../utils/subscriptionCheckoutUtil.test.ts | 6 +- .../utils/subscriptionCheckoutUtil.ts | 25 ++- .../utils/subscriptionTierRank.ts | 13 +- .../subscription/utils/tierBenefits.test.ts | 8 +- src/platform/keybindings/keybindingStore.ts | 5 +- .../missingMedia/missingMediaAssetResolver.ts | 4 +- .../useMissingModelInteractions.test.ts | 2 +- .../missingModel/missingModelPipeline.ts | 5 +- .../missingModel/missingModelScan.test.ts | 17 +- .../missingModel/missingModelStore.test.ts | 3 +- .../navigation/preservedQueryManager.ts | 28 +-- .../navigation/preservedQueryTracker.ts | 4 +- .../components/ColorPaletteMessage.vue | 2 +- .../settings/components/ExtensionPanel.vue | 10 +- .../settings/components/ServerConfigPanel.vue | 8 +- .../settings/components/SettingDialog.vue | 8 +- .../settings/components/SettingItem.test.ts | 5 +- .../settings/components/SettingItem.vue | 4 +- .../composables/useLitegraphSettings.ts | 2 +- .../settings/composables/useSettingSearch.ts | 6 +- .../settings/composables/useSettingUI.ts | 16 +- src/platform/settings/settingStore.ts | 2 +- .../cloud/ImpactTelemetryProvider.test.ts | 3 +- .../cloud/ImpactTelemetryProvider.ts | 3 +- .../cloud/MixpanelTelemetryProvider.test.ts | 5 +- src/platform/updates/common/releaseService.ts | 14 +- src/platform/updates/common/releaseStore.ts | 5 +- .../useFrontendVersionMismatchWarning.ts | 4 +- .../ReleaseNotificationToast.test.ts | 2 +- .../components/ReleaseNotificationToast.vue | 12 +- .../updates/components/WhatsNewPopup.test.ts | 2 +- .../updates/components/WhatsNewPopup.vue | 6 +- .../core/services/workflowActionsService.ts | 8 +- .../workflow/core/services/workflowService.ts | 48 ++-- .../workflow/core/utils/pendingWarnings.ts | 5 +- .../composables/useAppsSidebarTab.ts | 2 +- .../composables/useWorkflowsSidebarTab.ts | 2 +- .../management/stores/workflowStore.test.ts | 13 +- .../management/stores/workflowStore.ts | 112 +++++----- .../workflow/persistence/base/draftCache.ts | 25 ++- .../composables/useWorkflowAutoSave.ts | 4 +- .../composables/useWorkflowPersistenceV2.ts | 18 +- .../persistence/stores/workflowDraftStore.ts | 29 +-- .../publish/ComfyHubExamplesStep.vue | 4 +- .../ComfyHubPublishWizardContent.test.ts | 6 +- .../publish/ReorderableExampleImage.vue | 4 +- .../composables/useTemplateUrlLoader.ts | 8 +- .../composables/useTemplateWorkflows.ts | 18 +- .../repositories/workflowTemplatesStore.ts | 63 +++--- .../workspace/auth/WorkspaceAuthGate.test.ts | 5 +- .../CurrentUserPopoverWorkspace.vue | 22 +- .../components/PricingTableWorkspace.vue | 31 +-- .../TeamWorkspacesDialogContent.test.ts | 5 +- .../composables/useInviteUrlLoader.ts | 6 +- .../composables/useWorkspaceBilling.ts | 4 +- .../workspace/stores/useWorkspaceAuth.test.ts | 3 +- src/renderer/core/canvas/canvasStore.ts | 12 +- .../canvas/interaction/canvasPointerEvent.ts | 12 +- .../core/canvas/links/linkDropOrchestrator.ts | 8 +- .../core/canvas/useCanvasInteractions.ts | 15 +- .../core/layout/operations/layoutMutations.ts | 32 +-- .../core/layout/store/layoutStore.test.ts | 46 ++-- .../layout/transform/useTransformState.ts | 2 +- .../core/layout/utils/layoutMath.test.ts | 20 +- .../core/layout/utils/nodeSizeUtil.ts | 5 +- .../core/thumbnail/useWorkflowThumbnail.ts | 14 +- .../extensions/linearMode/DropZone.stories.ts | 62 +++--- .../getExecutionStatusMessage.test.ts | 4 +- src/renderer/extensions/minimap/MiniMap.vue | 2 +- .../minimap/composables/useMinimap.test.ts | 8 +- .../minimap/composables/useMinimap.ts | 10 +- .../minimap/composables/useMinimapGraph.ts | 12 +- .../composables/useMinimapInteraction.ts | 10 +- .../minimap/composables/useMinimapRenderer.ts | 9 +- .../minimap/composables/useMinimapViewport.ts | 12 +- .../extensions/vueNodes/VideoPreview.vue | 27 +-- .../components/LGraphNode.subgraph.test.ts | 37 ++-- .../vueNodes/components/LGraphNode.vue | 17 +- .../vueNodes/components/LivePreview.vue | 4 +- .../vueNodes/components/NodeHeader.test.ts | 34 +-- .../vueNodes/components/NodeHeader.vue | 10 +- .../vueNodes/components/NodeSlots.test.ts | 32 +-- .../vueNodes/components/NodeSlots.vue | 5 +- .../vueNodes/components/NodeWidgets.test.ts | 52 +++-- .../useNodePointerInteractions.test.ts | 8 +- .../composables/useNodePointerInteractions.ts | 2 +- .../vueNodes/composables/useNodeTooltips.ts | 12 +- .../composables/useProcessedWidgets.test.ts | 26 ++- .../composables/useProcessedWidgets.ts | 2 +- .../vueNodes/composables/useShiftKeySync.ts | 2 +- .../composables/useSlotLinkInteraction.ts | 76 ++++--- .../execution/useNodeExecutionState.ts | 4 +- .../interactions/resize/useNodeResize.ts | 20 +- .../layout/ensureCorrectLayoutScale.ts | 4 +- .../vueNodes/layout/useNodeDrag.test.ts | 4 +- .../vueNodes/preview/useNodePreviewState.ts | 4 +- .../components/ValueControlPopover.test.ts | 5 +- .../widgets/components/WidgetButton.test.ts | 10 +- .../widgets/components/WidgetButton.vue | 2 +- .../components/WidgetColorPicker.test.ts | 11 +- .../components/WidgetImageCompare.test.ts | 7 +- .../components/WidgetInputNumber.test.ts | 17 +- .../WidgetInputNumberGradientSlider.test.ts | 8 +- .../WidgetInputNumberGradientSlider.vue | 2 +- .../components/WidgetInputNumberSlider.vue | 4 +- .../components/WidgetInputText.test.ts | 15 +- .../widgets/components/WidgetMarkdown.test.ts | 7 +- .../WidgetSelect.asset-mode.test.ts | 12 +- .../widgets/components/WidgetSelect.test.ts | 11 +- .../components/WidgetSelectDefault.test.ts | 28 ++- .../components/WidgetSelectDropdown.vue | 2 +- .../components/WidgetToggleSwitch.test.ts | 11 +- .../components/WidgetWithControl.test.ts | 9 +- .../components/audio/AudioPreviewPlayer.vue | 20 +- .../components/form/FormSelectButton.test.ts | 6 +- .../components/form/dropdown/FormDropdown.vue | 4 +- .../form/dropdown/FormDropdownMenu.vue | 2 +- .../composables/useAssetWidgetData.test.ts | 24 +- .../widgets/composables/useBooleanWidget.ts | 9 +- .../composables/useBoundingBoxWidget.ts | 2 +- .../widgets/composables/useChartWidget.ts | 2 +- .../widgets/composables/useColorWidget.ts | 2 +- .../widgets/composables/useComboWidget.ts | 27 +-- .../widgets/composables/useCurveWidget.ts | 2 +- .../widgets/composables/useFloatWidget.ts | 9 +- .../widgets/composables/useGalleriaWidget.ts | 2 +- .../composables/useImageCompareWidget.ts | 2 +- .../composables/useImagePreviewWidget.ts | 20 +- .../composables/useImageUploadWidget.ts | 28 ++- .../widgets/composables/useIntWidget.ts | 9 +- .../widgets/composables/useMarkdownWidget.ts | 9 +- .../widgets/composables/usePainterWidget.ts | 2 +- .../widgets/composables/useRangeWidget.ts | 2 +- .../composables/useRemoteWidget.test.ts | 20 +- .../widgets/composables/useRemoteWidget.ts | 66 +++--- .../widgets/composables/useStringWidget.ts | 9 +- .../widgets/composables/useTextareaWidget.ts | 2 +- .../composables/useWidgetSelectItems.test.ts | 26 ++- .../widgets/registry/widgetRegistry.ts | 10 +- src/renderer/glsl/useGLSLUniforms.ts | 4 +- src/renderer/utils/nodeTypeGuards.ts | 6 +- src/schemas/nodeDef/nodeDefSchemaV2.ts | 24 +- src/services/audioService.ts | 12 +- src/services/colorPaletteService.ts | 26 +-- src/services/comfyRegistryService.ts | 54 ++--- src/services/customerEventsService.ts | 10 +- src/services/dialogService.ts | 32 +-- src/services/extensionService.ts | 14 +- src/services/gateway/registrySearchGateway.ts | 24 +- src/services/litegraphService.ts | 2 +- src/services/load3dService.ts | 2 +- src/services/mediaCacheService.ts | 17 +- src/services/nodeOrganizationService.test.ts | 2 +- .../providers/algoliaSearchProvider.ts | 26 +-- .../providers/registrySearchProvider.test.ts | 4 +- .../providers/registrySearchProvider.ts | 14 +- .../subgraphPseudoWidgetCache.test.ts | 2 +- src/services/subgraphService.ts | 2 +- src/stores/apiKeyAuthStore.ts | 10 +- src/stores/assetsStore.test.ts | 68 +++--- src/stores/assetsStore.ts | 26 ++- src/stores/authStore.ts | 67 +++--- src/stores/comfyRegistryStore.ts | 8 +- src/stores/commandStore.ts | 16 +- src/stores/dialogStore.ts | 4 +- src/stores/domWidgetStore.test.ts | 2 +- src/stores/electronDownloadStore.ts | 25 ++- src/stores/executionErrorStore.ts | 8 +- src/stores/executionStore.ts | 8 +- src/stores/extensionStore.ts | 9 +- src/stores/helpCenterStore.ts | 6 +- src/stores/maskEditorDataStore.test.ts | 10 +- src/stores/maskEditorDataStore.ts | 4 +- src/stores/maskEditorStore.test.ts | 2 +- src/stores/menuItemStore.ts | 8 +- src/stores/nodeBookmarkStore.ts | 35 +-- src/stores/nodeDefStore.test.ts | 34 +-- src/stores/nodeDefStore.ts | 11 +- src/stores/nodeOutputStore.test.ts | 11 +- src/stores/nodeOutputStore.ts | 8 +- src/stores/queueStore.test.ts | 12 +- src/stores/queueStore.ts | 21 +- src/stores/serverConfigStore.ts | 2 +- src/stores/subgraphNavigationStore.ts | 10 +- src/stores/systemStatsStore.test.ts | 3 +- src/stores/systemStatsStore.ts | 2 +- src/stores/templateRankingStore.ts | 12 +- src/stores/userFileStore.ts | 2 +- src/stores/userStore.test.ts | 3 +- .../workspace/assetsSidebarBadgeStore.test.ts | 7 +- .../workspace/assetsSidebarBadgeStore.ts | 4 +- src/stores/workspace/bottomPanelStore.ts | 14 +- src/stores/workspace/colorPaletteStore.ts | 8 +- src/stores/workspace/sidebarTabStore.ts | 16 +- src/types/nodeIdentification.ts | 4 +- src/utils/categoryUtil.ts | 2 +- src/utils/colorUtil.test.ts | 8 +- src/utils/colorUtil.ts | 13 +- src/utils/createAnnotatedPath.ts | 17 +- src/utils/dateTimeUtil.ts | 10 +- src/utils/electronMirrorCheck.ts | 2 +- src/utils/executionUtil.ts | 4 +- src/utils/graphTraversalUtil.ts | 2 +- src/utils/imageUtil.ts | 6 +- src/utils/linkFixer.ts | 47 +++- src/utils/litegraphUtil.ts | 8 +- src/utils/mapperUtil.ts | 12 +- src/utils/mathUtil.ts | 4 +- src/utils/migration/migrateReroute.test.ts | 2 +- src/utils/migration/migrateReroute.ts | 4 +- src/utils/mouseDownUtil.ts | 6 +- src/utils/nodeDefUtil.ts | 18 +- src/utils/nodeFilterUtil.test.ts | 4 +- src/utils/nodeFilterUtil.ts | 10 +- src/utils/numberUtil.ts | 4 +- src/utils/objectUrlUtil.ts | 4 +- src/utils/queueDisplay.ts | 12 +- src/utils/queueUtil.ts | 4 +- src/utils/rafBatch.ts | 10 +- src/utils/treeUtil.test.ts | 14 +- src/utils/treeUtil.ts | 6 +- src/utils/typeGuardUtil.ts | 30 +-- src/views/GraphView.vue | 8 +- src/views/UserSelectView.test.ts | 5 +- src/views/UserSelectView.vue | 2 +- .../components/ManagerProgressToast.vue | 2 +- .../manager/ImportFailedNodeFooter.vue | 2 +- .../components/manager/ManagerDialog.vue | 20 +- .../manager/NodeConflictDialogContent.vue | 6 +- .../components/manager/NodeConflictFooter.vue | 4 +- .../components/manager/PackVersionBadge.vue | 6 +- .../PackVersionSelectorPopover.test.ts | 2 +- .../manager/PackVersionSelectorPopover.vue | 16 +- .../manager/button/PackEnableToggle.vue | 10 +- .../manager/button/PackUninstallButton.vue | 11 +- .../manager/button/PackUpdateButton.vue | 6 +- .../manager/infoPanel/InfoPanelMultiItem.vue | 2 +- .../tabs/DescriptionTabPanel.test.ts | 12 +- .../infoPanel/tabs/DescriptionTabPanel.vue | 21 +- .../manager/infoPanel/tabs/NodesTabPanel.vue | 9 +- .../composables/nodePack/useInstalledPacks.ts | 9 +- .../nodePack/useMissingNodes.test.ts | 12 +- .../composables/nodePack/useMissingNodes.ts | 9 +- .../composables/nodePack/useNodePacks.ts | 10 +- .../composables/nodePack/usePackInstall.ts | 11 +- .../nodePack/usePackUpdateStatus.ts | 4 +- .../nodePack/usePacksSelection.test.ts | 24 +- .../nodePack/usePacksStatus.test.ts | 56 ++--- .../nodePack/useUpdateAvailableNodes.ts | 9 +- .../composables/nodePack/useWorkflowPacks.ts | 34 +-- .../manager/composables/useApplyChanges.ts | 2 +- .../composables/useManagerDisplayPacks.ts | 17 +- .../composables/useManagerQueue.test.ts | 2 +- .../manager/composables/useManagerQueue.ts | 30 +-- .../composables/useManagerState.test.ts | 42 ++-- .../manager/composables/useManagerState.ts | 8 +- .../composables/useManagerStatePersistence.ts | 8 +- .../manager/composables/useRegistrySearch.ts | 8 +- .../manager/services/comfyManagerService.ts | 64 +++--- .../manager/stores/comfyManagerStore.test.ts | 4 +- .../manager/stores/comfyManagerStore.ts | 87 ++++---- .../manager/types/comfyManagerTypes.ts | 6 +- .../utils/graphHasMissingNodes.test.ts | 9 +- .../manager/utils/graphHasMissingNodes.ts | 12 +- 692 files changed, 4543 insertions(+), 3923 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 66142ab5ca..268917241d 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -28,6 +28,7 @@ ], "rules": { "no-async-promise-executor": "off", + "func-style": ["error", "declaration"], "no-console": [ "error", { @@ -124,6 +125,12 @@ "no-console": "allow" } }, + { + "files": ["src/lib/litegraph/**"], + "rules": { + "func-style": "off" + } + }, { "files": ["browser_tests/**/*.ts"], "jsPlugins": ["eslint-plugin-playwright"], diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 54eca1d76c..4f3c95541f 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -47,7 +47,7 @@ setup((app) => { }) // Theme and dialog decorator -export const withTheme = (Story: StoryFn, context: StoryContext) => { +export function withTheme(Story: StoryFn, context: StoryContext) { const theme = context.globals.theme || 'light' // Apply theme class to document root diff --git a/apps/desktop-ui/.storybook/preview.ts b/apps/desktop-ui/.storybook/preview.ts index a0ead30cc1..50886fd363 100644 --- a/apps/desktop-ui/.storybook/preview.ts +++ b/apps/desktop-ui/.storybook/preview.ts @@ -40,7 +40,7 @@ setup((app) => { app.use(ToastService) }) -export const withTheme = (Story: StoryFn, context: StoryContext) => { +export function withTheme(Story: StoryFn, context: StoryContext) { const theme = context.globals.theme || 'light' if (theme === 'dark') { document.documentElement.classList.add('dark-theme') diff --git a/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue b/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue index 4983dc8917..10d2fb65c4 100644 --- a/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue +++ b/apps/desktop-ui/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue @@ -58,7 +58,7 @@ const tooltipText = computed(() => { : t('serverStart.copyAllTooltip') }) -const handleCopy = async () => { +async function handleCopy() { const existingSelection = terminal.getSelection() const shouldSelectAll = !existingSelection if (shouldSelectAll) terminal.selectAll() @@ -76,7 +76,7 @@ const handleCopy = async () => { } } -const showContextMenu = (event: MouseEvent) => { +function showContextMenu(event: MouseEvent) { event.preventDefault() electronAPI()?.showContextMenu({ type: 'text' }) } diff --git a/apps/desktop-ui/src/components/common/UrlInput.vue b/apps/desktop-ui/src/components/common/UrlInput.vue index 91f8cfe564..a7c8c16f1e 100644 --- a/apps/desktop-ui/src/components/common/UrlInput.vue +++ b/apps/desktop-ui/src/components/common/UrlInput.vue @@ -44,8 +44,9 @@ const emit = defineEmits<{ const validationState = ref(ValidationState.IDLE) -const cleanInput = (value: string): string => - value ? value.replace(/\s+/g, '') : '' +function cleanInput(value: string): string { + return value ? value.replace(/\s+/g, '') : '' +} // Add internal value state const internalValue = ref(cleanInput(props.modelValue)) @@ -68,14 +69,14 @@ onMounted(async () => { await validateUrl(props.modelValue) }) -const handleInput = (value: string | undefined) => { +function handleInput(value: string | undefined) { // Update internal value without emitting internalValue.value = cleanInput(value ?? '') // Reset validation state when user types validationState.value = ValidationState.IDLE } -const handleBlur = async () => { +async function handleBlur() { const input = cleanInput(internalValue.value) let normalizedUrl = input @@ -91,7 +92,7 @@ const handleBlur = async () => { } // Default validation implementation -const defaultValidateUrl = async (url: string): Promise => { +async function defaultValidateUrl(url: string): Promise { if (!isValidUrl(url)) return false try { return await checkUrlReachable(url) @@ -100,7 +101,7 @@ const defaultValidateUrl = async (url: string): Promise => { } } -const validateUrl = async (value: string) => { +async function validateUrl(value: string) { if (validationState.value === ValidationState.LOADING) return const url = cleanInput(value) diff --git a/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue b/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue index f1caa62faa..a927a4e3d4 100644 --- a/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue +++ b/apps/desktop-ui/src/components/install/DesktopSettingsConfiguration.vue @@ -127,7 +127,7 @@ const showDialog = ref(false) const autoUpdate = defineModel('autoUpdate', { required: true }) const allowMetrics = defineModel('allowMetrics', { required: true }) -const showMetricsInfo = () => { +function showMetricsInfo() { showDialog.value = true } diff --git a/apps/desktop-ui/src/components/install/InstallLocationPicker.vue b/apps/desktop-ui/src/components/install/InstallLocationPicker.vue index e14e9a0468..95c85d60e3 100644 --- a/apps/desktop-ui/src/components/install/InstallLocationPicker.vue +++ b/apps/desktop-ui/src/components/install/InstallLocationPicker.vue @@ -182,10 +182,12 @@ function getTorchMirrorItem(device: TorchDeviceType): UVMirror { } const userIsInChina = ref(false) -const useFallbackMirror = (mirror: UVMirror) => ({ - ...mirror, - mirror: mirror.fallbackMirror -}) +function useFallbackMirror(mirror: UVMirror) { + return { + ...mirror, + mirror: mirror.fallbackMirror + } +} const mirrors = computed<[UVMirror, ModelRef][]>(() => ( @@ -212,7 +214,7 @@ onMounted(async () => { userIsInChina.value = await isInChina() }) -const validatePath = async (path: string | undefined) => { +async function validatePath(path: string | undefined) { try { pathError.value = '' pathExists.value = false @@ -246,7 +248,7 @@ const validatePath = async (path: string | undefined) => { } } -const browsePath = async () => { +async function browsePath() { try { const result = await electron.showDirectoryPicker() if (result) { @@ -258,7 +260,7 @@ const browsePath = async () => { } } -const onFocus = async () => { +async function onFocus() { if (!inputTouched.value) { inputTouched.value = true return diff --git a/apps/desktop-ui/src/components/install/MigrationPicker.vue b/apps/desktop-ui/src/components/install/MigrationPicker.vue index ba542ca697..d26c62cb71 100644 --- a/apps/desktop-ui/src/components/install/MigrationPicker.vue +++ b/apps/desktop-ui/src/components/install/MigrationPicker.vue @@ -92,7 +92,7 @@ const isValidSource = computed( () => sourcePath.value !== '' && pathError.value === '' ) -const validateSource = async (sourcePath: string | undefined) => { +async function validateSource(sourcePath: string | undefined) { if (!sourcePath) { pathError.value = '' return @@ -109,7 +109,7 @@ const validateSource = async (sourcePath: string | undefined) => { } } -const browsePath = async () => { +async function browsePath() { try { const result = await electron.showDirectoryPicker() if (result) { diff --git a/apps/desktop-ui/src/components/maintenance/TaskListItem.vue b/apps/desktop-ui/src/components/maintenance/TaskListItem.vue index 6f893d0496..2765451c1d 100644 --- a/apps/desktop-ui/src/components/maintenance/TaskListItem.vue +++ b/apps/desktop-ui/src/components/maintenance/TaskListItem.vue @@ -82,7 +82,7 @@ const isExecuting = useMinLoadingDurationRef(reactiveExecuting, 250) // Popover const infoPopover = ref | null>(null) -const toggle = (event: Event) => { +function toggle(event: Event) { infoPopover.value?.toggle(event) } diff --git a/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue b/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue index f667cacb11..0cdb81c3ef 100644 --- a/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue +++ b/apps/desktop-ui/src/components/maintenance/TaskListPanel.vue @@ -67,7 +67,7 @@ defineProps<{ filter: MaintenanceFilter }>() -const executeTask = async (task: MaintenanceTask) => { +async function executeTask(task: MaintenanceTask) { let message: string | undefined try { @@ -87,7 +87,7 @@ const executeTask = async (task: MaintenanceTask) => { } // Commands -const confirmButton = async (event: MouseEvent, task: MaintenanceTask) => { +async function confirmButton(event: MouseEvent, task: MaintenanceTask) { if (!task.requireConfirm) { await executeTask(task) return diff --git a/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue b/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue index b3cf67cc50..dd61eb6487 100644 --- a/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue +++ b/apps/desktop-ui/src/components/maintenance/TerminalOutputDrawer.vue @@ -34,10 +34,10 @@ const buffer = useTerminalBuffer() let xterm: Terminal | null = null // Created and destroyed with the Drawer - contents copied from hidden buffer -const terminalCreated = ( +function terminalCreated( { terminal, useAutoSize }: ReturnType, root: Ref -) => { +) { xterm = terminal useAutoSize({ root, autoRows: true, autoCols: true }) terminal.write(props.defaultMessage) @@ -49,7 +49,7 @@ const terminalCreated = ( terminal.options.disableStdin = true } -const terminalUnmounted = () => { +function terminalUnmounted() { xterm = null } diff --git a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts index d353294f09..678470c904 100644 --- a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts +++ b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminal.ts @@ -55,14 +55,14 @@ export function useTerminal(element: Ref) { minRows?: number onResize?: () => void }) { - const ensureValidRows = (rows: number | undefined): number => { + function ensureValidRows(rows: number | undefined): number { if (rows == null || isNaN(rows)) { return (root.value?.clientHeight ?? 80) / 20 } return rows } - const ensureValidCols = (cols: number | undefined): number => { + function ensureValidCols(cols: number | undefined): number { if (cols == null || isNaN(cols)) { // Sometimes this is NaN if so, estimate. return (root.value?.clientWidth ?? 80) / 8 @@ -70,7 +70,7 @@ export function useTerminal(element: Ref) { return cols } - const resize = () => { + function resize() { const dims = fitAddon.proposeDimensions() // Sometimes propose returns NaN, so we may need to estimate. terminal.resize( diff --git a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts index 5dda8db2ed..fb071cf3bf 100644 --- a/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts +++ b/apps/desktop-ui/src/composables/bottomPanelTabs/useTerminalBuffer.ts @@ -6,13 +6,17 @@ export function useTerminalBuffer() { const serializeAddon = new SerializeAddon() const terminal = markRaw(new Terminal({ convertEol: true })) - const copyTo = (destinationTerminal: Terminal) => { + function copyTo(destinationTerminal: Terminal) { destinationTerminal.write(serializeAddon.serialize()) } - const write = (message: string) => terminal.write(message) + function write(message: string) { + return terminal.write(message) + } - const serialize = () => serializeAddon.serialize() + function serialize() { + return serializeAddon.serialize() + } onMounted(() => { terminal.loadAddon(serializeAddon) diff --git a/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts b/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts index 9f81ab394e..f7df0e491f 100644 --- a/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts +++ b/apps/desktop-ui/src/constants/desktopMaintenanceTasks.ts @@ -5,7 +5,7 @@ import { electronAPI } from '@/utils/envUtil' const electron = electronAPI() -const openUrl = (url: string) => { +function openUrl(url: string) { window.open(url, '_blank') return true } diff --git a/apps/desktop-ui/src/stores/maintenanceTaskStore.ts b/apps/desktop-ui/src/stores/maintenanceTaskStore.ts index 235d370ccf..f75064b2fd 100644 --- a/apps/desktop-ui/src/stores/maintenanceTaskStore.ts +++ b/apps/desktop-ui/src/stores/maintenanceTaskStore.ts @@ -124,13 +124,15 @@ export const useMaintenanceTaskStore = defineStore('maintenanceTask', () => { * @param task Task to get the matching state object for * @returns The state object for this task */ - const getRunner = (task: MaintenanceTask) => taskRunners.value.get(task.id)! + function getRunner(task: MaintenanceTask) { + return taskRunners.value.get(task.id)! + } /** * Updates the task list with the latest validation state. * @param validationUpdate Update details passed in by electron */ - const processUpdate = (validationUpdate: InstallValidation) => { + function processUpdate(validationUpdate: InstallValidation) { lastUpdate.value = validationUpdate const update = validationUpdate as IndexedUpdate isRefreshing.value = true @@ -151,19 +153,19 @@ export const useMaintenanceTaskStore = defineStore('maintenanceTask', () => { } /** Clears the resolved status of tasks (when changing filters) */ - const clearResolved = () => { + function clearResolved() { for (const task of tasks.value) { getRunner(task).resolved &&= false } } /** @todo Refreshes Electron tasks only. */ - const refreshDesktopTasks = async () => { + async function refreshDesktopTasks() { isRefreshing.value = true await electron.Validation.validateInstallation(processUpdate) } - const execute = async (task: MaintenanceTask) => { + async function execute(task: MaintenanceTask) { const success = await getRunner(task).execute(task) if (success && task.isInstallationFix) { await refreshDesktopTasks() diff --git a/apps/desktop-ui/src/utils/electronMirrorCheck.ts b/apps/desktop-ui/src/utils/electronMirrorCheck.ts index 31098ae4fd..417291cb9b 100644 --- a/apps/desktop-ui/src/utils/electronMirrorCheck.ts +++ b/apps/desktop-ui/src/utils/electronMirrorCheck.ts @@ -7,7 +7,7 @@ import { electronAPI } from './envUtil' * @param mirror - The mirror to check. * @returns True if the mirror is reachable, false otherwise. */ -export const checkMirrorReachable = async (mirror: string) => { +export async function checkMirrorReachable(mirror: string) { return ( isValidUrl(mirror) && (await electronAPI().NetWork.canAccessUrl(mirror)) ) diff --git a/apps/desktop-ui/src/views/DesktopDialogView.vue b/apps/desktop-ui/src/views/DesktopDialogView.vue index 0bc5e01d9a..e4b5207cb5 100644 --- a/apps/desktop-ui/src/views/DesktopDialogView.vue +++ b/apps/desktop-ui/src/views/DesktopDialogView.vue @@ -36,7 +36,7 @@ import { electronAPI } from '@/utils/envUtil' const route = useRoute() const { id, title, message, buttons } = getDialog(route.params.dialogId) -const handleButtonClick = async (button: DialogAction) => { +async function handleButtonClick(button: DialogAction) { await electronAPI().Dialog.clickButton(button.returnValue) } diff --git a/apps/desktop-ui/src/views/DesktopUpdateView.vue b/apps/desktop-ui/src/views/DesktopUpdateView.vue index e811cd91e3..2a1d28ace2 100644 --- a/apps/desktop-ui/src/views/DesktopUpdateView.vue +++ b/apps/desktop-ui/src/views/DesktopUpdateView.vue @@ -52,7 +52,7 @@ const electron = electronAPI() const terminalVisible = ref(false) -const toggleConsoleDrawer = () => { +function toggleConsoleDrawer() { terminalVisible.value = !terminalVisible.value } diff --git a/apps/desktop-ui/src/views/DownloadGitView.vue b/apps/desktop-ui/src/views/DownloadGitView.vue index 12c116ad83..5e975c6864 100644 --- a/apps/desktop-ui/src/views/DownloadGitView.vue +++ b/apps/desktop-ui/src/views/DownloadGitView.vue @@ -47,11 +47,11 @@ import { useRouter } from 'vue-router' import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue' -const openGitDownloads = () => { +function openGitDownloads() { window.open('https://git-scm.com/downloads/', '_blank') } -const skipGit = async () => { +async function skipGit() { console.warn('pushing') const router = useRouter() await router.push('install') diff --git a/apps/desktop-ui/src/views/InstallView.stories.ts b/apps/desktop-ui/src/views/InstallView.stories.ts index d7247161b2..d6d0b96b4b 100644 --- a/apps/desktop-ui/src/views/InstallView.stories.ts +++ b/apps/desktop-ui/src/views/InstallView.stories.ts @@ -8,8 +8,8 @@ import { createMemoryHistory, createRouter } from 'vue-router' import InstallView from './InstallView.vue' // Create a mock router for stories -const createMockRouter = () => - createRouter({ +function createMockRouter() { + return createRouter({ history: createMemoryHistory(), routes: [ { path: '/', component: { template: '
Home
' } }, @@ -23,6 +23,7 @@ const createMockRouter = () => } ] }) +} const meta: Meta = { title: 'Desktop/Views/InstallView', diff --git a/apps/desktop-ui/src/views/InstallView.vue b/apps/desktop-ui/src/views/InstallView.vue index d59a44624f..af742e9bc9 100644 --- a/apps/desktop-ui/src/views/InstallView.vue +++ b/apps/desktop-ui/src/views/InstallView.vue @@ -90,7 +90,7 @@ const currentStep = ref('1') /** Forces each install step to be visited at least once. */ const highestStep = ref(0) -const handleStepChange = (value: string | number) => { +function handleStepChange(value: string | number) { setHighestStep(value) electronAPI().Events.trackEvent('install_stepper_change', { @@ -98,7 +98,7 @@ const handleStepChange = (value: string | number) => { }) } -const setHighestStep = (value: string | number) => { +function setHighestStep(value: string | number) { const int = typeof value === 'number' ? value : parseInt(value, 10) if (!isNaN(int) && int > highestStep.value) highestStep.value = int } @@ -123,7 +123,7 @@ const canProceed = computed(() => { }) // Navigation methods -const goToNextStep = () => { +function goToNextStep() { const nextStep = (parseInt(currentStep.value) + 1).toString() currentStep.value = nextStep setHighestStep(nextStep) @@ -132,7 +132,7 @@ const goToNextStep = () => { }) } -const goToPreviousStep = () => { +function goToPreviousStep() { const prevStep = (parseInt(currentStep.value) - 1).toString() currentStep.value = prevStep electronAPI().Events.trackEvent('install_stepper_change', { @@ -142,7 +142,7 @@ const goToPreviousStep = () => { const electron = electronAPI() const router = useRouter() -const install = async () => { +async function install() { if (!device.value) return const options: InstallOptions = { diff --git a/apps/desktop-ui/src/views/MaintenanceView.stories.ts b/apps/desktop-ui/src/views/MaintenanceView.stories.ts index 4a8a4b012f..9eee93e2d7 100644 --- a/apps/desktop-ui/src/views/MaintenanceView.stories.ts +++ b/apps/desktop-ui/src/views/MaintenanceView.stories.ts @@ -35,12 +35,14 @@ const validationState: ValidationState = { upgradePackages: 'OK' } -const createMockElectronAPI = () => { +function createMockElectronAPI() { const logListeners: Array<(message: string) => void> = [] - const getValidationUpdate = () => ({ - ...validationState - }) + function getValidationUpdate() { + return { + ...validationState + } + } return { getPlatform: () => 'darwin', @@ -76,7 +78,7 @@ const createMockElectronAPI = () => { } } -const ensureElectronAPI = () => { +function ensureElectronAPI() { const globalWindow = window as { electronAPI?: unknown } if (!globalWindow.electronAPI) { globalWindow.electronAPI = createMockElectronAPI() diff --git a/apps/desktop-ui/src/views/MaintenanceView.vue b/apps/desktop-ui/src/views/MaintenanceView.vue index 9fdfd906b1..468dc1ceaf 100644 --- a/apps/desktop-ui/src/views/MaintenanceView.vue +++ b/apps/desktop-ui/src/views/MaintenanceView.vue @@ -183,7 +183,7 @@ const unsafeReasonText = computed(() => { }) /** If valid, leave the validation window. */ -const completeValidation = async () => { +async function completeValidation() { const isValid = await electron.Validation.complete() if (!isValid) { toast.add({ @@ -194,7 +194,7 @@ const completeValidation = async () => { } } -const toggleConsoleDrawer = () => { +function toggleConsoleDrawer() { terminalVisible.value = !terminalVisible.value } diff --git a/apps/desktop-ui/src/views/ManualConfigurationView.vue b/apps/desktop-ui/src/views/ManualConfigurationView.vue index 5a79514b85..74d63bf5c6 100644 --- a/apps/desktop-ui/src/views/ManualConfigurationView.vue +++ b/apps/desktop-ui/src/views/ManualConfigurationView.vue @@ -67,7 +67,9 @@ const electron = electronAPI() const basePath = ref(null) const sep = ref<'\\' | '/'>('/') -const restartApp = (message?: string) => electron.restartApp(message) +function restartApp(message?: string) { + return electron.restartApp(message) +} onMounted(async () => { basePath.value = await electron.getBasePath() diff --git a/apps/desktop-ui/src/views/MetricsConsentView.vue b/apps/desktop-ui/src/views/MetricsConsentView.vue index ee6d3d5deb..e109731038 100644 --- a/apps/desktop-ui/src/views/MetricsConsentView.vue +++ b/apps/desktop-ui/src/views/MetricsConsentView.vue @@ -64,7 +64,7 @@ const allowMetrics = ref(true) const router = useRouter() const isUpdating = ref(false) -const updateConsent = async () => { +async function updateConsent() { isUpdating.value = true try { await electronAPI().setMetricsConsent(allowMetrics.value) diff --git a/apps/desktop-ui/src/views/NotSupportedView.vue b/apps/desktop-ui/src/views/NotSupportedView.vue index 3a2ba7f333..6ad1ec2b70 100644 --- a/apps/desktop-ui/src/views/NotSupportedView.vue +++ b/apps/desktop-ui/src/views/NotSupportedView.vue @@ -61,19 +61,19 @@ import { useRouter } from 'vue-router' import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue' -const openDocs = () => { +function openDocs() { window.open( 'https://github.com/Comfy-Org/desktop#currently-supported-platforms', '_blank' ) } -const reportIssue = () => { +function reportIssue() { window.open('https://forum.comfy.org/c/v1-feedback/', '_blank') } const router = useRouter() -const continueToInstall = async () => { +async function continueToInstall() { await router.push('/install') } diff --git a/apps/desktop-ui/src/views/ServerStartView.vue b/apps/desktop-ui/src/views/ServerStartView.vue index 6849e22b14..15e1aa9a27 100644 --- a/apps/desktop-ui/src/views/ServerStartView.vue +++ b/apps/desktop-ui/src/views/ServerStartView.vue @@ -118,7 +118,7 @@ let xterm: Terminal | undefined /** * Handles installation stage updates from the desktop */ -const updateInstallStage = (stageInfo: InstallStageInfo) => { +function updateInstallStage(stageInfo: InstallStageInfo) { console.warn('[InstallStage.onUpdate] Received:', { stage: stageInfo.stage, progress: stageInfo.progress, @@ -183,17 +183,17 @@ const displayStatusText = computed(() => { return currentStatusLabel.value }) -const updateProgress = ({ status: newStatus }: { status: ProgressStatus }) => { +function updateProgress({ status: newStatus }: { status: ProgressStatus }) { status.value = newStatus // Make critical error screen more obvious. if (newStatus === ProgressStatus.ERROR) terminalVisible.value = false } -const terminalCreated = ( +function terminalCreated( { terminal, useAutoSize }: ReturnType, root: Ref -) => { +) { xterm = terminal useAutoSize({ root, autoRows: true, autoCols: true }) @@ -206,11 +206,15 @@ const terminalCreated = ( terminal.options.cursorInactiveStyle = 'block' } -const troubleshoot = () => electron.startTroubleshooting() -const reportIssue = () => { +function troubleshoot() { + return electron.startTroubleshooting() +} +function reportIssue() { window.open('https://forum.comfy.org/c/v1-feedback/', '_blank') } -const openLogs = () => electron.openLogsFolder() +function openLogs() { + return electron.openLogsFolder() +} let cleanupInstallStageListener: (() => void) | undefined diff --git a/apps/desktop-ui/src/views/WelcomeView.vue b/apps/desktop-ui/src/views/WelcomeView.vue index 07a03f42b0..7920e73139 100644 --- a/apps/desktop-ui/src/views/WelcomeView.vue +++ b/apps/desktop-ui/src/views/WelcomeView.vue @@ -33,7 +33,7 @@ import { useRouter } from 'vue-router' import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue' const router = useRouter() -const navigateTo = async (path: string) => { +async function navigateTo(path: string) { await router.push(path) } diff --git a/apps/website/e2e/demos.spec.ts b/apps/website/e2e/demos.spec.ts index bbf333e3e6..d9ce494430 100644 --- a/apps/website/e2e/demos.spec.ts +++ b/apps/website/e2e/demos.spec.ts @@ -3,8 +3,9 @@ import { expect, test } from '@playwright/test' import { demos, getNextDemo } from '../src/config/demos' import { t } from '../src/i18n/translations' -const escapeRegExp = (value: string): string => - value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} test.describe('Demo pages @smoke', () => { for (const demo of demos) { diff --git a/apps/website/e2e/responsive.spec.ts b/apps/website/e2e/responsive.spec.ts index 6488170457..bd97b624be 100644 --- a/apps/website/e2e/responsive.spec.ts +++ b/apps/website/e2e/responsive.spec.ts @@ -111,7 +111,7 @@ async function measureMarqueeLoopGeometry( `Animation on ${sel} has unusable duration: ${String(duration)}` ) } - const setAllTimes = (time: number) => { + function setAllTimes(time: number) { for (const track of tracks) { for (const anim of track.getAnimations()) { anim.currentTime = time @@ -119,7 +119,9 @@ async function measureMarqueeLoopGeometry( } void document.body.offsetWidth } - const readX = () => tracks.map((track) => track.getBoundingClientRect().x) + function readX() { + return tracks.map((track) => track.getBoundingClientRect().x) + } setAllTimes(0) const startPositions = readX() const copyWidths = tracks.map( diff --git a/apps/website/src/components/careers/RolesSection.vue b/apps/website/src/components/careers/RolesSection.vue index f57a400f02..16e4e57860 100644 --- a/apps/website/src/components/careers/RolesSection.vue +++ b/apps/website/src/components/careers/RolesSection.vue @@ -36,7 +36,9 @@ let pendingFrame = 0 const HEADER_OFFSET = -144 const ACTIVATION_OFFSET = 300 -const deptElementId = (key: string) => `careers-dept-${key}` +function deptElementId(key: string) { + return `careers-dept-${key}` +} function pickActiveSection() { pendingFrame = 0 diff --git a/apps/website/src/components/product/local/HeroSection.vue b/apps/website/src/components/product/local/HeroSection.vue index 8a2d5b7019..ad800db9fc 100644 --- a/apps/website/src/components/product/local/HeroSection.vue +++ b/apps/website/src/components/product/local/HeroSection.vue @@ -58,7 +58,7 @@ onMounted(() => { }) raw.sort((a, b) => { - const norm = (v: number) => { + function norm(v: number) { const r = v + Math.PI / 2 return r < 0 ? r + 2 * Math.PI : r } @@ -117,7 +117,7 @@ onMounted(() => { applyToPanel(panels[1], elapsed2) applyToPanel(panels[2], elapsed3) - const wOf = (elapsed: number) => { + function wOf(elapsed: number) { const progress = elapsed < PANEL_DURATION ? elapsed / PANEL_DURATION : 1 return lerp(S.w, E.w, ease(progress)) } diff --git a/apps/website/src/composables/useParallax.ts b/apps/website/src/composables/useParallax.ts index af0b926de8..ba49420fff 100644 --- a/apps/website/src/composables/useParallax.ts +++ b/apps/website/src/composables/useParallax.ts @@ -35,7 +35,7 @@ export function useParallax( const triggerEl = options.trigger?.value - const createAnimations = () => { + function createAnimations() { const els = elements .map((r) => r.value) .filter((el): el is HTMLElement => !!el && el.offsetParent !== null) diff --git a/apps/website/src/composables/usePinScrub.ts b/apps/website/src/composables/usePinScrub.ts index 0eb68904be..46bbc738d3 100644 --- a/apps/website/src/composables/usePinScrub.ts +++ b/apps/website/src/composables/usePinScrub.ts @@ -29,7 +29,7 @@ function interpolateY( contentH: number, vpH: number ) { - const clampedTarget = (i: number) => { + function clampedTarget(i: number) { const center = buttonCenters[i] ?? 0 return Math.max(-(contentH - vpH), Math.min(0, vpH / 2 - center)) } diff --git a/apps/website/src/pages/cloud/supported-nodes/[pack].astro b/apps/website/src/pages/cloud/supported-nodes/[pack].astro index 1b5fa30f94..c75c959336 100644 --- a/apps/website/src/pages/cloud/supported-nodes/[pack].astro +++ b/apps/website/src/pages/cloud/supported-nodes/[pack].astro @@ -9,7 +9,7 @@ import { t } from '../../../i18n/translations' import { loadPacksForBuild } from '../../../utils/cloudNodes.build' import { escapeJsonLd } from '../../../utils/escapeJsonLd' -export const getStaticPaths: GetStaticPaths = async () => { +export async function getStaticPaths() { const packs = await loadPacksForBuild() return packs.map((pack) => ({ params: { pack: pack.id }, diff --git a/apps/website/src/pages/customers/[slug].astro b/apps/website/src/pages/customers/[slug].astro index 9801b70f09..c9264cb94e 100644 --- a/apps/website/src/pages/customers/[slug].astro +++ b/apps/website/src/pages/customers/[slug].astro @@ -7,7 +7,7 @@ import WhatsNextSection from '../../components/customers/WhatsNextSection.vue' import { customerStories, getNextStory, getStoryBySlug } from '../../config/customerStories' import { t } from '../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return customerStories.map((story) => ({ params: { slug: story.slug } })) diff --git a/apps/website/src/pages/demos/[slug].astro b/apps/website/src/pages/demos/[slug].astro index 79f9d7c963..d828c9698d 100644 --- a/apps/website/src/pages/demos/[slug].astro +++ b/apps/website/src/pages/demos/[slug].astro @@ -8,7 +8,7 @@ import DemoNavSection from '../../components/demos/DemoNavSection.vue' import { demos, getDemoBySlug, getNextDemo } from '../../config/demos' import { t } from '../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return demos.map((demo) => ({ params: { slug: demo.slug } })) diff --git a/apps/website/src/pages/p/supported-models/[slug].astro b/apps/website/src/pages/p/supported-models/[slug].astro index 39a8333526..8f23929f44 100644 --- a/apps/website/src/pages/p/supported-models/[slug].astro +++ b/apps/website/src/pages/p/supported-models/[slug].astro @@ -5,7 +5,7 @@ import ModelHeroSection from '../../../components/models/ModelHeroSection.vue' import { models, getModelBySlug } from '../../../config/models' import { t } from '../../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return models.map((model) => ({ params: { slug: model.slug } })) diff --git a/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro b/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro index b74d4ebd27..458b046066 100644 --- a/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro +++ b/apps/website/src/pages/zh-CN/cloud/supported-nodes/[pack].astro @@ -9,7 +9,7 @@ import { t } from '../../../../i18n/translations' import { loadPacksForBuild } from '../../../../utils/cloudNodes.build' import { escapeJsonLd } from '../../../../utils/escapeJsonLd' -export const getStaticPaths: GetStaticPaths = async () => { +export async function getStaticPaths() { const packs = await loadPacksForBuild() return packs.map((pack) => ({ params: { pack: pack.id }, diff --git a/apps/website/src/pages/zh-CN/customers/[slug].astro b/apps/website/src/pages/zh-CN/customers/[slug].astro index 4775239178..f0251125d5 100644 --- a/apps/website/src/pages/zh-CN/customers/[slug].astro +++ b/apps/website/src/pages/zh-CN/customers/[slug].astro @@ -7,7 +7,7 @@ import WhatsNextSection from '../../../components/customers/WhatsNextSection.vue import { customerStories, getNextStory, getStoryBySlug } from '../../../config/customerStories' import { t } from '../../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return customerStories.map((story) => ({ params: { slug: story.slug } })) diff --git a/apps/website/src/pages/zh-CN/demos/[slug].astro b/apps/website/src/pages/zh-CN/demos/[slug].astro index fb31d3a40a..e7d4e10a72 100644 --- a/apps/website/src/pages/zh-CN/demos/[slug].astro +++ b/apps/website/src/pages/zh-CN/demos/[slug].astro @@ -8,7 +8,7 @@ import DemoNavSection from '../../../components/demos/DemoNavSection.vue' import { demos, getDemoBySlug, getNextDemo } from '../../../config/demos' import { t } from '../../../i18n/translations' -export const getStaticPaths: GetStaticPaths = () => { +export function getStaticPaths() { return demos.map((demo) => ({ params: { slug: demo.slug } })) diff --git a/apps/website/src/scripts/snakeGame.ts b/apps/website/src/scripts/snakeGame.ts index 0dd7503198..7ebc8fbc9e 100644 --- a/apps/website/src/scripts/snakeGame.ts +++ b/apps/website/src/scripts/snakeGame.ts @@ -35,8 +35,9 @@ const TICK_MS = 200 function readColors() { const style = getComputedStyle(document.documentElement) - const get = (name: string, fallback: string): string => - style.getPropertyValue(name).trim() || fallback + function get(name: string, fallback: string): string { + return style.getPropertyValue(name).trim() || fallback + } return { bg: get('--color-primary-comfy-ink', '#211927'), @@ -59,9 +60,12 @@ function requireElement( return el } -const isSVGSVG = (el: Element): el is SVGSVGElement => - el instanceof SVGSVGElement -const isSVGG = (el: Element): el is SVGGElement => el instanceof SVGGElement +function isSVGSVG(el: Element): el is SVGSVGElement { + return el instanceof SVGSVGElement +} +function isSVGG(el: Element): el is SVGGElement { + return el instanceof SVGGElement +} function isSVGText(el: Element): el is SVGTextElement { return el instanceof SVGTextElement } @@ -127,8 +131,9 @@ function depth(cell: Cell): number { function roundedPath(pts: [number, number][], radius: number): string { const n = pts.length - const fmt = (p: readonly [number, number]) => - `${p[0].toFixed(2)},${p[1].toFixed(2)}` + function fmt(p: readonly [number, number]) { + return `${p[0].toFixed(2)},${p[1].toFixed(2)}` + } let d = '' for (let i = 0; i < n; i++) { const prev = pts[(i - 1 + n) % n] @@ -206,7 +211,7 @@ function triggerExplosion() { const cx = ((COLS - ROWS) * STEP_X) / 2 const cy = ((COLS + ROWS - 2) * STEP_Y) / 2 - const launchParticle = (i: number, j: number, fill: string): Particle => { + function launchParticle(i: number, j: number, fill: string): Particle { const [sx, sy] = iso(i, j) const baseAngle = Math.atan2(sy - cy, sx - cx) const angle = baseAngle + (Math.random() - 0.5) * 1.2 @@ -239,7 +244,9 @@ function triggerExplosion() { const DROP_DURATION_MS = 450 const DROP_HEIGHT = 600 let foodDropStart = 0 -const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3) +function easeOutCubic(t: number) { + return 1 - Math.pow(1 - t, 3) +} function foodDropOffset(now = performance.now()): number { if (!foodDropStart) return 0 @@ -252,7 +259,7 @@ function foodDropOffset(now = performance.now()): number { const REBIRTH_STAGGER_MS = 90 const REBIRTH_GROW_MS = 260 let rebirthStart = 0 -const easeOutBack = (t: number) => { +function easeOutBack(t: number) { const c1 = 1.70158 const c3 = c1 + 1 return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2) @@ -271,7 +278,9 @@ function rebirthScaleFor(idx: number, now = performance.now()): number { const CHOMP_DURATION_MS = 220 const CHOMP_PEAK_SCALE = 1.15 let chompStart = 0 -const easeOut = (t: number) => 1 - (1 - t) * (1 - t) +function easeOut(t: number) { + return 1 - (1 - t) * (1 - t) +} function chompScale(now = performance.now()): number { if (!chompStart) return 1 @@ -299,7 +308,7 @@ function isAnimating(): boolean { function ensureAnimationLoop() { if (animationHandle !== null) return - const tick = () => { + function tick() { if ( explodeStart && performance.now() - explodeStart >= EXPLODE_DURATION_MS @@ -411,8 +420,12 @@ function updateScoreDisplay() { scoreBestEl.textContent = String(best) } -const cellsEqual = (a: Cell, b: Cell) => a.i === b.i && a.j === b.j -const inBounds = (c: Cell) => c.i >= 0 && c.j >= 0 && c.i < COLS && c.j < ROWS +function cellsEqual(a: Cell, b: Cell) { + return a.i === b.i && a.j === b.j +} +function inBounds(c: Cell) { + return c.i >= 0 && c.j >= 0 && c.i < COLS && c.j < ROWS +} function reset() { const j0 = Math.floor(ROWS / 2) diff --git a/browser_tests/fixtures/helpers/AssetHelper.ts b/browser_tests/fixtures/helpers/AssetHelper.ts index 6bcfaa14cf..42bd1d03e5 100644 --- a/browser_tests/fixtures/helpers/AssetHelper.ts +++ b/browser_tests/fixtures/helpers/AssetHelper.ts @@ -158,7 +158,7 @@ export class AssetHelper { statusCode: number, error: string = 'Internal Server Error' ): Promise { - const handler = async (route: Route) => { + async function handler(route: Route) { return route.fulfill({ status: statusCode, json: { error } diff --git a/browser_tests/fixtures/helpers/AssetsHelper.ts b/browser_tests/fixtures/helpers/AssetsHelper.ts index 39c5f94336..b692050f5a 100644 --- a/browser_tests/fixtures/helpers/AssetsHelper.ts +++ b/browser_tests/fixtures/helpers/AssetsHelper.ts @@ -325,7 +325,7 @@ export class AssetsHelper { await this.page.unroute(pattern, existingHandler) } - const handler = async (route: Route) => { + async function handler(route: Route) { await route.fulfill({ status: 200, contentType: 'application/json', diff --git a/browser_tests/fixtures/helpers/NodeReplacementHelper.ts b/browser_tests/fixtures/helpers/NodeReplacementHelper.ts index 31584e7bef..9e542a0210 100644 --- a/browser_tests/fixtures/helpers/NodeReplacementHelper.ts +++ b/browser_tests/fixtures/helpers/NodeReplacementHelper.ts @@ -42,7 +42,7 @@ export async function setupNodeReplacement( options?: AddEventListenerOptions | boolean ) { if (type === 'message' && typeof listener === 'function') { - const wrapped = function (this: WebSocket, event: Event) { + function wrapped(this: WebSocket, event: Event) { const msgEvent = event as MessageEvent if (typeof msgEvent.data === 'string') { try { diff --git a/browser_tests/fixtures/helpers/SubgraphHelper.ts b/browser_tests/fixtures/helpers/SubgraphHelper.ts index 7016049166..76e45f6d32 100644 --- a/browser_tests/fixtures/helpers/SubgraphHelper.ts +++ b/browser_tests/fixtures/helpers/SubgraphHelper.ts @@ -606,7 +606,7 @@ export class SubgraphHelper { ] ): { warnings: string[]; dispose: () => void } { const warnings: string[] = [] - const handler = (msg: ConsoleMessage) => { + function handler(msg: ConsoleMessage) { const text = msg.text() if (patterns.some((p) => text.includes(p))) { warnings.push(text) diff --git a/browser_tests/fixtures/helpers/TemplateHelper.ts b/browser_tests/fixtures/helpers/TemplateHelper.ts index 7ae904e890..fcd730292e 100644 --- a/browser_tests/fixtures/helpers/TemplateHelper.ts +++ b/browser_tests/fixtures/helpers/TemplateHelper.ts @@ -150,7 +150,7 @@ export class TemplateHelper { } async mockThumbnails(): Promise { - const thumbnailHandler = async (route: Route) => { + async function thumbnailHandler(route: Route) { await route.fulfill({ status: 200, path: 'browser_tests/assets/example.webp', diff --git a/browser_tests/fixtures/sharedWorkflowImportFixture.ts b/browser_tests/fixtures/sharedWorkflowImportFixture.ts index 6b6c2894fc..03cc8d32b4 100644 --- a/browser_tests/fixtures/sharedWorkflowImportFixture.ts +++ b/browser_tests/fixtures/sharedWorkflowImportFixture.ts @@ -130,10 +130,12 @@ export const sharedWorkflowImportFixture = base.extend<{ async function mockSharedWorkflowImportFlow( page: Page ): Promise { + function noopResolveResponse() {} let isRecording = false let importEndpointCalled = false let importBody: ImportPublishedAssetsRequest | undefined - let resolvePublicInclusiveInputAssetResponseAfterImport: () => void = () => {} + let resolvePublicInclusiveInputAssetResponseAfterImport: () => void = + noopResolveResponse let publicInclusiveInputAssetResponseAfterImport = new Promise( (resolve) => { resolvePublicInclusiveInputAssetResponseAfterImport = resolve diff --git a/browser_tests/fixtures/utils/litegraphUtils.ts b/browser_tests/fixtures/utils/litegraphUtils.ts index 0036526a65..6d592e7862 100644 --- a/browser_tests/fixtures/utils/litegraphUtils.ts +++ b/browser_tests/fixtures/utils/litegraphUtils.ts @@ -7,7 +7,7 @@ import type { ComfyPage } from '@e2e/fixtures/ComfyPage' import type { Position, Size } from '@e2e/fixtures/types' import { VueNodeFixture } from '@e2e/fixtures/utils/vueNodeFixtures' -export const getMiddlePoint = (pos1: Position, pos2: Position) => { +export function getMiddlePoint(pos1: Position, pos2: Position) { return { x: (pos1.x + pos2.x) / 2, y: (pos1.y + pos2.y) / 2 diff --git a/browser_tests/tests/actionbar.spec.ts b/browser_tests/tests/actionbar.spec.ts index 62dd43359b..8cc3460739 100644 --- a/browser_tests/tests/actionbar.spec.ts +++ b/browser_tests/tests/actionbar.spec.ts @@ -45,7 +45,7 @@ test.describe('Actionbar', { tag: '@ui' }, () => { const requestPromise = comfyPage.page.waitForResponse('**/api/prompt') // Find and set the width on the latent node - const triggerChange = async (value: number) => { + async function triggerChange(value: number) { return await comfyPage.page.evaluate((value) => { const node = window.app!.graph!._nodes.find( (n) => n.type === 'EmptyLatentImage' @@ -59,7 +59,7 @@ test.describe('Actionbar', { tag: '@ui' }, () => { } // Trigger a status websocket message - const triggerStatus = (queueSize: number) => { + function triggerStatus(queueSize: number) { ws.send( JSON.stringify({ type: 'status', @@ -75,7 +75,7 @@ test.describe('Actionbar', { tag: '@ui' }, () => { } // Extract the width from the queue response - const getQueuedWidth = async (resp: Promise) => { + async function getQueuedWidth(resp: Promise) { const obj = await (await resp).json() return obj['__request']['prompt']['5']['inputs']['width'] } diff --git a/browser_tests/tests/canvasLayoutSettings.spec.ts b/browser_tests/tests/canvasLayoutSettings.spec.ts index 1996c8ea71..fe28e79c6b 100644 --- a/browser_tests/tests/canvasLayoutSettings.spec.ts +++ b/browser_tests/tests/canvasLayoutSettings.spec.ts @@ -5,16 +5,18 @@ import { import type { ComfyPage } from '@e2e/fixtures/ComfyPage' import type { Size } from '@e2e/fixtures/types' -const expectedGroupSize = ( +function expectedGroupSize( nodeBounds: Size, padding: number, titleHeight: number -): Size => ({ - width: nodeBounds.width + padding * 2, - // Group height adds one title row above the contained node bounds (which - // themselves already include the node's own title), independent of padding. - height: nodeBounds.height + padding * 2 + titleHeight -}) +): Size { + return { + width: nodeBounds.width + padding * 2, + // Group height adds one title row above the contained node bounds (which + // themselves already include the node's own title), independent of padding. + height: nodeBounds.height + padding * 2 + titleHeight + } +} test.describe('Canvas layout settings', { tag: '@canvas' }, () => { test.describe('Comfy.SnapToGrid.GridSize', () => { @@ -24,7 +26,7 @@ test.describe('Canvas layout settings', { tag: '@canvas' }, () => { await comfyPage.nodeOps.clearGraph() }) - const createNode = async (comfyPage: ComfyPage) => { + async function createNode(comfyPage: ComfyPage) { const note = await comfyPage.nodeOps.addNode('Note', undefined, { x: 0, y: 0 @@ -79,10 +81,10 @@ test.describe('Canvas layout settings', { tag: '@canvas' }, () => { await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') }) - const groupAroundAllNodesWithPadding = async ( + async function groupAroundAllNodesWithPadding( comfyPage: ComfyPage, padding: number - ): Promise => { + ): Promise { await comfyPage.settings.setSetting( 'Comfy.GroupSelectedNodes.Padding', padding @@ -126,15 +128,16 @@ test.describe('Canvas layout settings', { tag: '@canvas' }, () => { test.describe('LiteGraph.ContextMenu.Scaling', () => { const ZOOM_SCALE = 2 - const litegraphContextMenu = (comfyPage: ComfyPage) => - comfyPage.page.locator('.litecontextmenu') + function litegraphContextMenu(comfyPage: ComfyPage) { + return comfyPage.page.locator('.litecontextmenu') + } test.beforeEach(async ({ comfyPage }) => { await comfyPage.workflow.loadWorkflow('widgets/load_image_widget') await comfyPage.canvasOps.setScale(ZOOM_SCALE) }) - const openComboMenu = async (comfyPage: ComfyPage) => { + async function openComboMenu(comfyPage: ComfyPage) { const loadImage = ( await comfyPage.nodeOps.getNodeRefsByType('LoadImage') )[0] diff --git a/browser_tests/tests/canvasModeSelector.spec.ts b/browser_tests/tests/canvasModeSelector.spec.ts index 2e770d3ce4..355b7127a2 100644 --- a/browser_tests/tests/canvasModeSelector.spec.ts +++ b/browser_tests/tests/canvasModeSelector.spec.ts @@ -3,12 +3,14 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage' -const getLocators = (page: Page) => ({ - trigger: page.getByRole('button', { name: 'Canvas Mode' }), - menu: page.getByRole('menu', { name: 'Canvas Mode' }), - selectItem: page.getByRole('menuitemradio', { name: 'Select' }), - handItem: page.getByRole('menuitemradio', { name: 'Hand' }) -}) +function getLocators(page: Page) { + return { + trigger: page.getByRole('button', { name: 'Canvas Mode' }), + menu: page.getByRole('menu', { name: 'Canvas Mode' }), + selectItem: page.getByRole('menuitemradio', { name: 'Select' }), + handItem: page.getByRole('menuitemradio', { name: 'Hand' }) + } +} const MODES = [ { diff --git a/browser_tests/tests/canvasSettings.spec.ts b/browser_tests/tests/canvasSettings.spec.ts index e026edc284..c3fd62a64d 100644 --- a/browser_tests/tests/canvasSettings.spec.ts +++ b/browser_tests/tests/canvasSettings.spec.ts @@ -7,7 +7,7 @@ import { sleep } from '@e2e/fixtures/utils/timing' const CLIP_NODE_COUNT = 2 -const getClipNodesDragBox = async (comfyPage: ComfyPage) => { +async function getClipNodesDragBox(comfyPage: ComfyPage) { const clipNodes = await comfyPage.nodeOps.getNodeRefsByType('CLIPTextEncode') expect( clipNodes, @@ -242,11 +242,11 @@ test.describe('Canvas settings', { tag: '@canvas' }, () => { * hold), nudge by `(dx, dy)` absolute pixels, then release. Spec-local * because it exists only to probe the CanvasPointer timing thresholds. */ - const holdDragAt = async ( + async function holdDragAt( comfyPage: ComfyPage, pos: { x: number; y: number }, opts: { dx: number; dy: number; holdMs: number } - ) => { + ) { const abs = await comfyPage.canvasOps.toAbsolute(pos) await comfyPage.page.mouse.move(abs.x, abs.y) await comfyPage.page.mouse.down() @@ -383,8 +383,9 @@ test.describe('Canvas settings', { tag: '@canvas' }, () => { // (CI jitter, background throttling, canvas-idle behaviour). Assert the // render-loop throttle value instead — that is what actually governs // frame cadence. - const getFrameGap = (comfyPage: ComfyPage) => - comfyPage.page.evaluate(() => window.app!.canvas.maximumFps * 1000) + function getFrameGap(comfyPage: ComfyPage) { + return comfyPage.page.evaluate(() => window.app!.canvas.maximumFps * 1000) + } test('caps the render loop frame gap', async ({ comfyPage }) => { await comfyPage.settings.setSetting('LiteGraph.Canvas.MaximumFps', 30) diff --git a/browser_tests/tests/changeTracker.spec.ts b/browser_tests/tests/changeTracker.spec.ts index c4087888f9..32198a0923 100644 --- a/browser_tests/tests/changeTracker.spec.ts +++ b/browser_tests/tests/changeTracker.spec.ts @@ -219,7 +219,7 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { comfyPage }) => { const node = (await comfyPage.nodeOps.getFirstNodeRef())! - const bypassAndPin = async () => { + async function bypassAndPin() { await beforeChange(comfyPage) await comfyPage.keyboard.bypass() await expect(node).toBeBypassed() @@ -228,14 +228,14 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { await afterChange(comfyPage) } - const collapse = async () => { + async function collapse() { await beforeChange(comfyPage) await node.click('collapse', { moveMouseToEmptyArea: true }) await expect(node).toBeCollapsed() await afterChange(comfyPage) } - const multipleChanges = async () => { + async function multipleChanges() { await beforeChange(comfyPage) // Call other actions that uses begin/endChange await node.click('title') diff --git a/browser_tests/tests/defaultKeybindings.spec.ts b/browser_tests/tests/defaultKeybindings.spec.ts index 54ea64f90d..d608637ade 100644 --- a/browser_tests/tests/defaultKeybindings.spec.ts +++ b/browser_tests/tests/defaultKeybindings.spec.ts @@ -133,10 +133,11 @@ test.describe('Default Keybindings', { tag: '@keyboard' }, () => { await node.click('title') // Normal mode is ALWAYS (0) - const getMode = () => - comfyPage.page.evaluate((nodeId) => { + function getMode() { + return comfyPage.page.evaluate((nodeId) => { return window.app!.canvas.graph!.getNodeById(nodeId)!.mode }, node.id) + } await expect.poll(() => getMode()).toBe(0) diff --git a/browser_tests/tests/dialog.spec.ts b/browser_tests/tests/dialog.spec.ts index 9a6889a38b..995af6e1b3 100644 --- a/browser_tests/tests/dialog.spec.ts +++ b/browser_tests/tests/dialog.spec.ts @@ -290,7 +290,7 @@ test('Blueprint overwrite', { tag: ['@subgraph'] }, async ({ comfyPage }) => { const confirmDialog = comfyPage.confirmDialog.root const { incrementButton } = comfyPage.vueNodes.getInputNumberControls(steps) - const dirtyGraphAndSave = async () => { + async function dirtyGraphAndSave() { await incrementButton.click() await comfyPage.page.keyboard.press('Control+s') } diff --git a/browser_tests/tests/groupCopyPaste.spec.ts b/browser_tests/tests/groupCopyPaste.spec.ts index de6e514663..ee1be198e0 100644 --- a/browser_tests/tests/groupCopyPaste.spec.ts +++ b/browser_tests/tests/groupCopyPaste.spec.ts @@ -21,13 +21,14 @@ test.describe('Group Copy Paste', { tag: ['@canvas'] }, () => { await comfyPage.clipboard.paste() await comfyPage.nextFrame() - const getGroupPositions = () => - comfyPage.page.evaluate(() => + function getGroupPositions() { + return comfyPage.page.evaluate(() => window.app!.graph.groups.map((g: { pos: number[] }) => ({ x: g.pos[0], y: g.pos[1] })) ) + } await expect.poll(getGroupPositions).toHaveLength(2) diff --git a/browser_tests/tests/groupNode.spec.ts b/browser_tests/tests/groupNode.spec.ts index d002d83681..90f06a27f2 100644 --- a/browser_tests/tests/groupNode.spec.ts +++ b/browser_tests/tests/groupNode.spec.ts @@ -137,7 +137,7 @@ test.describe('Group Node', { tag: '@node' }, () => { test('Manage group opens with the correct group selected', async ({ comfyPage }) => { - const makeGroup = async (name: string, type1: string, type2: string) => { + async function makeGroup(name: string, type1: string, type2: string) { const node1 = (await comfyPage.nodeOps.getNodeRefsByType(type1))[0] const node2 = (await comfyPage.nodeOps.getNodeRefsByType(type2))[0] await node1.click('title') @@ -204,7 +204,7 @@ test.describe('Group Node', { tag: '@node' }, () => { test('Reconnects inputs after configuration changed via manage dialog save', async ({ comfyPage }) => { - const expectSingleNode = async (type: string) => { + async function expectSingleNode(type: string) { const nodes = await comfyPage.nodeOps.getNodeRefsByType(type) expect(nodes).toHaveLength(1) return nodes[0] @@ -255,13 +255,13 @@ test.describe('Group Node', { tag: '@node' }, () => { const GROUP_NODE_NAME = 'group_node' // Node name in given workflow const GROUP_NODE_TYPE = `${GROUP_NODE_PREFIX}${GROUP_NODE_NAME}` - const isRegisteredLitegraph = async (comfyPage: ComfyPage) => { + async function isRegisteredLitegraph(comfyPage: ComfyPage) { return await comfyPage.page.evaluate((nodeType: string) => { return !!window.LiteGraph!.registered_node_types[nodeType] }, GROUP_NODE_TYPE) } - const isRegisteredNodeDefStore = async (comfyPage: ComfyPage) => { + async function isRegisteredNodeDefStore(comfyPage: ComfyPage) { await comfyPage.menu.nodeLibraryTab.open() const groupNodesFolderCt = await comfyPage.menu.nodeLibraryTab .getFolder(GROUP_NODE_CATEGORY) @@ -269,10 +269,10 @@ test.describe('Group Node', { tag: '@node' }, () => { return groupNodesFolderCt === 1 } - const verifyNodeLoaded = async ( + async function verifyNodeLoaded( comfyPage: ComfyPage, expectedCount: number - ) => { + ) { expect( await comfyPage.nodeOps.getNodeRefsByType(GROUP_NODE_TYPE) ).toHaveLength(expectedCount) diff --git a/browser_tests/tests/imageCompare.spec.ts b/browser_tests/tests/imageCompare.spec.ts index 1f14565822..daf008561d 100644 --- a/browser_tests/tests/imageCompare.spec.ts +++ b/browser_tests/tests/imageCompare.spec.ts @@ -510,7 +510,7 @@ test.describe('Image Compare', { tag: ['@widget', '@vue-nodes'] }, () => { const brokenAfter = 'http://127.0.0.1:1/broken2.png' const pageErrors: Error[] = [] - const onPageError = (err: Error) => { + function onPageError(err: Error) { pageErrors.push(err) } comfyPage.page.on('pageerror', onPageError) diff --git a/browser_tests/tests/interaction.spec.ts b/browser_tests/tests/interaction.spec.ts index b90338ec60..e43d7c80d0 100644 --- a/browser_tests/tests/interaction.spec.ts +++ b/browser_tests/tests/interaction.spec.ts @@ -82,10 +82,10 @@ test.describe('Node Interaction', () => { } ) - const dragSelectNodes = async ( + async function dragSelectNodes( comfyPage: ComfyPage, clipNodes: NodeReference[] - ) => { + ) { const clipNode1Pos = await clipNodes[0].getPosition() const clipNode2Pos = await clipNodes[1].getPosition() const offset = 64 @@ -117,15 +117,16 @@ test.describe('Node Interaction', () => { }) => { const clipNodes = await comfyPage.nodeOps.getNodeRefsByType('CLIPTextEncode') - const getPositions = () => - Promise.all(clipNodes.map((node) => node.getPosition())) - const testDirection = async ({ + function getPositions() { + return Promise.all(clipNodes.map((node) => node.getPosition())) + } + async function testDirection({ direction, expectedPosition }: { direction: string expectedPosition: (originalPosition: Position) => Position - }) => { + }) { const originalPositions = await getPositions() await dragSelectNodes(comfyPage, clipNodes) await comfyPage.command.executeCommand( @@ -671,7 +672,7 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => { }) test('Cursor style changes when panning', async ({ comfyPage }) => { - const getCursorStyle = async () => { + async function getCursorStyle() { return await comfyPage.page.evaluate(() => { return ( document.getElementById('graph-canvas')!.style.cursor || 'default' @@ -703,7 +704,7 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => { test('Properly resets dragging state after pan mode sequence', async ({ comfyPage }) => { - const getCursorStyle = async () => { + async function getCursorStyle() { return await comfyPage.page.evaluate(() => { return ( document.getElementById('graph-canvas')!.style.cursor || 'default' @@ -878,8 +879,9 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => { ) }) - const generateUniqueFilename = (extension = '') => - `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}${extension}` + function generateUniqueFilename(extension = '') { + return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}${extension}` + } test.describe('Restore all open workflows on reload', () => { let workflowA: string @@ -1077,7 +1079,7 @@ test.describe('Viewport settings', () => { comfyPage, comfyMouse }) => { - const changeTab = async (tab: Locator) => { + async function changeTab(tab: Locator) { await tab.click() await comfyPage.nextFrame() await comfyMouse.move(DefaultGraphPositions.emptySpace) @@ -1406,7 +1408,7 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { test('Cursor changes appropriately in different modes', async ({ comfyPage }) => { - const getCursorStyle = async () => { + async function getCursorStyle() { return await comfyPage.page.evaluate(() => { return ( document.getElementById('graph-canvas')!.style.cursor || 'default' diff --git a/browser_tests/tests/load3d/gizmoControls.spec.ts b/browser_tests/tests/load3d/gizmoControls.spec.ts index fa666cb4aa..5becf01cd9 100644 --- a/browser_tests/tests/load3d/gizmoControls.spec.ts +++ b/browser_tests/tests/load3d/gizmoControls.spec.ts @@ -3,14 +3,15 @@ import type { Page } from '@playwright/test' import { load3dTest as test } from '@e2e/fixtures/helpers/Load3DFixtures' -const getGizmoConfig = (page: Page) => - page.evaluate(() => { +function getGizmoConfig(page: Page) { + return page.evaluate(() => { const n = window.app!.graph.getNodeById(1) const modelConfig = n?.properties?.['Model Config'] as | { gizmo?: { enabled: boolean; mode: string } } | undefined return modelConfig?.gizmo }) +} test.describe('Load3D Gizmo Controls', () => { test( diff --git a/browser_tests/tests/load3d/load3d.spec.ts b/browser_tests/tests/load3d/load3d.spec.ts index f3ec05cbc1..14230a64b8 100644 --- a/browser_tests/tests/load3d/load3d.spec.ts +++ b/browser_tests/tests/load3d/load3d.spec.ts @@ -155,7 +155,7 @@ test.describe('Load3D', () => { async ({ comfyPage, load3d }) => { await expect(load3d.uploadBackgroundImageButton).toBeVisible() const node = await comfyPage.nodeOps.getNodeRefById(1) - const readBackgroundImage = async () => { + async function readBackgroundImage() { const properties = await node.getProperty>( 'properties' @@ -222,7 +222,7 @@ test.describe('Load3D', () => { await expect(load3d.gridToggleButton).toBeVisible() const node = await comfyPage.nodeOps.getNodeRefById(1) - const readShowGrid = async () => { + async function readShowGrid() { const properties = await node.getProperty>( 'properties' diff --git a/browser_tests/tests/nodeHelp.spec.ts b/browser_tests/tests/nodeHelp.spec.ts index 11cd72b1fd..eb3c845207 100644 --- a/browser_tests/tests/nodeHelp.spec.ts +++ b/browser_tests/tests/nodeHelp.spec.ts @@ -55,7 +55,7 @@ async function setLocaleAndWaitForWorkflowReload( const waitForReload = new Promise((resolve, reject) => { const timeoutAt = performance.now() + 5000 - const tick = () => { + function tick() { if (changeTracker.isLoadingGraph) { sawLoading = true } diff --git a/browser_tests/tests/nodeSearchBox.spec.ts b/browser_tests/tests/nodeSearchBox.spec.ts index ad57ae29e3..911e4cba15 100644 --- a/browser_tests/tests/nodeSearchBox.spec.ts +++ b/browser_tests/tests/nodeSearchBox.spec.ts @@ -166,10 +166,10 @@ test.describe('Node search box', { tag: '@node' }, () => { }) test.describe('Filtering', () => { - const expectFilterChips = async ( + async function expectFilterChips( comfyPage: ComfyPage, expectedTexts: string[] - ) => { + ) { const chips = comfyPage.searchBox.filterChips // Check that the number of chips matches the expected count diff --git a/browser_tests/tests/nodeSearchBoxV2.spec.ts b/browser_tests/tests/nodeSearchBoxV2.spec.ts index 7e014a859e..e9edf5969c 100644 --- a/browser_tests/tests/nodeSearchBoxV2.spec.ts +++ b/browser_tests/tests/nodeSearchBoxV2.spec.ts @@ -243,15 +243,18 @@ test.describe('Node search box V2', { tag: '@node' }, () => { comfyPage }) => { const { searchBoxV2 } = comfyPage - const switchToDesktop = () => - comfyPage.page.setViewportSize({ width: 1280, height: 800 }) - const switchToMobile = () => - comfyPage.page.setViewportSize({ width: 360, height: 800 }) - const expectExpanded = (value: 'true' | 'false') => - expect(searchBoxV2.sidebarToggle).toHaveAttribute( + function switchToDesktop() { + return comfyPage.page.setViewportSize({ width: 1280, height: 800 }) + } + function switchToMobile() { + return comfyPage.page.setViewportSize({ width: 360, height: 800 }) + } + function expectExpanded(value: 'true' | 'false') { + return expect(searchBoxV2.sidebarToggle).toHaveAttribute( 'aria-expanded', value ) + } await switchToDesktop() await searchBoxV2.open() diff --git a/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts b/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts index 3a50e4a887..4d3637e47b 100644 --- a/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts +++ b/browser_tests/tests/nodeSearchBoxV2Extended.spec.ts @@ -312,7 +312,9 @@ test.describe('Node search box V2 extended', { tag: '@node' }, () => { test.describe('Search behavior', () => { test('Search narrows results progressively', async ({ comfyPage }) => { const { searchBoxV2 } = comfyPage - const getCount = () => searchBoxV2.results.count() + function getCount() { + return searchBoxV2.results.count() + } await searchBoxV2.open() diff --git a/browser_tests/tests/painter.spec.ts b/browser_tests/tests/painter.spec.ts index a790a956be..908b50c976 100644 --- a/browser_tests/tests/painter.spec.ts +++ b/browser_tests/tests/painter.spec.ts @@ -758,8 +758,8 @@ test.describe('Painter', { tag: ['@widget', '@vue-nodes'] }, () => { await drawStroke(comfyPage.page, canvas, { yPct: 0.75 }) await comfyPage.nextFrame() - const hasContentAtRow = (yFraction: number) => - canvas.evaluate((el: HTMLCanvasElement, y: number) => { + function hasContentAtRow(yFraction: number) { + return canvas.evaluate((el: HTMLCanvasElement, y: number) => { const ctx = el.getContext('2d') if (!ctx) return false const cy = Math.floor(el.height * y) @@ -769,6 +769,7 @@ test.describe('Painter', { tag: ['@widget', '@vue-nodes'] }, () => { } return false }, yFraction) + } await expect .poll(() => hasContentAtRow(0.25), { diff --git a/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts b/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts index 96954139a6..df87a4da90 100644 --- a/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts +++ b/browser_tests/tests/propertiesPanel/errorsTabMissingMediaRuntime.spec.ts @@ -77,7 +77,7 @@ const cloudUploadRaceTest = comfyPageFixture.extend<{ } cloudUploadAssetStateByPage.set(page, state) - const assetsRouteHandler = async (route: Route) => { + async function assetsRouteHandler(route: Route) { const allAssets = [ cloudDefaultGraphInputAsset, ...(state.isUploadedAssetAvailable ? [cloudUploadedVideoAsset] : []) @@ -149,7 +149,7 @@ async function delayNextUpload(comfyPage: ComfyPage) { releaseUpload = resolve }) - const uploadRouteHandler = async (route: Route) => { + async function uploadRouteHandler(route: Route) { resolveUploadStarted() await release await route.continue() diff --git a/browser_tests/tests/queueNotificationBanners.spec.ts b/browser_tests/tests/queueNotificationBanners.spec.ts index ca64919045..3051b5249c 100644 --- a/browser_tests/tests/queueNotificationBanners.spec.ts +++ b/browser_tests/tests/queueNotificationBanners.spec.ts @@ -15,7 +15,9 @@ const REQUEST_ID_SECONDARY = 2 const REQUEST_ID_MISMATCH = 999 let nextRequestId = 1000 -const newRequestId = () => nextRequestId++ +function newRequestId() { + return nextRequestId++ +} function bannerLocator(page: Page) { return page.getByTestId(TestIds.queue.notificationBanner) diff --git a/browser_tests/tests/remoteWidgets.spec.ts b/browser_tests/tests/remoteWidgets.spec.ts index f5eddc115f..4de2d75f20 100644 --- a/browser_tests/tests/remoteWidgets.spec.ts +++ b/browser_tests/tests/remoteWidgets.spec.ts @@ -6,11 +6,11 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage' test.describe('Remote COMBO Widget', { tag: '@widget' }, () => { const mockOptions = ['d', 'c', 'b', 'a'] - const addRemoteWidgetNode = async ( + async function addRemoteWidgetNode( comfyPage: ComfyPage, nodeName: string, count: number = 1 - ) => { + ) { const tab = comfyPage.menu.nodeLibraryTab await tab.open() await tab.getFolder('DevTools').click() @@ -21,24 +21,24 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => { } } - const getWidgetOptions = async ( + async function getWidgetOptions( comfyPage: ComfyPage, nodeName: string - ): Promise => { + ): Promise { return await comfyPage.page.evaluate((name) => { const node = window.app!.graph!.nodes.find((node) => node.title === name) return node!.widgets![0].options.values as string[] | undefined }, nodeName) } - const getWidgetValue = async (comfyPage: ComfyPage, nodeName: string) => { + async function getWidgetValue(comfyPage: ComfyPage, nodeName: string) { return await comfyPage.page.evaluate((name) => { const node = window.app!.graph!.nodes.find((node) => node.title === name) return node!.widgets![0].value }, nodeName) } - const clickRefreshButton = (comfyPage: ComfyPage, nodeName: string) => { + function clickRefreshButton(comfyPage: ComfyPage, nodeName: string) { return comfyPage.page.evaluate((name) => { const node = window.app!.graph!.nodes.find((node) => node.title === name) const buttonWidget = node!.widgets!.find((w) => w.name === 'refresh') diff --git a/browser_tests/tests/selectionToolbox.spec.ts b/browser_tests/tests/selectionToolbox.spec.ts index 03ac01ac1e..74079e730b 100644 --- a/browser_tests/tests/selectionToolbox.spec.ts +++ b/browser_tests/tests/selectionToolbox.spec.ts @@ -13,16 +13,21 @@ test.beforeEach(async ({ comfyPage }) => { const BLUE_COLOR = 'rgb(51, 51, 85)' const RED_COLOR = 'rgb(85, 51, 51)' -const getColorPickerButton = (comfyPage: { page: Page }) => - comfyPage.page.getByTestId(TestIds.selectionToolbox.colorPickerButton) +function getColorPickerButton(comfyPage: { page: Page }) { + return comfyPage.page.getByTestId(TestIds.selectionToolbox.colorPickerButton) +} -const getColorPickerCurrentColor = (comfyPage: { page: Page }) => - comfyPage.page.getByTestId(TestIds.selectionToolbox.colorPickerCurrentColor) +function getColorPickerCurrentColor(comfyPage: { page: Page }) { + return comfyPage.page.getByTestId( + TestIds.selectionToolbox.colorPickerCurrentColor + ) +} -const getColorPickerGroup = (comfyPage: { page: Page }) => - comfyPage.page.getByRole('group').filter({ +function getColorPickerGroup(comfyPage: { page: Page }) { + return comfyPage.page.getByRole('group').filter({ has: comfyPage.page.getByTestId(TestIds.selectionToolbox.colorBlue) }) +} test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => { test.beforeEach(async ({ comfyPage }) => { diff --git a/browser_tests/tests/selectionToolboxSubmenus.spec.ts b/browser_tests/tests/selectionToolboxSubmenus.spec.ts index 0aa2515874..d26b55675c 100644 --- a/browser_tests/tests/selectionToolboxSubmenus.spec.ts +++ b/browser_tests/tests/selectionToolboxSubmenus.spec.ts @@ -19,8 +19,9 @@ test.describe( await comfyPage.nextFrame() }) - const openMoreOptions = (comfyPage: ComfyPage) => - openMoreOptionsMenu(comfyPage, 'KSampler') + function openMoreOptions(comfyPage: ComfyPage) { + return openMoreOptionsMenu(comfyPage, 'KSampler') + } test('hides Node Info from More Options menu when the new menu is disabled', async ({ comfyPage diff --git a/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts b/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts index 6e955335e9..b4993e882b 100644 --- a/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts +++ b/browser_tests/tests/sidebar/sidebarSplitterWidth.spec.ts @@ -114,11 +114,12 @@ test.describe('Sidebar splitter width independence', () => { await dragGutter(comfyPage, 80) // Check that saved sizes sum to ~100% - const getSidebarSizes = () => - comfyPage.page.evaluate(() => { + function getSidebarSizes() { + return comfyPage.page.evaluate(() => { const raw = localStorage.getItem('unified-sidebar') return raw ? (JSON.parse(raw) as number[]) : null }) + } await expect .poll(async () => { diff --git a/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts b/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts index 30ab964d1f..8901512bb3 100644 --- a/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts +++ b/browser_tests/tests/subgraph/subgraphBreadcrumb.spec.ts @@ -25,7 +25,7 @@ const MISSING_NODES_SUBGRAPH_NODE_ID = '2' * the root graph, then the inner subgraph node that appears inside. Matches * how a user navigates via the canvas. */ -const enterNestedSubgraphs = async (comfyPage: ComfyPage) => { +async function enterNestedSubgraphs(comfyPage: ComfyPage) { const outerNode = await comfyPage.nodeOps.getNodeRefById( OUTER_SUBGRAPH_NODE_ID_IN_NESTED ) diff --git a/browser_tests/tests/subgraph/subgraphPromotion.spec.ts b/browser_tests/tests/subgraph/subgraphPromotion.spec.ts index f4f271f17a..344ab3dfdc 100644 --- a/browser_tests/tests/subgraph/subgraphPromotion.spec.ts +++ b/browser_tests/tests/subgraph/subgraphPromotion.spec.ts @@ -689,7 +689,9 @@ test('Can intermix linked and proxy @vue-nodes', async ({ comfyPage }) => { const fromSlot = ksampler.getSlot('steps') const toPos = await comfyPage.subgraph.getInputSlot().getOpenSlotPosition() await fromSlot.dragTo(comfyPage.canvas, { targetPosition: toPos }) - const isConnected = () => comfyPage.vueNodes.isSlotConnected(fromSlot) + function isConnected() { + return comfyPage.vueNodes.isSlotConnected(fromSlot) + } await expect.poll(isConnected).toBe(true) await comfyPage.subgraph.exitViaBreadcrumb() @@ -735,7 +737,9 @@ test('Link already promoted widget @vue-nodes', async ({ comfyPage }) => { const fromSlot = ksampler.getSlot('steps') const toPos = await comfyPage.subgraph.getInputSlot().getOpenSlotPosition() await fromSlot.dragTo(comfyPage.canvas, { targetPosition: toPos }) - const isConnected = () => comfyPage.vueNodes.isSlotConnected(fromSlot) + function isConnected() { + return comfyPage.vueNodes.isSlotConnected(fromSlot) + } await expect.poll(isConnected).toBe(true) await comfyPage.subgraph.exitViaBreadcrumb() @@ -812,7 +816,9 @@ test('Linked widgets can not be demoted @vue-nodes', async ({ comfyPage }) => { const fromSlot = ksampler.getSlot('steps') const toPos = await comfyPage.subgraph.getInputSlot().getOpenSlotPosition() await fromSlot.dragTo(comfyPage.canvas, { targetPosition: toPos }) - const isConnected = () => comfyPage.vueNodes.isSlotConnected(fromSlot) + function isConnected() { + return comfyPage.vueNodes.isSlotConnected(fromSlot) + } await expect.poll(isConnected).toBe(true) await comfyPage.subgraph.exitViaBreadcrumb() diff --git a/browser_tests/tests/subgraph/subgraphSerialization.spec.ts b/browser_tests/tests/subgraph/subgraphSerialization.spec.ts index c843317764..cc9e094c41 100644 --- a/browser_tests/tests/subgraph/subgraphSerialization.spec.ts +++ b/browser_tests/tests/subgraph/subgraphSerialization.spec.ts @@ -368,15 +368,16 @@ test.describe('Subgraph Serialization', { tag: ['@subgraph'] }, () => { ] const SENTINEL_IDS = new Set([-1, -10, -20]) - const isSentinelNodeId = (id: number | string): id is number => - typeof id === 'number' && SENTINEL_IDS.has(id) + function isSentinelNodeId(id: number | string): id is number { + return typeof id === 'number' && SENTINEL_IDS.has(id) + } - const checkEndpoint = ( + function checkEndpoint( label: string, kind: 'origin_id' | 'target_id', id: number | string, g: typeof graph - ): string | null => { + ): string | null { if (isSentinelNodeId(id)) return null if (typeof id !== 'number' || !g._nodes_by_id[id]) { return `${label}: ${kind} ${id} invalid or not found` diff --git a/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts b/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts index 3d0a0348f7..fa43257d5c 100644 --- a/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts +++ b/browser_tests/tests/subgraph/subgraphZeroUuid.spec.ts @@ -14,7 +14,7 @@ test.describe( ) await comfyPage.vueNodes.waitForNodes() - const assertInSubgraph = async (inSubgraph: boolean) => { + async function assertInSubgraph(inSubgraph: boolean) { await expect .poll(() => comfyPage.subgraph.isInSubgraph()) .toBe(inSubgraph) diff --git a/browser_tests/tests/versionMismatchWarnings.spec.ts b/browser_tests/tests/versionMismatchWarnings.spec.ts index b24f798c86..4630eff387 100644 --- a/browser_tests/tests/versionMismatchWarnings.spec.ts +++ b/browser_tests/tests/versionMismatchWarnings.spec.ts @@ -7,9 +7,9 @@ test.describe('Version Mismatch Warnings', { tag: '@slow' }, () => { const ALWAYS_AHEAD_OF_INSTALLED_VERSION = '100.100.100' const ALWAYS_BEHIND_INSTALLED_VERSION = '0.0.0' - const createMockSystemStatsRes = ( + function createMockSystemStatsRes( requiredFrontendVersion: string - ): SystemStats => { + ): SystemStats { return { system: { os: 'posix', diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts b/browser_tests/tests/vueNodes/groups/groups.spec.ts index e5b8d586e1..5cb574bc01 100644 --- a/browser_tests/tests/vueNodes/groups/groups.spec.ts +++ b/browser_tests/tests/vueNodes/groups/groups.spec.ts @@ -79,7 +79,7 @@ async function getNodeGroupCenteringErrors( const nodeRect = nodeElement.getBoundingClientRect() - const getCenteringError = (group: GraphGroup): NodeGroupCenteringError => { + function getCenteringError(group: GraphGroup): NodeGroupCenteringError { const [groupStartX, groupStartY] = app.canvasPosToClientPos([ group.pos[0], group.pos[1] diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts index 6b0e1b752a..aafaae5b6d 100644 --- a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts @@ -1151,10 +1151,11 @@ test.describe('Vue Node Widget Link Position', { tag: '@vue-nodes' }, () => { const ksampler = await comfyPage.page.evaluate(() => { const node = window.app!.graph.nodes.find((n) => n.type === 'KSampler') if (!node) return null - const findIndex = (name: string) => - node.inputs.findIndex( + function findIndex(name: string) { + return node.inputs.findIndex( (input) => input.name === name || input.widget?.name === name ) + } return { id: node.id, denoiseIndex: findIndex('denoise'), diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts index af0ce5761c..2aab4870e2 100644 --- a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts @@ -8,10 +8,10 @@ import type { ComfyPage } from '@e2e/fixtures/ComfyPage' import type { Position } from '@e2e/fixtures/types' test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => { - const getHeaderPos = async ( + async function getHeaderPos( comfyPage: ComfyPage, title: string - ): Promise<{ x: number; y: number; width: number; height: number }> => { + ): Promise<{ x: number; y: number; width: number; height: number }> { const box = await comfyPage.vueNodes .getNodeByTitle(title) .getByTestId('node-title') @@ -21,27 +21,30 @@ test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => { return box } - const getLoadCheckpointHeaderPos = async (comfyPage: ComfyPage) => - getHeaderPos(comfyPage, 'Load Checkpoint') + async function getLoadCheckpointHeaderPos(comfyPage: ComfyPage) { + return getHeaderPos(comfyPage, 'Load Checkpoint') + } - const expectPosChanged = async (pos1: Position, pos2: Position) => { + async function expectPosChanged(pos1: Position, pos2: Position) { const diffX = Math.abs(pos2.x - pos1.x) const diffY = Math.abs(pos2.y - pos1.y) expect(diffX).toBeGreaterThan(0) expect(diffY).toBeGreaterThan(0) } - const deltaBetween = (before: Position, after: Position) => ({ - x: after.x - before.x, - y: after.y - before.y - }) + function deltaBetween(before: Position, after: Position) { + return { + x: after.x - before.x, + y: after.y - before.y + } + } - const expectSameDelta = (a: Position, b: Position, tol = 2) => { + function expectSameDelta(a: Position, b: Position, tol = 2) { expect(Math.abs(a.x - b.x)).toBeLessThanOrEqual(tol) expect(Math.abs(a.y - b.y)).toBeLessThanOrEqual(tol) } - const dragFromTabButton = async (comfyPage: ComfyPage, button: Locator) => { + async function dragFromTabButton(comfyPage: ComfyPage, button: Locator) { const box = await button.boundingBox() if (!box) throw new Error('Tab button has no bounding box') const start = { @@ -172,7 +175,7 @@ test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => { const dx = 120 const dy = 80 - const clickNodeTitleWithMeta = async (title: string) => { + async function clickNodeTitleWithMeta(title: string) { await comfyPage.vueNodes .getNodeByTitle(title) .getByTestId('node-title') diff --git a/browser_tests/tests/vueNodes/widgets/legacy.spec.ts b/browser_tests/tests/vueNodes/widgets/legacy.spec.ts index 9b5ac3adf8..8774805091 100644 --- a/browser_tests/tests/vueNodes/widgets/legacy.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/legacy.spec.ts @@ -15,10 +15,11 @@ test('@vue-nodes In App Mode, widget width updates with panel size', async ({ await comfyPage.appMode.enterAppModeWithInputs([['10', 'legacy_widget']]) }) - const getWidth = () => - comfyPage.page.evaluate( + function getWidth() { + return comfyPage.page.evaluate( () => graph!.getNodeById(10)!.widgets![0].width ?? 0 ) + } await test.step('Mouse clicks resolve to button regions', async () => { const legacyWidget = comfyPage.appMode.linearWidgets.locator('canvas') diff --git a/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts b/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts index f44de55aaa..b5458958fe 100644 --- a/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts @@ -5,11 +5,15 @@ import { import type { ComfyPage } from '@e2e/fixtures/ComfyPage' test.describe('Vue Multiline String Widget', { tag: '@vue-nodes' }, () => { - const getFirstClipNode = (comfyPage: ComfyPage) => - comfyPage.vueNodes.getNodeByTitle('CLIP Text Encode (Prompt)').first() + function getFirstClipNode(comfyPage: ComfyPage) { + return comfyPage.vueNodes + .getNodeByTitle('CLIP Text Encode (Prompt)') + .first() + } - const getFirstMultilineStringWidget = (comfyPage: ComfyPage) => - getFirstClipNode(comfyPage).getByRole('textbox', { name: 'text' }) + function getFirstMultilineStringWidget(comfyPage: ComfyPage) { + return getFirstClipNode(comfyPage).getByRole('textbox', { name: 'text' }) + } test('should allow entering text', async ({ comfyPage }) => { const textarea = getFirstMultilineStringWidget(comfyPage) diff --git a/browser_tests/tests/widget.spec.ts b/browser_tests/tests/widget.spec.ts index ed70f5b4f8..62ac37ac8c 100644 --- a/browser_tests/tests/widget.spec.ts +++ b/browser_tests/tests/widget.spec.ts @@ -56,8 +56,8 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { test('should refresh combo values of optional inputs', async ({ comfyPage }) => { - const getComboValues = async () => - comfyPage.page.evaluate(() => { + async function getComboValues() { + return comfyPage.page.evaluate(() => { return window .app!.graph!.nodes.find( (node) => node.title === 'Node With Optional Combo Input' @@ -65,6 +65,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { .widgets!.find((widget) => widget.name === 'optional_combo_input')! .options.values }) + } await comfyPage.workflow.loadWorkflow('inputs/optional_combo_input') const initialComboValues = await getComboValues() @@ -82,8 +83,8 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { test('Should refresh combo values of nodes with v2 combo input spec', async ({ comfyPage }) => { - const getComboValues = async () => - comfyPage.page.evaluate(() => { + async function getComboValues() { + return comfyPage.page.evaluate(() => { return window .app!.graph!.nodes.find( (node) => node.title === 'Node With V2 Combo Input' @@ -91,6 +92,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { .widgets!.find((widget) => widget.name === 'combo_input')!.options .values }) + } await comfyPage.workflow.loadWorkflow('inputs/node_with_v2_combo_input') // click canvas to focus diff --git a/browser_tests/tests/workflowPersistence.spec.ts b/browser_tests/tests/workflowPersistence.spec.ts index 614796119d..2ea610d686 100644 --- a/browser_tests/tests/workflowPersistence.spec.ts +++ b/browser_tests/tests/workflowPersistence.spec.ts @@ -213,10 +213,11 @@ test.describe('Workflow Persistence', () => { .poll(() => comfyPage.nodeOps.getNodeCount()) .toBeGreaterThanOrEqual(2) - const getNodeTypes = () => - comfyPage.page.evaluate(() => + function getNodeTypes() { + return comfyPage.page.evaluate(() => window.app!.graph.nodes.map((n: { type: string }) => n.type) ) + } await expect.poll(getNodeTypes).toContain('KSampler') await expect.poll(getNodeTypes).toContain('EmptyLatentImage') await expect @@ -552,11 +553,12 @@ test.describe('Workflow Persistence', () => { await comfyPage.setup({ clearStorage: false }) await comfyPage.nextFrame() - const getSplitterSizes = () => - comfyPage.page.evaluate(() => { + function getSplitterSizes() { + return comfyPage.page.evaluate(() => { const raw = localStorage.getItem('Comfy.Splitter.MainSplitter') return raw ? (JSON.parse(raw) as number[]) : null }) + } await expect .poll(async () => { diff --git a/browser_tests/utils/backupUtils.ts b/browser_tests/utils/backupUtils.ts index 063e42cc4b..2bd689563b 100644 --- a/browser_tests/utils/backupUtils.ts +++ b/browser_tests/utils/backupUtils.ts @@ -3,9 +3,11 @@ import path from 'path' type PathParts = readonly [string, ...string[]] -const getBackupPath = (originalPath: string): string => `${originalPath}.bak` +function getBackupPath(originalPath: string): string { + return `${originalPath}.bak` +} -const resolvePathIfExists = (pathParts: PathParts): string | null => { +function resolvePathIfExists(pathParts: PathParts): string | null { const resolvedPath = path.resolve(...pathParts) if (!fs.pathExistsSync(resolvedPath)) { console.warn(`Path not found: ${resolvedPath}`) @@ -14,7 +16,7 @@ const resolvePathIfExists = (pathParts: PathParts): string | null => { return resolvedPath } -const createScaffoldingCopy = (srcDir: string, destDir: string) => { +function createScaffoldingCopy(srcDir: string, destDir: string) { // Get all items (files and directories) in the source directory const items = fs.readdirSync(srcDir, { withFileTypes: true }) diff --git a/packages/shared-frontend-utils/src/formatUtil.ts b/packages/shared-frontend-utils/src/formatUtil.ts index 01e52cdd4a..d930ed9f2b 100644 --- a/packages/shared-frontend-utils/src/formatUtil.ts +++ b/packages/shared-frontend-utils/src/formatUtil.ts @@ -195,7 +195,7 @@ export function processDynamicPrompt(input: string): string { let result = '' input = stripComments(input) - const handleEscape = () => { + function handleEscape() { const nextChar = input[i++] return '\\' + nextChar } @@ -347,7 +347,7 @@ export function formatDate(text: string, date: Date) { * Generate a cache key from parameters * Sorts the parameters to ensure consistent keys regardless of parameter order */ -export const paramsToCacheKey = (params: unknown): string => { +export function paramsToCacheKey(params: unknown): string { if (typeof params === 'string') return params if (typeof params === 'object' && params !== null) return Object.keys(params) @@ -362,7 +362,7 @@ export const paramsToCacheKey = (params: unknown): string => { * Generates a RFC4122 compliant UUID v4 using the native crypto API when available * @returns A properly formatted UUID string */ -export const generateUUID = (): string => { +export function generateUUID(): string { // Use native crypto.randomUUID() if available (modern browsers) if ( typeof crypto !== 'undefined' && @@ -379,18 +379,21 @@ export const generateUUID = (): string => { }) } -const isCivitaiHost = (hostname: string): boolean => - hostname === 'civitai.com' || - hostname.endsWith('.civitai.com') || - hostname === 'civitai.red' || - hostname.endsWith('.civitai.red') +function isCivitaiHost(hostname: string): boolean { + return ( + hostname === 'civitai.com' || + hostname.endsWith('.civitai.com') || + hostname === 'civitai.red' || + hostname.endsWith('.civitai.red') + ) +} /** * Checks if a URL belongs to any Civitai domain (civitai.com or civitai.red). * Use this for source-name detection; use `isCivitaiModelUrl` when the URL * must also match a specific model API path format. */ -export const isCivitaiUrl = (url: string): boolean => { +export function isCivitaiUrl(url: string): boolean { if (!isValidUrl(url)) return false return isCivitaiHost(new URL(url).hostname.toLowerCase()) } @@ -403,7 +406,7 @@ export const isCivitaiUrl = (url: string): boolean => { * isCivitaiModelUrl('https://civitai.com/api/v1/models-versions/15342') // true * isCivitaiModelUrl('https://example.com/model.safetensors') // false */ -export const isCivitaiModelUrl = (url: string): boolean => { +export function isCivitaiModelUrl(url: string): boolean { if (!isValidUrl(url)) return false const urlObj = new URL(url) @@ -426,7 +429,7 @@ export const isCivitaiModelUrl = (url: string): boolean => { * 'https://huggingface.co/bfl/FLUX.1/resolve/main/flux1-canny-dev.safetensors?download=true' * ) // https://huggingface.co/bfl/FLUX.1 */ -export const downloadUrlToHfRepoUrl = (url: string): string => { +export function downloadUrlToHfRepoUrl(url: string): string { try { const urlObj = new URL(url) const pathname = urlObj.pathname diff --git a/packages/shared-frontend-utils/src/networkUtil.ts b/packages/shared-frontend-utils/src/networkUtil.ts index 7ae5972326..607b93e082 100644 --- a/packages/shared-frontend-utils/src/networkUtil.ts +++ b/packages/shared-frontend-utils/src/networkUtil.ts @@ -1,7 +1,7 @@ import axios from 'axios' const VALID_STATUS_CODES = [200, 201, 301, 302, 307, 308] -export const checkUrlReachable = async (url: string): Promise => { +export async function checkUrlReachable(url: string): Promise { try { const response = await axios.head(url) // Additional check for successful response diff --git a/scripts/check-unused-i18n-keys.ts b/scripts/check-unused-i18n-keys.ts index 5998369d78..010af1c753 100755 --- a/scripts/check-unused-i18n-keys.ts +++ b/scripts/check-unused-i18n-keys.ts @@ -103,8 +103,9 @@ function shouldIgnoreKey(key: string): boolean { // Search for key usage in source files function isKeyUsed(key: string, sourceFiles: string[]): boolean { // Escape special regex characters - const escapeRegex = (str: string) => - str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + function escapeRegex(str: string) { + return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + } const escapedKey = escapeRegex(key) const lastPart = key.split('.').pop() const escapedLastPart = lastPart ? escapeRegex(lastPart) : '' diff --git a/scripts/collect-i18n-general.ts b/scripts/collect-i18n-general.ts index 42ca568a8a..b67564a9fd 100644 --- a/scripts/collect-i18n-general.ts +++ b/scripts/collect-i18n-general.ts @@ -18,7 +18,7 @@ const localePath = './src/locales/en/main.json' const commandsPath = './src/locales/en/commands.json' const settingsPath = './src/locales/en/settings.json' -const extractMenuCommandLocaleStrings = (): Set => { +function extractMenuCommandLocaleStrings(): Set { const labels = new Set() for (const [category, _] of CORE_MENU_COMMANDS) { category.forEach((category) => labels.add(category)) diff --git a/scripts/size-report.js b/scripts/size-report.js index 96f334cdb6..a9b14c874a 100644 --- a/scripts/size-report.js +++ b/scripts/size-report.js @@ -93,7 +93,9 @@ async function buildBundleReport() { * @param {string[]} files * @returns {string[]} */ - const filterFiles = (files) => files.filter((file) => file.endsWith('.json')) + function filterFiles(files) { + return files.filter((file) => file.endsWith('.json')) + } const currFiles = filterFiles(await readdir(currDir)) const baselineFiles = existsSync(prevDir) diff --git a/src/App.vue b/src/App.vue index acc8fdb237..c71f7b9ee0 100644 --- a/src/App.vue +++ b/src/App.vue @@ -34,7 +34,7 @@ watch( { flush: 'post' } ) -const showContextMenu = (event: MouseEvent) => { +function showContextMenu(event: MouseEvent) { const { target } = event switch (true) { case target instanceof HTMLTextAreaElement: diff --git a/src/base/common/downloadUtil.ts b/src/base/common/downloadUtil.ts index aac46ad4ce..88da6041a9 100644 --- a/src/base/common/downloadUtil.ts +++ b/src/base/common/downloadUtil.ts @@ -70,7 +70,7 @@ export function downloadBlob(filename: string, blob: Blob): void { * @param url - The URL to extract filename from * @returns The extracted filename or null if not found */ -const extractFilenameFromUrl = (url: string): string | null => { +function extractFilenameFromUrl(url: string): string | null { try { const urlObj = new URL(url, window.location.origin) return urlObj.searchParams.get('filename') diff --git a/src/base/credits/comfyCredits.ts b/src/base/credits/comfyCredits.ts index b49df573f3..bff5841b60 100644 --- a/src/base/credits/comfyCredits.ts +++ b/src/base/credits/comfyCredits.ts @@ -3,7 +3,7 @@ const DEFAULT_NUMBER_FORMAT: Intl.NumberFormatOptions = { maximumFractionDigits: 2 } -const formatNumber = ({ +function formatNumber({ value, locale, options @@ -11,7 +11,7 @@ const formatNumber = ({ value: number locale?: string options?: Intl.NumberFormatOptions -}): string => { +}): string { const merged: Intl.NumberFormatOptions = { ...DEFAULT_NUMBER_FORMAT, ...options @@ -31,19 +31,25 @@ const formatNumber = ({ export const CREDITS_PER_USD = 211 export const COMFY_CREDIT_RATE_CENTS = CREDITS_PER_USD / 100 // credits per cent -export const usdToCents = (usd: number): number => Math.round(usd * 100) +export function usdToCents(usd: number): number { + return Math.round(usd * 100) +} -export const centsToCredits = (cents: number): number => - Math.round(cents * COMFY_CREDIT_RATE_CENTS) +export function centsToCredits(cents: number): number { + return Math.round(cents * COMFY_CREDIT_RATE_CENTS) +} -export const creditsToCents = (credits: number): number => - Math.round(credits / COMFY_CREDIT_RATE_CENTS) +export function creditsToCents(credits: number): number { + return Math.round(credits / COMFY_CREDIT_RATE_CENTS) +} -export const usdToCredits = (usd: number): number => - Math.round(usd * CREDITS_PER_USD) +export function usdToCredits(usd: number): number { + return Math.round(usd * CREDITS_PER_USD) +} -export const creditsToUsd = (credits: number): number => - Math.round((credits / CREDITS_PER_USD) * 100) / 100 +export function creditsToUsd(credits: number): number { + return Math.round((credits / CREDITS_PER_USD) * 100) / 100 +} export type FormatOptions = { value: number @@ -63,63 +69,68 @@ export type FormatFromUsdOptions = { numberOptions?: Intl.NumberFormatOptions } -export const formatCredits = ({ +export function formatCredits({ value, locale, numberOptions -}: FormatOptions): string => - formatNumber({ value, locale, options: numberOptions }) +}: FormatOptions): string { + return formatNumber({ value, locale, options: numberOptions }) +} -export const formatCreditsFromCents = ({ +export function formatCreditsFromCents({ cents, locale, numberOptions -}: FormatFromCentsOptions): string => - formatCredits({ +}: FormatFromCentsOptions): string { + return formatCredits({ value: centsToCredits(cents), locale, numberOptions }) +} -export const formatCreditsFromUsd = ({ +export function formatCreditsFromUsd({ usd, locale, numberOptions -}: FormatFromUsdOptions): string => - formatCredits({ +}: FormatFromUsdOptions): string { + return formatCredits({ value: usdToCredits(usd), locale, numberOptions }) +} -export const formatUsd = ({ +export function formatUsd({ value, locale, numberOptions -}: FormatOptions): string => - formatNumber({ +}: FormatOptions): string { + return formatNumber({ value, locale, options: numberOptions }) +} -export const formatUsdFromCents = ({ +export function formatUsdFromCents({ cents, locale, numberOptions -}: FormatFromCentsOptions): string => - formatUsd({ +}: FormatFromCentsOptions): string { + return formatUsd({ value: cents / 100, locale, numberOptions }) +} /** * Clamps a USD value to the allowed range for credit purchases * @param value - The USD amount to clamp * @returns The clamped value between $1 and $1000, or 0 if NaN */ -export const clampUsd = (value: number): number => { +export function clampUsd(value: number): number { if (Number.isNaN(value)) return 0 return Math.min(1000, Math.max(1, value)) } diff --git a/src/base/wheelGestures.ts b/src/base/wheelGestures.ts index 3e4f952759..3d708b43b9 100644 --- a/src/base/wheelGestures.ts +++ b/src/base/wheelGestures.ts @@ -14,7 +14,10 @@ * Components that intercept wheel events should suppress the default for * these gestures even when they otherwise let the browser scroll natively. */ -export const isCanvasGestureWheel = (event: WheelEvent): boolean => - event.ctrlKey || - event.metaKey || - Math.abs(event.deltaX) > Math.abs(event.deltaY) +export function isCanvasGestureWheel(event: WheelEvent): boolean { + return ( + event.ctrlKey || + event.metaKey || + Math.abs(event.deltaX) > Math.abs(event.deltaY) + ) +} diff --git a/src/components/MenuHamburger.vue b/src/components/MenuHamburger.vue index 5b4103a495..04a6ac966e 100644 --- a/src/components/MenuHamburger.vue +++ b/src/components/MenuHamburger.vue @@ -29,7 +29,7 @@ import { showNativeSystemMenu } from '@/utils/envUtil' const workspaceState = useWorkspaceStore() const settingStore = useSettingStore() -const exitFocusMode = () => { +function exitFocusMode() { workspaceState.focusMode = false } diff --git a/src/components/TopMenuSection.test.ts b/src/components/TopMenuSection.test.ts index 45262b606a..6901d18b17 100644 --- a/src/components/TopMenuSection.test.ts +++ b/src/components/TopMenuSection.test.ts @@ -328,11 +328,11 @@ describe('TopMenuSection', () => { }) describe('inline progress summary', () => { - const configureSettings = ( + function configureSettings( pinia: ReturnType, qpoV2Enabled: boolean, showRunProgressBar = true - ) => { + ) { const settingStore = useSettingStore(pinia) vi.mocked(settingStore.get).mockImplementation((key) => { if (key === 'Comfy.Queue.QPOV2') return qpoV2Enabled @@ -413,10 +413,10 @@ describe('TopMenuSection', () => { }) describe(QueueNotificationBannerHost, () => { - const configureSettings = ( + function configureSettings( pinia: ReturnType, qpoV2Enabled: boolean - ) => { + ) { const settingStore = useSettingStore(pinia) vi.mocked(settingStore.get).mockImplementation((key) => { if (key === 'Comfy.Queue.QPOV2') return qpoV2Enabled diff --git a/src/components/TopMenuSection.vue b/src/components/TopMenuSection.vue index 6dc7bdf9d5..515838a7a5 100644 --- a/src/components/TopMenuSection.vue +++ b/src/components/TopMenuSection.vue @@ -327,7 +327,7 @@ onBeforeUnmount(() => { legacyContentCheckRafId = null }) -const openCustomNodeManager = async () => { +async function openCustomNodeManager() { try { await managerState.openManager({ initialTab: ManagerTab.All, diff --git a/src/components/actionbar/BatchCountEdit.vue b/src/components/actionbar/BatchCountEdit.vue index 318b9caf68..897649b383 100644 --- a/src/components/actionbar/BatchCountEdit.vue +++ b/src/components/actionbar/BatchCountEdit.vue @@ -92,38 +92,39 @@ watch(batchCount, (nextBatchCount) => { } }) -const clampBatchCount = (nextBatchCount: number): number => - Math.min(Math.max(nextBatchCount, minQueueCount), maxQueueCount.value) +function clampBatchCount(nextBatchCount: number): number { + return Math.min(Math.max(nextBatchCount, minQueueCount), maxQueueCount.value) +} -const setBatchCount = (nextBatchCount: number) => { +function setBatchCount(nextBatchCount: number) { batchCount.value = clampBatchCount(nextBatchCount) batchCountInput.value = String(batchCount.value) } -const incrementBatchCount = () => { +function incrementBatchCount() { setBatchCount(batchCount.value * 2) } -const decrementBatchCount = () => { +function decrementBatchCount() { setBatchCount(Math.floor(batchCount.value / 2)) } -const onInputFocus = () => { +function onInputFocus() { isEditing.value = true } -const onInput = (event: Event) => { +function onInput(event: Event) { const input = event.target as HTMLInputElement batchCountInput.value = input.value.replace(/[^0-9]/g, '') } -const onInputBlur = () => { +function onInputBlur() { isEditing.value = false const parsedInput = Number.parseInt(batchCountInput.value, 10) setBatchCount(Number.isNaN(parsedInput) ? minQueueCount : parsedInput) } -const onInputEnter = () => { +function onInputEnter() { batchCountInputRef.value?.blur() } diff --git a/src/components/actionbar/ComfyActionbar.test.ts b/src/components/actionbar/ComfyActionbar.test.ts index 6593f92277..3902f70426 100644 --- a/src/components/actionbar/ComfyActionbar.test.ts +++ b/src/components/actionbar/ComfyActionbar.test.ts @@ -7,10 +7,10 @@ import ComfyActionbar from '@/components/actionbar/ComfyActionbar.vue' import { i18n } from '@/i18n' import { useSettingStore } from '@/platform/settings/settingStore' -const configureSettings = ( +function configureSettings( pinia: ReturnType, showRunProgressBar: boolean -) => { +) { const settingStore = useSettingStore(pinia) vi.mocked(settingStore.get).mockImplementation((key) => { if (key === 'Comfy.UseNewMenu') return 'Top' @@ -20,7 +20,7 @@ const configureSettings = ( }) } -const renderActionbar = (showRunProgressBar: boolean) => { +function renderActionbar(showRunProgressBar: boolean) { const topMenuContainer = document.createElement('div') document.body.appendChild(topMenuContainer) diff --git a/src/components/actionbar/ComfyActionbar.vue b/src/components/actionbar/ComfyActionbar.vue index 29835a3670..030f46f5d6 100644 --- a/src/components/actionbar/ComfyActionbar.vue +++ b/src/components/actionbar/ComfyActionbar.vue @@ -170,7 +170,7 @@ watchDebounced( ) // Set initial position to bottom center -const setInitialPosition = () => { +function setInitialPosition() { const panel = panelElement.value if (panel) { const screenWidth = window.innerWidth @@ -232,7 +232,7 @@ const lastDragState = ref({ windowWidth: window.innerWidth, windowHeight: window.innerHeight }) -const captureLastDragState = () => { +function captureLastDragState() { lastDragState.value = { x: x.value, y: y.value, @@ -251,7 +251,7 @@ watch( { immediate: true } ) -const adjustMenuPosition = () => { +function adjustMenuPosition() { const panel = panelElement.value if (panel) { const screenWidth = window.innerWidth @@ -312,13 +312,13 @@ useEventListener(window, 'resize', adjustMenuPosition) const isMouseOverDropZone = ref(false) // Mouse event handlers for self-contained drop zone -const onMouseEnterDropZone = () => { +function onMouseEnterDropZone() { if (isDragging.value) { isMouseOverDropZone.value = true } } -const onMouseLeaveDropZone = () => { +function onMouseLeaveDropZone() { if (isDragging.value) { isMouseOverDropZone.value = false } @@ -396,21 +396,21 @@ const queueContextMenuItems = computed(() => [ } ]) -const cancelCurrentJob = async () => { +async function cancelCurrentJob() { if (isExecutionIdle.value) return await commandStore.execute('Comfy.Interrupt') } -const toggleQueueOverlay = () => { +function toggleQueueOverlay() { if (isQueuePanelV2Enabled.value) { sidebarTabStore.toggleSidebarTab('job-history') return } commandStore.execute('Comfy.Queue.ToggleOverlay') } -const showQueueContextMenu = (event: MouseEvent) => { +function showQueueContextMenu(event: MouseEvent) { queueContextMenu.value?.show(event) } -const handleClearQueue = async () => { +async function handleClearQueue() { const pendingJobIds = queueStore.pendingTasks .map((task) => task.jobId) .filter((id): id is string => typeof id === 'string' && id.length > 0) diff --git a/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue b/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue index d3a79317a0..313f4b6ef2 100644 --- a/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue +++ b/src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue @@ -220,7 +220,7 @@ const queueButtonTooltip = computed(() => { }) const commandStore = useCommandStore() -const queuePrompt = async (e: Event) => { +async function queuePrompt(e: Event) { if (isStopInstantAction.value) { queueMode.value = 'instant-idle' return diff --git a/src/components/bottomPanel/BottomPanel.vue b/src/components/bottomPanel/BottomPanel.vue index 37567ab7e5..0d679f1566 100644 --- a/src/components/bottomPanel/BottomPanel.vue +++ b/src/components/bottomPanel/BottomPanel.vue @@ -103,20 +103,20 @@ const isShortcutsTabActive = computed(() => { ) }) -const shouldCapitalizeTab = (tabId: string): boolean => { +function shouldCapitalizeTab(tabId: string): boolean { return tabId !== 'shortcuts-essentials' && tabId !== 'shortcuts-view-controls' } -const getTabDisplayTitle = (tab: BottomPanelExtension): string => { +function getTabDisplayTitle(tab: BottomPanelExtension): string { const title = tab.titleKey ? t(tab.titleKey) : tab.title || '' return shouldCapitalizeTab(tab.id) ? title.toUpperCase() : title } -const openKeybindingSettings = async () => { +async function openKeybindingSettings() { settingsDialog.show('keybinding') } -const closeBottomPanel = () => { +function closeBottomPanel() { bottomPanelStore.activePanel = null } diff --git a/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue b/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue index b9a9ff6894..47f419d19d 100644 --- a/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue +++ b/src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue @@ -71,7 +71,7 @@ const filteredSubcategories = computed(() => { return result }) -const getSubcategoryTitle = (subcategory: string): string => { +function getSubcategoryTitle(subcategory: string): string { const titleMap: Record = { workflow: t('shortcuts.subcategories.workflow'), node: t('shortcuts.subcategories.node'), @@ -83,7 +83,7 @@ const getSubcategoryTitle = (subcategory: string): string => { return titleMap[subcategory] || subcategory } -const formatKey = (key: string): string => { +function formatKey(key: string): string { const keyMap: Record = { Control: 'Ctrl', Meta: 'Cmd', diff --git a/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue b/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue index 982a68f063..fed98e5137 100644 --- a/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue +++ b/src/components/bottomPanel/tabs/terminal/BaseTerminal.vue @@ -69,7 +69,7 @@ const tooltipText = computed(() => { : t('serverStart.copyAllTooltip') }) -const handleCopy = async () => { +async function handleCopy() { const existingSelection = terminal.getSelection() const shouldSelectAll = !existingSelection if (shouldSelectAll) terminal.selectAll() @@ -87,7 +87,7 @@ const handleCopy = async () => { } } -const showContextMenu = (event: MouseEvent) => { +function showContextMenu(event: MouseEvent) { event.preventDefault() electronAPI()?.showContextMenu({ type: 'text' }) } diff --git a/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue b/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue index 1983a4c4c9..b78d7a5ba1 100644 --- a/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue +++ b/src/components/bottomPanel/tabs/terminal/CommandTerminal.vue @@ -12,10 +12,10 @@ import { electronAPI } from '@/utils/envUtil' import BaseTerminal from './BaseTerminal.vue' -const terminalCreated = ( +function terminalCreated( { terminal, useAutoSize }: ReturnType, root: Ref -) => { +) { const terminalApi = electronAPI().Terminal let offData: IDisposable diff --git a/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts b/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts index ba4707ce14..0c49cd0577 100644 --- a/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts +++ b/src/components/bottomPanel/tabs/terminal/LogsTerminal.test.ts @@ -68,8 +68,8 @@ const i18n = createI18n({ } }) -const renderLogsTerminal = () => - render(LogsTerminal, { +function renderLogsTerminal() { + return render(LogsTerminal, { global: { plugins: [ createTestingPinia({ @@ -81,6 +81,7 @@ const renderLogsTerminal = () => ] } }) +} // Silence the production console.error calls in error-path tests. Vitest // isolates this file's module graph so the spy does not affect other files. @@ -88,7 +89,7 @@ vi.spyOn(console, 'error').mockImplementation(() => {}) // Resolve a getRawLogs call manually to drive deterministic timing in tests // that need to observe behavior mid-fetch. -const deferredRawLogs = () => { +function deferredRawLogs() { let resolve!: (value: { entries: { m: string }[] }) => void let reject!: (err: unknown) => void const promise = new Promise<{ entries: { m: string }[] }>((res, rej) => { diff --git a/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue b/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue index 4360888c43..48da3264e4 100644 --- a/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue +++ b/src/components/bottomPanel/tabs/terminal/LogsTerminal.vue @@ -33,10 +33,10 @@ import BaseTerminal from './BaseTerminal.vue' const terminal = shallowRef() const { errorMessage, loading } = useLogsTerminal(terminal) -const terminalCreated = ( +function terminalCreated( { terminal: instance, useAutoSize }: ReturnType, root: Ref -) => { +) { // Auto-size terminal to fill container width. // minCols: 80 ensures minimum width for colab environments. // See https://github.com/comfyanonymous/ComfyUI/issues/6396 diff --git a/src/components/breadcrumb/SubgraphBreadcrumb.vue b/src/components/breadcrumb/SubgraphBreadcrumb.vue index 742ef4e5c6..0dfa4b99e7 100644 --- a/src/components/breadcrumb/SubgraphBreadcrumb.vue +++ b/src/components/breadcrumb/SubgraphBreadcrumb.vue @@ -125,7 +125,7 @@ const items = computed(() => { const activeItemKey = computed(() => items.value.at(-1)?.key) -const handleBackClick = () => { +function handleBackClick() { void useCommandStore().execute('Comfy.Graph.ExitSubgraph') } diff --git a/src/components/breadcrumb/SubgraphBreadcrumbItem.vue b/src/components/breadcrumb/SubgraphBreadcrumbItem.vue index b1e54ae793..7133c74aea 100644 --- a/src/components/breadcrumb/SubgraphBreadcrumbItem.vue +++ b/src/components/breadcrumb/SubgraphBreadcrumbItem.vue @@ -104,10 +104,7 @@ const itemLabel = ref() const itemInputRef = ref<{ $el?: HTMLInputElement }>() const wrapperRef = ref() -const rename = async ( - newName: string | null | undefined, - initialName: string -) => { +async function rename(newName: string | null | undefined, initialName: string) { if (newName && newName !== initialName) { // Synchronize the node titles with the new name item.updateTitle?.(newName) @@ -144,7 +141,7 @@ const tooltipText = computed(() => { return item.label }) -const startRename = async () => { +async function startRename() { // Check if element is hidden (collapsed breadcrumb) // When collapsed, root item is hidden via CSS display:none, so use rename command if (isRoot && wrapperRef.value?.offsetParent === null) { @@ -167,7 +164,7 @@ const startRename = async () => { const { menuItems } = useWorkflowActionsMenu(startRename, { isRoot }) -const handleClick = (event: MouseEvent) => { +function handleClick(event: MouseEvent) { if (isEditing.value) { return } @@ -186,7 +183,7 @@ const handleClick = (event: MouseEvent) => { } } -const inputBlur = async (doRename: boolean) => { +async function inputBlur(doRename: boolean) { if (doRename) { await rename(itemLabel.value, item.label as string) } diff --git a/src/components/builder/AppModeWidgetList.vue b/src/components/builder/AppModeWidgetList.vue index 8ab4e9bc4f..e2ea7da455 100644 --- a/src/components/builder/AppModeWidgetList.vue +++ b/src/components/builder/AppModeWidgetList.vue @@ -122,7 +122,7 @@ function getDropIndicator(node: LGraphNode) { ? parseImageWidgetValue(stringValue) : { filename: '', subfolder: '', type: 'input' } - const buildImageUrl = () => { + function buildImageUrl() { if (!filename) return undefined const params = new URLSearchParams({ filename, subfolder, type }) appendCloudResParam(params, filename) @@ -154,7 +154,7 @@ function nodeToNodeData(node: LGraphNode) { } async function handleDragDrop() { - const onDragDrop = async (e: DragEvent) => { + async function onDragDrop(e: DragEvent) { for (const { nodeData } of mappedSelections.value) if (nodeData?.onDragOver?.(e) && (await nodeData.onDragDrop?.(e))) return true diff --git a/src/components/builder/useAppModeWidgetResizing.ts b/src/components/builder/useAppModeWidgetResizing.ts index f95ee958fe..d0ea56a2e3 100644 --- a/src/components/builder/useAppModeWidgetResizing.ts +++ b/src/components/builder/useAppModeWidgetResizing.ts @@ -34,15 +34,16 @@ export function useAppModeWidgetResizing( return const resizable = target.closest(RESIZABLE_SELECTOR) if (!resizable || !wrapper.contains(resizable)) return + const resizableEl: HTMLElement = resizable clearPendingHandler() - const startHeight = resizable.offsetHeight - const handler = () => { + const startHeight = resizableEl.offsetHeight + function handler() { window.removeEventListener('pointerup', handler) window.removeEventListener('pointercancel', handler) pendingHandler = null - const height = resizable.offsetHeight + const height = resizableEl.offsetHeight if (height === startHeight) return onResize(nodeId, widgetName, { height }) } diff --git a/src/components/card/Card.stories.ts b/src/components/card/Card.stories.ts index 6c2ec30e87..142651f38f 100644 --- a/src/components/card/Card.stories.ts +++ b/src/components/card/Card.stories.ts @@ -166,29 +166,30 @@ const meta: Meta = { export default meta type Story = StoryObj -const createCardTemplate = (args: CardStoryArgs) => ({ - components: { - CardContainer, - CardTop, - CardBottom, - CardTitle, - CardDescription, - Button, - Tag - }, - setup() { - const favorited = ref(false) - const toggleFavorite = () => { - favorited.value = !favorited.value - } +function createCardTemplate(args: CardStoryArgs) { + return { + components: { + CardContainer, + CardTop, + CardBottom, + CardTitle, + CardDescription, + Button, + Tag + }, + setup() { + const favorited = ref(false) + function toggleFavorite() { + favorited.value = !favorited.value + } - return { - args, - favorited, - toggleFavorite - } - }, - template: ` + return { + args, + favorited, + toggleFavorite + } + }, + template: `
({
` -}) + } +} export const Default: Story = { render: (args: CardStoryArgs) => createCardTemplate(args), diff --git a/src/components/common/BackgroundImageUpload.vue b/src/components/common/BackgroundImageUpload.vue index 72f5af1f25..26151d37ad 100644 --- a/src/components/common/BackgroundImageUpload.vue +++ b/src/components/common/BackgroundImageUpload.vue @@ -49,11 +49,11 @@ const modelValue = defineModel() const fileInput = ref(null) const isUploading = ref(false) -const triggerFileInput = () => { +function triggerFileInput() { fileInput.value?.click() } -const uploadFile = async (file: File): Promise => { +async function uploadFile(file: File): Promise { const body = new FormData() body.append('image', file) body.append('subfolder', 'backgrounds') @@ -74,7 +74,7 @@ const uploadFile = async (file: File): Promise => { return data.subfolder ? `${data.subfolder}/${data.name}` : data.name } -const handleFileUpload = async (event: Event) => { +async function handleFileUpload(event: Event) { const target = event.target as HTMLInputElement if (target.files && target.files[0]) { const file = target.files[0] @@ -100,7 +100,7 @@ const handleFileUpload = async (event: Event) => { } } -const clearImage = () => { +function clearImage() { modelValue.value = '' if (fileInput.value) { fileInput.value.value = '' diff --git a/src/components/common/CustomizationDialog.vue b/src/components/common/CustomizationDialog.vue index 12eac61a1d..eb508cc35e 100644 --- a/src/components/common/CustomizationDialog.vue +++ b/src/components/common/CustomizationDialog.vue @@ -136,13 +136,13 @@ const defaultIcon = iconOptions.find( const selectedIcon = ref(defaultIcon ?? iconOptions[0]) const finalColor = ref(initialColor || nodeBookmarkStore.defaultBookmarkColor) -const resetCustomization = () => { +function resetCustomization() { selectedIcon.value = iconOptions.find((option) => option.value === initialIcon) ?? iconOptions[0] finalColor.value = initialColor || nodeBookmarkStore.defaultBookmarkColor } -const confirmCustomization = () => { +function confirmCustomization() { emit('confirm', selectedIcon.value.value, finalColor.value) visible.value = false } diff --git a/src/components/common/DeviceInfo.vue b/src/components/common/DeviceInfo.vue index ab141cfbc0..0a9cda83bb 100644 --- a/src/components/common/DeviceInfo.vue +++ b/src/components/common/DeviceInfo.vue @@ -28,7 +28,7 @@ const deviceColumns: { field: keyof DeviceStats; header: string }[] = [ { field: 'torch_vram_free', header: 'Torch VRAM Free' } ] -const formatValue = (value: string | number, field: string) => { +function formatValue(value: string | number, field: string) { if ( ['vram_total', 'vram_free', 'torch_vram_total', 'torch_vram_free'].includes( field diff --git a/src/components/common/ExtensionSlot.vue b/src/components/common/ExtensionSlot.vue index 6819e494e7..6a01fa051e 100644 --- a/src/components/common/ExtensionSlot.vue +++ b/src/components/common/ExtensionSlot.vue @@ -23,7 +23,7 @@ const props = defineProps<{ extension: VueExtension | CustomExtension }>() -const mountCustomExtension = (extension: CustomExtension, el: HTMLElement) => { +function mountCustomExtension(extension: CustomExtension, el: HTMLElement) { extension.render(el) } diff --git a/src/components/common/FormImageUpload.vue b/src/components/common/FormImageUpload.vue index 479b84e627..4a582c606c 100644 --- a/src/components/common/FormImageUpload.vue +++ b/src/components/common/FormImageUpload.vue @@ -55,11 +55,11 @@ const emit = defineEmits<{ const fileInput = ref(null) -const triggerFileInput = () => { +function triggerFileInput() { fileInput.value?.click() } -const handleFileUpload = (event: Event) => { +function handleFileUpload(event: Event) { const target = event.target as HTMLInputElement if (target.files && target.files[0]) { const file = target.files[0] @@ -71,7 +71,7 @@ const handleFileUpload = (event: Event) => { } } -const clearImage = () => { +function clearImage() { emit('update:modelValue', '') if (fileInput.value) { fileInput.value.value = '' diff --git a/src/components/common/InputKnob.vue b/src/components/common/InputKnob.vue index 1d67449dab..cbf7475cb6 100644 --- a/src/components/common/InputKnob.vue +++ b/src/components/common/InputKnob.vue @@ -53,7 +53,7 @@ watch( } ) -const updateValue = (newValue: number | null) => { +function updateValue(newValue: number | null) { if (newValue === null) { // If the input is cleared, reset to the minimum value or 0 newValue = Number(props.min) || 0 @@ -74,7 +74,7 @@ const updateValue = (newValue: number | null) => { emit('update:modelValue', newValue) } -const displayValue = (value: number): string => { +function displayValue(value: number): string { updateValue(value) const stepString = (props.step ?? 1).toString() const resolution = stepString.includes('.') diff --git a/src/components/common/InputSlider.vue b/src/components/common/InputSlider.vue index 8d04f1fc9c..5d39f83bda 100644 --- a/src/components/common/InputSlider.vue +++ b/src/components/common/InputSlider.vue @@ -51,7 +51,7 @@ watch( } ) -const updateValue = (newValue: number | null) => { +function updateValue(newValue: number | null) { if (newValue === null) { // If the input is cleared, reset to the minimum value or 0 newValue = Number(props.min) || 0 diff --git a/src/components/common/LazyImage.vue b/src/components/common/LazyImage.vue index 6a5ac08290..6b6363b36a 100644 --- a/src/components/common/LazyImage.vue +++ b/src/components/common/LazyImage.vue @@ -115,12 +115,12 @@ watch( { immediate: true } ) -const onImageLoad = () => { +function onImageLoad() { isImageLoaded.value = true hasError.value = false } -const onImageError = () => { +function onImageError() { hasError.value = true isImageLoaded.value = false } diff --git a/src/components/common/TreeExplorer.vue b/src/components/common/TreeExplorer.vue index b7434be697..767e929423 100644 --- a/src/components/common/TreeExplorer.vue +++ b/src/components/common/TreeExplorer.vue @@ -95,7 +95,7 @@ const renderedRoot = computed>(() => { ? combineTrees(renderedRoot, newFolderNode.value) : renderedRoot }) -const getTreeNodeIcon = (node: TreeExplorerNode) => { +function getTreeNodeIcon(node: TreeExplorerNode) { if (node.getIcon) { const icon = node.getIcon() if (icon) { @@ -111,9 +111,7 @@ const getTreeNodeIcon = (node: TreeExplorerNode) => { const isExpanded = expandedKeys.value?.[node.key] ?? false return isExpanded ? 'pi pi-folder-open' : 'pi pi-folder' } -const fillNodeInfo = ( - node: TreeExplorerNode -): RenderedTreeExplorerNode => { +function fillNodeInfo(node: TreeExplorerNode): RenderedTreeExplorerNode { const children = node.children?.map(fillNodeInfo) ?? [] const totalLeaves = node.leaf ? 1 @@ -128,10 +126,10 @@ const fillNodeInfo = ( isEditingLabel: node.key === renameEditingNode.value?.key } } -const onNodeContentClick = async ( +async function onNodeContentClick( e: MouseEvent, node: RenderedTreeExplorerNode -) => { +) { if (!storeSelectionKeys) { selectionKeys.value = {} } @@ -152,10 +150,10 @@ const extraMenuItems = computed(() => { }) const renameEditingNode = shallowRef | null>(null) const errorHandling = useErrorHandling() -const handleNodeLabelEdit = async ( +async function handleNodeLabelEdit( n: RenderedTreeExplorerNode, newName: string -) => { +) { const node = n as RenderedTreeExplorerNode await errorHandling.wrapWithErrorHandlingAsync( async () => { @@ -174,10 +172,10 @@ const handleNodeLabelEdit = async ( provide(InjectKeyHandleEditLabelFunction, handleNodeLabelEdit) const { t } = useI18n() -const renameCommand = (node: RenderedTreeExplorerNode) => { +function renameCommand(node: RenderedTreeExplorerNode) { renameEditingNode.value = node } -const deleteCommand = async (node: RenderedTreeExplorerNode) => { +async function deleteCommand(node: RenderedTreeExplorerNode) { await node.handleDelete?.() emit('nodeDelete', node) } @@ -217,10 +215,7 @@ const menuItems = computed(() => { })) }) -const handleContextMenu = ( - e: MouseEvent, - node: RenderedTreeExplorerNode -) => { +function handleContextMenu(e: MouseEvent, node: RenderedTreeExplorerNode) { menuTargetNode.value = node emit('contextMenu', node, e) if (menuItems.value.filter((item) => item.visible).length > 0) { @@ -228,10 +223,10 @@ const handleContextMenu = ( } } -const wrapCommandWithErrorHandler = ( +function wrapCommandWithErrorHandler( command: (event: MenuItemCommandEvent) => void, { isAsync = false }: { isAsync: boolean } -) => { +) { const node = menuTargetNode.value return isAsync ? errorHandling.wrapWithErrorHandlingAsync( diff --git a/src/components/common/TreeExplorerTreeNode.vue b/src/components/common/TreeExplorerTreeNode.vue index 1982f7d711..22fe115856 100644 --- a/src/components/common/TreeExplorerTreeNode.vue +++ b/src/components/common/TreeExplorerTreeNode.vue @@ -79,15 +79,16 @@ const showNodeBadgeText = computed(() => nodeBadgeText.value !== '') const isEditing = computed(() => props.node.isEditingLabel ?? false) const handleEditLabel = inject(InjectKeyHandleEditLabelFunction) -const handleRename = (newName: string) => { +function handleRename(newName: string) { handleEditLabel?.(props.node as RenderedTreeExplorerNode, newName) } const container = ref(null) const canDrop = ref(false) -const treeNodeElementGetter = () => - container.value?.closest('.p-tree-node-content') as HTMLElement +function treeNodeElementGetter() { + return container.value?.closest('.p-tree-node-content') as HTMLElement +} if (props.node.draggable) { usePragmaticDraggable(treeNodeElementGetter, { diff --git a/src/components/common/TreeExplorerV2Node.vue b/src/components/common/TreeExplorerV2Node.vue index 1104d857fc..0abbbfcc00 100644 --- a/src/components/common/TreeExplorerV2Node.vue +++ b/src/components/common/TreeExplorerV2Node.vue @@ -159,7 +159,7 @@ function deleteBlueprint() { void subgraphStore.deleteBlueprint(nodeDef.value.name) } } -const editBlueprint = async () => { +async function editBlueprint() { if (!nodeDef.value) throw new Error( 'Failed to edit subgraph blueprint lacking backing node data' diff --git a/src/components/common/UrlInput.vue b/src/components/common/UrlInput.vue index df40ba0c40..cc6322de82 100644 --- a/src/components/common/UrlInput.vue +++ b/src/components/common/UrlInput.vue @@ -44,8 +44,9 @@ const emit = defineEmits<{ const validationState = ref(ValidationState.IDLE) -const cleanInput = (value: string): string => - value ? value.replace(/\s+/g, '') : '' +function cleanInput(value: string): string { + return value ? value.replace(/\s+/g, '') : '' +} // Add internal value state const internalValue = ref(cleanInput(props.modelValue)) @@ -68,14 +69,14 @@ onMounted(async () => { await validateUrl(props.modelValue) }) -const handleInput = (value: string | undefined) => { +function handleInput(value: string | undefined) { // Update internal value without emitting internalValue.value = cleanInput(value ?? '') // Reset validation state when user types validationState.value = ValidationState.IDLE } -const handleBlur = async () => { +async function handleBlur() { const input = cleanInput(internalValue.value) let normalizedUrl = input @@ -91,7 +92,7 @@ const handleBlur = async () => { } // Default validation implementation -const defaultValidateUrl = async (url: string): Promise => { +async function defaultValidateUrl(url: string): Promise { if (!isValidUrl(url)) return false try { return await checkUrlReachable(url) @@ -100,7 +101,7 @@ const defaultValidateUrl = async (url: string): Promise => { } } -const validateUrl = async (value: string) => { +async function validateUrl(value: string) { if (validationState.value === ValidationState.LOADING) return const url = cleanInput(value) diff --git a/src/components/common/UserAvatar.vue b/src/components/common/UserAvatar.vue index 48a7add134..0e8bd298da 100644 --- a/src/components/common/UserAvatar.vue +++ b/src/components/common/UserAvatar.vue @@ -25,7 +25,7 @@ const { photoUrl, ariaLabel } = defineProps<{ }>() const imageError = ref(false) -const handleImageError = () => { +function handleImageError() { imageError.value = true } const hasAvatar = computed(() => photoUrl && !imageError.value) diff --git a/src/components/common/UserCredit.test.ts b/src/components/common/UserCredit.test.ts index 352010dfb9..ed5a40190a 100644 --- a/src/components/common/UserCredit.test.ts +++ b/src/components/common/UserCredit.test.ts @@ -50,7 +50,7 @@ describe('UserCredit', () => { mockIsFetchingBalance.value = false }) - const renderComponent = (props = {}) => { + function renderComponent(props = {}) { const i18n = createI18n({ legacy: false, locale: 'en', diff --git a/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue b/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue index 63995bcb6e..ae92a8d81f 100644 --- a/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue +++ b/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue @@ -452,7 +452,7 @@ onMounted(() => { }) // Wrap onClose to track session end -const onClose = () => { +function onClose() { if (isCloud) { const timeSpentSeconds = Math.floor( (Date.now() - sessionStartTime.value) / 1000 @@ -479,23 +479,26 @@ const { getTemplateDescription } = useTemplateWorkflows() -const getEffectiveSourceModule = (template: TemplateInfo) => - template.sourceModule || 'default' +function getEffectiveSourceModule(template: TemplateInfo) { + return template.sourceModule || 'default' +} -const isAppTemplate = (template: TemplateInfo) => template.name.endsWith('.app') +function isAppTemplate(template: TemplateInfo) { + return template.name.endsWith('.app') +} -const getBaseThumbnailSrc = (template: TemplateInfo) => { +function getBaseThumbnailSrc(template: TemplateInfo) { const sm = getEffectiveSourceModule(template) return getTemplateThumbnailUrl(template, sm, sm === 'default' ? '1' : '') } -const getOverlayThumbnailSrc = (template: TemplateInfo) => { +function getOverlayThumbnailSrc(template: TemplateInfo) { const sm = getEffectiveSourceModule(template) return getTemplateThumbnailUrl(template, sm, sm === 'default' ? '2' : '') } // Open tutorial in new tab -const openTutorial = (template: TemplateInfo) => { +function openTutorial(template: TemplateInfo) { if (template.tutorialUrl) { window.open(template.tutorialUrl, '_blank') } @@ -579,7 +582,7 @@ const { */ const searchInput = ref(searchQuery.value) -const applySearchQuery = async (query: string) => { +async function applySearchQuery(query: string) { searchQuery.value = query } @@ -596,7 +599,7 @@ watch(searchQuery, (value) => { * create deterministic, predictable behavior. * @param source The origin of the change ('nav' or 'sort'). */ -const coordinateNavAndSort = (source: 'nav' | 'sort') => { +function coordinateNavAndSort(source: 'nav' | 'sort') { const isPopularNav = selectedNavItem.value === 'popular' const isPopularSort = sortBy.value === 'popular' @@ -810,7 +813,7 @@ watch( ) // Methods -const onLoadWorkflow = async (template: TemplateInfo) => { +async function onLoadWorkflow(template: TemplateInfo) { loadingTemplate.value = template.name try { await loadWorkflowTemplate( diff --git a/src/components/dialog/UnloadWindowConfirmDialog.vue b/src/components/dialog/UnloadWindowConfirmDialog.vue index 32ccedaa9a..9539485fcd 100644 --- a/src/components/dialog/UnloadWindowConfirmDialog.vue +++ b/src/components/dialog/UnloadWindowConfirmDialog.vue @@ -18,7 +18,7 @@ import { useWorkflowStore } from '@/platform/workflow/management/stores/workflow const settingStore = useSettingStore() const workflowStore = useWorkflowStore() -const handleBeforeUnload = (event: BeforeUnloadEvent) => { +function handleBeforeUnload(event: BeforeUnloadEvent) { if ( settingStore.get('Comfy.Window.UnloadConfirmation') && workflowStore.modifiedWorkflows.length > 0 diff --git a/src/components/dialog/content/ApiNodesSignInContent.vue b/src/components/dialog/content/ApiNodesSignInContent.vue index 20ccb38fb6..57bd78b8a9 100644 --- a/src/components/dialog/content/ApiNodesSignInContent.vue +++ b/src/components/dialog/content/ApiNodesSignInContent.vue @@ -45,7 +45,7 @@ const { apiNodeNames, onLogin, onCancel } = defineProps<{ onCancel?: () => void }>() -const handleLearnMoreClick = () => { +function handleLearnMoreClick() { window.open( buildDocsUrl('/tutorials/api-nodes/faq', { includeLocale: true }), '_blank' diff --git a/src/components/dialog/content/ConfirmationDialogContent.vue b/src/components/dialog/content/ConfirmationDialogContent.vue index 683f0b9781..0a5fadd616 100644 --- a/src/components/dialog/content/ConfirmationDialogContent.vue +++ b/src/components/dialog/content/ConfirmationDialogContent.vue @@ -61,14 +61,18 @@ {{ $t('g.cancel') }} - - @@ -94,7 +98,7 @@