diff --git a/src/composables/widgets/useBooleanWidget.ts b/src/composables/widgets/useBooleanWidget.ts index 5c226a385..51ac7a4f5 100644 --- a/src/composables/widgets/useBooleanWidget.ts +++ b/src/composables/widgets/useBooleanWidget.ts @@ -1,6 +1,6 @@ import type { LGraphNode } from '@comfyorg/litegraph' -import type { InputSpec } from '@/schemas/nodeDefSchema' +import { type InputSpec, isBooleanInputSpec } from '@/schemas/nodeDefSchema' import type { ComfyWidgetConstructor } from '@/scripts/widgets' export const useBooleanWidget = () => { @@ -9,7 +9,11 @@ export const useBooleanWidget = () => { inputName: string, inputData: InputSpec ) => { - const inputOptions = inputData[1] + if (!isBooleanInputSpec(inputData)) { + throw new Error(`Invalid input data: ${inputData}`) + } + + const inputOptions = inputData[1] ?? {} const defaultVal = inputOptions?.default ?? false const options = { on: inputOptions?.label_on, @@ -17,7 +21,6 @@ export const useBooleanWidget = () => { } return { - // @ts-expect-error InputSpec is not typed correctly widget: node.addWidget('toggle', inputName, defaultVal, () => {}, options) } } diff --git a/src/composables/widgets/useComboWidget.ts b/src/composables/widgets/useComboWidget.ts index 6a9cf7b89..684cf1c8f 100644 --- a/src/composables/widgets/useComboWidget.ts +++ b/src/composables/widgets/useComboWidget.ts @@ -1,7 +1,11 @@ import type { LGraphNode } from '@comfyorg/litegraph' import type { IComboWidget } from '@comfyorg/litegraph/dist/types/widgets' -import type { InputSpec } from '@/schemas/nodeDefSchema' +import { + type InputSpec, + isComboInputSpec, + isComboInputSpecV2 +} from '@/schemas/nodeDefSchema' import { addValueControlWidgets } from '@/scripts/widgets' import type { ComfyWidgetConstructor } from '@/scripts/widgets' import { useWidgetStore } from '@/stores/widgetStore' @@ -14,26 +18,32 @@ export const useComboWidget = () => { inputName: string, inputData: InputSpec ) => { + if (!isComboInputSpec(inputData)) { + throw new Error(`Invalid input data: ${inputData}`) + } + const widgetStore = useWidgetStore() - const { remote, options } = inputData[1] || {} + const inputOptions = inputData[1] ?? {} + const comboOptions = + (isComboInputSpecV2(inputData) ? inputOptions.options : inputData[0]) ?? + [] + const defaultValue = widgetStore.getDefaultValue(inputData) const res = { widget: node.addWidget('combo', inputName, defaultValue, () => {}, { - // @ts-expect-error InputSpec is not typed correctly - values: options ?? inputData[0] + values: comboOptions }) as IComboWidget } - if (remote) { + if (inputOptions.remote) { const remoteWidget = useRemoteWidget({ inputData, defaultValue, node, widget: res.widget }) - // @ts-expect-error InputSpec is not typed correctly - if (remote.refresh_button) remoteWidget.addRefreshButton() + if (inputOptions.remote.refresh_button) remoteWidget.addRefreshButton() const origOptions = res.widget.options res.widget.options = new Proxy( @@ -47,7 +57,7 @@ export const useComboWidget = () => { ) } - if (inputData[1]?.control_after_generate) { + if (inputOptions.control_after_generate) { res.widget.linkedWidgets = addValueControlWidgets( node, res.widget, diff --git a/src/composables/widgets/useStringWidget.ts b/src/composables/widgets/useStringWidget.ts index a2884d690..411b7596f 100644 --- a/src/composables/widgets/useStringWidget.ts +++ b/src/composables/widgets/useStringWidget.ts @@ -1,6 +1,6 @@ import type { IWidget, LGraphNode } from '@comfyorg/litegraph' -import type { InputSpec } from '@/schemas/nodeDefSchema' +import { type InputSpec, isStringInputSpec } from '@/schemas/nodeDefSchema' import type { ComfyWidgetConstructor } from '@/scripts/widgets' import { useSettingStore } from '@/stores/settingStore' import type { ComfyApp } from '@/types' @@ -64,15 +64,20 @@ export const useStringWidget = () => { inputData: InputSpec, app: ComfyApp ) => { - const defaultVal = inputData[1]?.default || '' - const multiline = !!inputData[1]?.multiline + if (!isStringInputSpec(inputData)) { + throw new Error(`Invalid input data: ${inputData}`) + } + + const inputOptions = inputData[1] ?? {} + const defaultVal = inputOptions.default ?? '' + const multiline = inputOptions.multiline let res: { widget: IWidget } if (multiline) { res = addMultilineWidget( node, inputName, - { defaultVal, ...inputData[1] }, + { defaultVal, ...inputOptions }, app ) } else { @@ -81,9 +86,9 @@ export const useStringWidget = () => { } } - if (inputData[1]?.dynamicPrompts != undefined) - // @ts-expect-error InputSpec is not typed correctly - res.widget.dynamicPrompts = inputData[1].dynamicPrompts + if (inputOptions.dynamicPrompts != undefined) { + res.widget.dynamicPrompts = inputOptions.dynamicPrompts + } return res } diff --git a/src/schemas/nodeDefSchema.ts b/src/schemas/nodeDefSchema.ts index c991c40aa..a3e8cb03b 100644 --- a/src/schemas/nodeDefSchema.ts +++ b/src/schemas/nodeDefSchema.ts @@ -69,7 +69,8 @@ const zComboInputOptions = zBaseInputOptions.extend({ image_folder: z.enum(['input', 'output', 'temp']).optional(), allow_batch: z.boolean().optional(), video_upload: z.boolean().optional(), - remote: zRemoteWidgetConfig.optional() + remote: zRemoteWidgetConfig.optional(), + options: z.array(z.union([z.string(), z.number()])).optional() }) const zIntInputSpec = z.tuple([z.literal('INT'), zIntInputOptions.optional()]) diff --git a/src/stores/widgetStore.ts b/src/stores/widgetStore.ts index b72a52d15..869014f5a 100644 --- a/src/stores/widgetStore.ts +++ b/src/stores/widgetStore.ts @@ -21,6 +21,9 @@ export const useWidgetStore = defineStore('widget', () => { function getWidgetType(type: string, inputName: string) { if (type === 'COMBO') { return 'COMBO' + /** + * @deprecated Group node logic. Remove once group node feature is removed. + */ } else if (`${type}:${inputName}` in widgets.value) { return `${type}:${inputName}` } else if (type in widgets.value) { diff --git a/tests-ui/tests/composables/widgets/useComboWidget.test.ts b/tests-ui/tests/composables/widgets/useComboWidget.test.ts index e8816b063..7cf6e6099 100644 --- a/tests-ui/tests/composables/widgets/useComboWidget.test.ts +++ b/tests-ui/tests/composables/widgets/useComboWidget.test.ts @@ -41,7 +41,7 @@ describe('useComboWidget', () => { undefined, // default value expect.any(Function), // callback expect.objectContaining({ - values: 'COMBO' + values: [] }) ) expect(widget).toEqual({