refactor: load extensions dynamically according to the configuration file

This commit is contained in:
Rizumu Ayaka
2025-11-13 17:12:07 +08:00
committed by Alexander Brown
parent ddbd26c062
commit bb2c99749a
96 changed files with 240 additions and 114 deletions

View File

@@ -88,7 +88,7 @@ import type {
LightConfig,
ModelConfig,
SceneConfig
} from '@/extensions/core/load3d/interfaces'
} from '@/extensions/core/extensions/load3d/interfaces'
const sceneConfig = defineModel<SceneConfig>('sceneConfig')
const modelConfig = defineModel<ModelConfig>('modelConfig')

View File

@@ -22,7 +22,7 @@ import Button from 'primevue/button'
import { computed } from 'vue'
import PopupSlider from '@/components/load3d/controls/PopupSlider.vue'
import type { CameraType } from '@/extensions/core/load3d/interfaces'
import type { CameraType } from '@/extensions/core/extensions/load3d/interfaces'
const cameraType = defineModel<CameraType>('cameraType')
const fov = defineModel<number>('fov')

View File

@@ -35,7 +35,7 @@ import Button from 'primevue/button'
import Slider from 'primevue/slider'
import { computed, onMounted, onUnmounted, ref } from 'vue'
import type { MaterialMode } from '@/extensions/core/load3d/interfaces'
import type { MaterialMode } from '@/extensions/core/extensions/load3d/interfaces'
import { useSettingStore } from '@/platform/settings/settingStore'
const lightIntensity = defineModel<number>('lightIntensity')

View File

@@ -68,7 +68,7 @@ import { computed, onMounted, onUnmounted, ref } from 'vue'
import type {
MaterialMode,
UpDirection
} from '@/extensions/core/load3d/interfaces'
} from '@/extensions/core/extensions/load3d/interfaces'
import { t } from '@/i18n'
const materialMode = defineModel<MaterialMode>('materialMode')

View File

@@ -95,7 +95,7 @@ import Button from 'primevue/button'
import { computed, ref } from 'vue'
import PopupSlider from '@/components/load3d/controls/PopupSlider.vue'
import type { BackgroundRenderModeType } from '@/extensions/core/load3d/interfaces'
import type { BackgroundRenderModeType } from '@/extensions/core/extensions/load3d/interfaces'
const emit = defineEmits<{
(e: 'updateBackgroundImage', file: File | null): void

View File

@@ -31,7 +31,7 @@ import Select from 'primevue/select'
import Slider from 'primevue/slider'
import { computed } from 'vue'
import type { CameraType } from '@/extensions/core/load3d/interfaces'
import type { CameraType } from '@/extensions/core/extensions/load3d/interfaces'
import { t } from '@/i18n'
const cameras = [

View File

@@ -29,7 +29,7 @@ import { computed } from 'vue'
import type {
MaterialMode,
UpDirection
} from '@/extensions/core/load3d/interfaces'
} from '@/extensions/core/extensions/load3d/interfaces'
import { t } from '@/i18n'
const upDirection = defineModel<UpDirection>('upDirection')

View File

@@ -2,8 +2,8 @@ import { toRef } from '@vueuse/core'
import type { MaybeRef } from '@vueuse/core'
import { nextTick, ref, toRaw, watch } from 'vue'
import Load3d from '@/extensions/core/load3d/Load3d'
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
import Load3d from '@/extensions/core/extensions/load3d/Load3d'
import Load3dUtils from '@/extensions/core/extensions/load3d/Load3dUtils'
import type {
AnimationItem,
CameraConfig,
@@ -13,7 +13,7 @@ import type {
ModelConfig,
SceneConfig,
UpDirection
} from '@/extensions/core/load3d/interfaces'
} from '@/extensions/core/extensions/load3d/interfaces'
import { t } from '@/i18n'
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
import { useToastStore } from '@/platform/updates/common/toastStore'

View File

@@ -1,7 +1,7 @@
import { computed, ref, toValue } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
import { SUPPORTED_EXTENSIONS } from '@/extensions/core/load3d/interfaces'
import { SUPPORTED_EXTENSIONS } from '@/extensions/core/extensions/load3d/interfaces'
import { t } from '@/i18n'
import { useToastStore } from '@/platform/updates/common/toastStore'

View File

@@ -1,13 +1,13 @@
import { ref, toRaw, watch } from 'vue'
import Load3d from '@/extensions/core/load3d/Load3d'
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
import Load3d from '@/extensions/core/extensions/load3d/Load3d'
import Load3dUtils from '@/extensions/core/extensions/load3d/Load3dUtils'
import type {
BackgroundRenderModeType,
CameraType,
MaterialMode,
UpDirection
} from '@/extensions/core/load3d/interfaces'
} from '@/extensions/core/extensions/load3d/interfaces'
import { t } from '@/i18n'
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
import { useToastStore } from '@/platform/updates/common/toastStore'

View File

@@ -1,6 +1,6 @@
import { app } from '../../scripts/app'
import { ComfyApp } from '../../scripts/app'
import { $el, ComfyDialog } from '../../scripts/ui'
import { app } from '@/scripts/app'
import { ComfyApp } from '@/scripts/app'
import { $el, ComfyDialog } from '@/scripts/ui'
export class ClipspaceDialog extends ComfyDialog {
static items: Array<

View File

@@ -0,0 +1,5 @@
import { defineComfyExtConfig } from '@/extensions/utils'
export default defineComfyExtConfig({
comfyCloud: true,
})

View File

@@ -0,0 +1,5 @@
import { defineComfyExtConfig } from '@/extensions/utils'
export default defineComfyExtConfig({
comfyCloud: true,
})

View File

@@ -0,0 +1,5 @@
import { defineComfyExtConfig } from '@/extensions/utils'
export default defineComfyExtConfig({
comfyCloud: true,
})

View File

@@ -0,0 +1,5 @@
import { defineComfyExtConfig } from '@/extensions/utils'
export default defineComfyExtConfig({
comfyCloud: true,
})

View File

@@ -0,0 +1,7 @@
import { defineComfyExtConfig } from '@/extensions/utils'
export default defineComfyExtConfig({
comfyCloud: {
subscriptionRequired: true,
},
})

View File

@@ -4,7 +4,7 @@ import {
isComboWidget
} from '@/lib/litegraph/src/litegraph'
import { app } from '../../scripts/app'
import { app } from '@/scripts/app'
// Adds filtering to combo context menus

View File

@@ -1,4 +1,4 @@
import { app } from '../../scripts/app'
import { app } from '@/scripts/app'
// Allows you to edit the attention weight by holding ctrl (or cmd) and using the up/down arrow keys

View File

@@ -25,10 +25,10 @@ import { ExecutableGroupNodeChildDTO } from '@/utils/executableGroupNodeChildDTO
import { GROUP } from '@/utils/executableGroupNodeDto'
import { deserialiseAndCreate, serialise } from '@/utils/vintageClipboard'
import { api } from '../../scripts/api'
import { app } from '../../scripts/app'
import { ManageGroupDialog } from './groupNodeManage'
import { mergeIfValid } from './widgetInputs'
import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
import { ManageGroupDialog } from '../groupNodeManage'
import { mergeIfValid } from '../widgetInputs'
type GroupNodeWorkflowData = {
external: ComfyLink[]

View File

@@ -6,11 +6,11 @@ import {
} from '@/lib/litegraph/src/litegraph'
import { useToastStore } from '@/platform/updates/common/toastStore'
import { type ComfyApp, app } from '../../scripts/app'
import { $el } from '../../scripts/ui'
import { ComfyDialog } from '../../scripts/ui/dialog'
import { DraggableList } from '../../scripts/ui/draggableList'
import { GroupNodeConfig, GroupNodeHandler } from './groupNode'
import { type ComfyApp, app } from '@/scripts/app'
import { $el } from '@/scripts/ui'
import { ComfyDialog } from '@/scripts/ui/dialog'
import { DraggableList } from '@/scripts/ui/draggableList'
import { GroupNodeConfig, GroupNodeHandler } from '../groupNode'
import './groupNodeManage.css'
const ORDER: symbol = Symbol()

View File

@@ -10,7 +10,7 @@ import {
import { useSettingStore } from '@/platform/settings/settingStore'
import type { ComfyExtension } from '@/types/comfy'
import { app } from '../../scripts/app'
import { app } from '@/scripts/app'
function setNodeMode(node: LGraphNode, mode: number) {
node.mode = mode

View File

@@ -4,7 +4,7 @@ import {
type AnimationItem,
type AnimationManagerInterface,
type EventManagerInterface
} from '@/extensions/core/load3d/interfaces'
} from './interfaces'
export class AnimationManager implements AnimationManagerInterface {
currentAnimation: THREE.AnimationMixer | null = null

View File

@@ -1,11 +1,11 @@
import Load3d from '@/extensions/core/load3d/Load3d'
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
import Load3d from './Load3d'
import Load3dUtils from './Load3dUtils'
import type {
CameraConfig,
LightConfig,
ModelConfig,
SceneConfig
} from '@/extensions/core/load3d/interfaces'
} from './interfaces'
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
import { useSettingStore } from '@/platform/settings/settingStore'
import { api } from '@/scripts/api'

View File

@@ -1,7 +1,7 @@
import { t } from '@/i18n'
import type { IContextMenuValue } from '@/lib/litegraph/src/interfaces'
import { useToastStore } from '@/platform/updates/common/toastStore'
import Load3d from '@/extensions/core/load3d/Load3d'
import Load3d from './Load3d'
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
const EXPORT_FORMATS = [

View File

@@ -3,9 +3,9 @@ import { nextTick } from 'vue'
import Load3D from '@/components/load3d/Load3D.vue'
import Load3DViewerContent from '@/components/load3d/Load3dViewerContent.vue'
import { nodeToLoad3dMap, useLoad3d } from '@/composables/useLoad3d'
import { createExportMenuItems } from '@/extensions/core/load3d/exportMenuHelper'
import Load3DConfiguration from '@/extensions/core/load3d/Load3DConfiguration'
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
import { createExportMenuItems } from './exportMenuHelper'
import Load3DConfiguration from './Load3DConfiguration'
import Load3dUtils from './Load3dUtils'
import { t } from '@/i18n'
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
import type { IContextMenuValue } from '@/lib/litegraph/src/interfaces'

View File

@@ -1,7 +1,7 @@
import { t } from '@/i18n'
import { api } from '../../../scripts/api'
import { ComfyApp } from '../../../scripts/app'
import { $el, ComfyDialog } from '../../../scripts/ui'
import { api } from '@/scripts/api'
import { ComfyApp } from '@/scripts/app'
import { $el, ComfyDialog } from '@/scripts/ui'
import { ClipspaceDialog } from '../clipspace'
import { imageLayerFilenamesByTimestamp } from './utils/maskEditorLayerFilenames'
import { CanvasHistory } from './CanvasHistory'

View File

@@ -1,13 +1,13 @@
import _ from 'es-toolkit/compat'
import { app } from '../../scripts/app'
import { ComfyApp } from '../../scripts/app'
import { ClipspaceDialog } from './clipspace'
import { MaskEditorDialog } from './maskeditor/MaskEditorDialog'
import { MaskEditorDialogOld } from './maskEditorOld'
import { app } from '@/scripts/app'
import { ComfyApp } from '@/scripts/app'
import { ClipspaceDialog } from '../clipspace'
import { MaskEditorDialog } from './MaskEditorDialog'
import { MaskEditorDialogOld } from '../../maskEditorOld'
// Import styles to inject into document
import './maskeditor/styles'
import './styles'
// Function to open the mask editor
function openMaskEditor(): void {

View File

@@ -7,10 +7,10 @@ import { useDialogService } from '@/services/dialogService'
import type { ComfyExtension } from '@/types/comfy'
import { deserialiseAndCreate } from '@/utils/vintageClipboard'
import { api } from '../../scripts/api'
import { app } from '../../scripts/app'
import { $el, ComfyDialog } from '../../scripts/ui'
import { GroupNodeConfig, GroupNodeHandler } from './groupNode'
import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
import { $el, ComfyDialog } from '@/scripts/ui'
import { GroupNodeConfig, GroupNodeHandler } from '../groupNode'
// Adds the ability to save and add multiple nodes as a template
// To save:

View File

@@ -1,8 +1,8 @@
import { LGraphCanvas, LiteGraph } from '@/lib/litegraph/src/litegraph'
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
import { app } from '../../scripts/app'
import { ComfyWidgets } from '../../scripts/widgets'
import { app } from '@/scripts/app'
import { ComfyWidgets } from '@/scripts/widgets'
// Node that add notes to your project

View File

@@ -6,8 +6,8 @@ import {
} from '@/lib/litegraph/src/litegraph'
import type { ISlotType } from '@/lib/litegraph/src/interfaces'
import { app } from '../../scripts/app'
import { getWidgetConfig, mergeIfValid, setWidgetConfig } from './widgetInputs'
import { app } from '@/scripts/app'
import { getWidgetConfig, mergeIfValid, setWidgetConfig } from '../widgetInputs'
// Node that allows you to redirect connections for cleaner graphs

View File

@@ -1,6 +1,6 @@
import { applyTextReplacements } from '@/utils/searchAndReplace'
import { app } from '../../scripts/app'
import { app } from '@/scripts/app'
const saveNodeTypes = new Set([
'SaveImage',

View File

@@ -2,8 +2,8 @@ import { nextTick } from 'vue'
import Load3D from '@/components/load3d/Load3D.vue'
import { useLoad3d } from '@/composables/useLoad3d'
import { createExportMenuItems } from '@/extensions/core/load3d/exportMenuHelper'
import Load3DConfiguration from '@/extensions/core/load3d/Load3DConfiguration'
import { createExportMenuItems } from '../load3d/exportMenuHelper'
import Load3DConfiguration from '../load3d/Load3DConfiguration'
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
import type { IContextMenuValue } from '@/lib/litegraph/src/interfaces'
import { type CustomInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'

View File

@@ -1,6 +1,6 @@
import { LGraphCanvas, LiteGraph } from '@/lib/litegraph/src/litegraph'
import { app } from '../../scripts/app'
import { app } from '@/scripts/app'
let touchZooming = false
let touchCount = 0

View File

@@ -1,7 +1,7 @@
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
import { app } from '../../scripts/app'
import { ComfyWidgets } from '../../scripts/widgets'
import { app } from '@/scripts/app'
import { ComfyWidgets } from '@/scripts/widgets'
// Adds defaults for quickly adding nodes with middle click on the input/output

View File

@@ -21,8 +21,8 @@ import { useAudioService } from '@/services/audioService'
import { type NodeLocatorId } from '@/types'
import { getNodeByLocatorId } from '@/utils/graphTraversalUtil'
import { api } from '../../scripts/api'
import { app } from '../../scripts/app'
import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
async function uploadFile(
audioWidget: IStringWidget,

View File

@@ -4,7 +4,7 @@ import {
isComboInputSpecV1
} from '@/schemas/nodeDefSchema'
import { app } from '../../scripts/app'
import { app } from '@/scripts/app'
// Adds an upload button to the nodes

View File

@@ -1,8 +1,8 @@
import { t } from '@/i18n'
import { useToastStore } from '@/platform/updates/common/toastStore'
import { api } from '../../scripts/api'
import { app } from '../../scripts/app'
import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
const WEBCAM_READY = Symbol()

View File

@@ -1,38 +1,15 @@
import { isCloud } from '@/platform/distribution/types'
import { dispatchComfyExtensions } from '../dispatch'
import './clipspace'
import './contextMenuFilter'
import './dynamicPrompts'
import './editAttention'
import './electronAdapter'
import './groupNode'
import './groupNodeManage'
import './groupOptions'
import './load3d'
import './maskeditor'
import './matchType'
import './nodeTemplates'
import './noteNode'
import './previewAny'
import './rerouteNode'
import './saveImageExtraOutput'
import './saveMesh'
import './selectionBorder'
import './simpleTouchSupport'
import './slotDefaults'
import './uploadAudio'
import './uploadImage'
import './webcamCapture'
import './widgetInputs'
export async function importExtensions() {
console.log('importExtensions running...')
// Cloud-only extensions - tree-shaken in OSS builds
if (isCloud) {
await import('./cloudRemoteConfig')
await import('./cloudBadges')
await import('./cloudSessionCookie')
await import('./cloudFeedbackTopbarButton')
const extConfigs = import.meta.glob(`./extensions/*/comfy.ext.config.ts`, {
// Since each config is small, we only import the default export and use eager mode for better tree-shaking and performance.
import: 'default',
eager: true,
})
const extensionEntrance = import.meta.glob(`./extensions/*/index.ts`)
if (window.__CONFIG__?.subscription_required) {
await import('./cloudSubscription')
}
dispatchComfyExtensions({ configs: extConfigs, entrance: extensionEntrance })
}

View File

@@ -2,7 +2,7 @@ import { api } from '../../scripts/api'
import { app } from '../../scripts/app'
import { ComfyApp } from '../../scripts/app'
import { $el, ComfyDialog } from '../../scripts/ui'
import { ClipspaceDialog } from './clipspace'
import { ClipspaceDialog } from './extensions/clipspace'
// Helper function to convert a data URL to a Blob object
// @ts-expect-error fixme ts strict error

View File

@@ -0,0 +1,32 @@
import { isCloud } from '@/platform/distribution/types'
import type {
ComfyExtensionConfigs,
ComfyExtensionEntrance,
ComfyExtensionLoadContext
} from './types'
import { formatExtensions, shouldLoadExtension } from './utils'
const extLoadContext: ComfyExtensionLoadContext = {
get isCloud() {
return isCloud
},
get subscriptionRequired() {
return !!window.__CONFIG__?.subscription_required
}
}
export async function dispatchComfyExtensions(options: {
configs: ComfyExtensionConfigs
entrance: ComfyExtensionEntrance
}) {
const { configs, entrance } = options
const extensions = formatExtensions(entrance, configs)
for (const extension of Object.values(extensions)) {
if (shouldLoadExtension(extLoadContext, extension.config)) {
const module = await extension.entry()
console.log('✅ extension', extension.name, 'loaded', extension, module)
} else {
console.log('❌ extension', extension.name, 'disabled', extension.config)
}
}
}

30
src/extensions/types.ts Normal file
View File

@@ -0,0 +1,30 @@
export interface ComfyExtensionConfig {
comfyCloud?:
| boolean
| {
subscriptionRequired: boolean
}
}
export type ComfyExtensionConfigs = Record<
string,
ComfyExtensionConfig | undefined
>
export interface ComfyExtensionLoadContext {
readonly isCloud: boolean
readonly subscriptionRequired: boolean
}
export type ComfyExtensionEntry = () => Promise<Record<string, unknown>>
export type ComfyExtensionEntrance = Record<
string,
ComfyExtensionEntry | undefined
>
export interface ComfyExtensionPackage {
name?: string
path?: string
config?: ComfyExtensionConfig
entry: ComfyExtensionEntry
}
export type ComfyExtensionPackages = Record<string, ComfyExtensionPackage>

59
src/extensions/utils.ts Normal file
View File

@@ -0,0 +1,59 @@
import type {
ComfyExtensionConfig,
ComfyExtensionConfigs,
ComfyExtensionEntrance,
ComfyExtensionLoadContext,
ComfyExtensionPackages
} from './types'
export function defineComfyExtConfig(
config: ComfyExtensionConfig
): ComfyExtensionConfig {
return config
}
export function formatExtensions(
entrance: ComfyExtensionEntrance,
configs: ComfyExtensionConfigs
): ComfyExtensionPackages {
const pkgs: ComfyExtensionPackages = {}
for (const [entryPath, entry] of Object.entries(entrance)) {
const pathArr = entryPath.split('/')
const name = pathArr.at(-2)!
const path = pathArr.slice(0, -1).join('/')
if (!name) {
console.error(`Extension`, path, `has no name`)
continue
}
if (!entry) {
console.error(`Extension`, path, `has no entrance`)
continue
}
const config = configs[`${path}/comfy.ext.config.ts`]
if (!config) {
console.warn(`⚠️ Extension`, path, `has no config`)
}
pkgs[name] = { name, path, config, entry }
}
return pkgs
}
export function shouldLoadExtension(
ctx: ComfyExtensionLoadContext,
extConfig: ComfyExtensionConfig | undefined
): boolean {
// No Config -> Load Extension
if (!extConfig) return true
// Cloud Only Extension
const { comfyCloud } = extConfig
if (comfyCloud) {
if (!ctx.isCloud) return false
if (comfyCloud === true) return true
return comfyCloud.subscriptionRequired && ctx.subscriptionRequired
}
// Default Extension -> Load Extension
return true
}

View File

@@ -1,4 +1,4 @@
import type { PrimitiveNode } from '@/extensions/core/widgetInputs'
import type { PrimitiveNode } from '@/extensions/core/extensions/widgetInputs'
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
export const isPrimitiveNode = (

View File

@@ -35,7 +35,8 @@ export const useExtensionService = () => {
// Need to load core extensions first as some custom extensions
// may depend on them.
await import('../extensions/core/index')
const { importExtensions } = await import('../extensions/core/index')
await importExtensions()
extensionStore.captureCoreExtensions()
await Promise.all(
extensions

View File

@@ -2,7 +2,7 @@ import { toRaw } from 'vue'
import { nodeToLoad3dMap } from '@/composables/useLoad3d'
import { useLoad3dViewer } from '@/composables/useLoad3dViewer'
import type Load3d from '@/extensions/core/load3d/Load3d'
import type Load3d from '@/extensions/core/extensions/load3d/Load3d'
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
import type { NodeId } from '@/platform/workflow/validation/schemas/workflowSchema'

View File

@@ -1,4 +1,4 @@
import type { GroupNodeHandler } from '@/extensions/core/groupNode'
import type { GroupNodeHandler } from '@/extensions/core/extensions/groupNode'
import { ExecutableNodeDTO } from '@/lib/litegraph/src/litegraph'
import type {
ExecutableLGraphNode,

View File

@@ -2,16 +2,16 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { nextTick, ref } from 'vue'
import { nodeToLoad3dMap, useLoad3d } from '@/composables/useLoad3d'
import Load3d from '@/extensions/core/load3d/Load3d'
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
import Load3d from '@/extensions/core/extensions/load3d/Load3d'
import Load3dUtils from '@/extensions/core/extensions/load3d/Load3dUtils'
import { useToastStore } from '@/platform/updates/common/toastStore'
import { api } from '@/scripts/api'
vi.mock('@/extensions/core/load3d/Load3d', () => ({
vi.mock('@/extensions/core/extensions/load3d/Load3d', () => ({
default: vi.fn()
}))
vi.mock('@/extensions/core/load3d/Load3dUtils', () => ({
vi.mock('@/extensions/core/extensions/load3d/Load3dUtils', () => ({
default: {
splitFilePath: vi.fn(),
getResourceURL: vi.fn(),

View File

@@ -2,8 +2,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { nextTick } from 'vue'
import { useLoad3dViewer } from '@/composables/useLoad3dViewer'
import Load3d from '@/extensions/core/load3d/Load3d'
import Load3dUtils from '@/extensions/core/load3d/Load3dUtils'
import Load3d from '@/extensions/core/extensions/load3d/Load3d'
import Load3dUtils from '@/extensions/core/extensions/load3d/Load3dUtils'
import { useToastStore } from '@/platform/updates/common/toastStore'
import { useLoad3dService } from '@/services/load3dService'
@@ -15,7 +15,7 @@ vi.mock('@/platform/updates/common/toastStore', () => ({
useToastStore: vi.fn()
}))
vi.mock('@/extensions/core/load3d/Load3dUtils', () => ({
vi.mock('@/extensions/core/extensions/load3d/Load3dUtils', () => ({
default: {
uploadFile: vi.fn()
}
@@ -25,7 +25,7 @@ vi.mock('@/i18n', () => ({
t: vi.fn((key) => key)
}))
vi.mock('@/extensions/core/load3d/Load3d', () => ({
vi.mock('@/extensions/core/extensions/load3d/Load3d', () => ({
default: vi.fn()
}))

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest'
import { imageLayerFilenamesIfApplicable } from '@/extensions/core/maskeditor/utils/maskEditorLayerFilenames'
import { imageLayerFilenamesIfApplicable } from '@/extensions/core/extensions/maskeditor/utils/maskEditorLayerFilenames'
describe('imageLayerFilenamesIfApplicable', () => {
// In case the naming scheme changes, this test will ensure CI fails if developers forget to support the old naming scheme. (Causing MaskEditor to lose layer data for previously-saved images.)

View File

@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { GroupNodeHandler } from '@/extensions/core/groupNode'
import type { GroupNodeHandler } from '@/extensions/core/extensions/groupNode'
import type {
ExecutableLGraphNode,
ExecutionId,