|
1 | 1 | import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode' |
2 | 2 | import { transformInputSpecV1ToV2 } from '@/schemas/nodeDef/migration' |
3 | 3 |
|
4 | | -import type { |
5 | | - ComboInputSpec, |
6 | | - ComfyInputsSpec, |
7 | | - InputSpec |
8 | | -} from '@/schemas/nodeDefSchema' |
| 4 | +import type { ComboInputSpec, InputSpec } from '@/schemas/nodeDefSchema' |
| 5 | +import { zDynamicComboInputSpec } from '@/schemas/nodeDefSchema' |
9 | 6 | import { app } from '@/scripts/app' |
10 | 7 | import type { ComfyApp } from '@/scripts/app' |
11 | 8 |
|
12 | 9 | function COMFY_DYNAMICCOMBO_V3( |
13 | 10 | node: LGraphNode, |
14 | 11 | inputName: string, |
15 | | - inputData: InputSpec, |
| 12 | + untypedInputData: InputSpec, |
16 | 13 | appArg: ComfyApp, |
17 | 14 | widgetName?: string |
18 | 15 | ) { |
19 | | - //FIXME: properly add to schema |
| 16 | + const parseResult = zDynamicComboInputSpec.safeParse(untypedInputData) |
| 17 | + if (!parseResult.success) throw new Error('invalid DynamicCombo spec') |
| 18 | + const inputData = parseResult.data |
20 | 19 | const options = Object.fromEntries( |
21 | | - (inputData[1]?.options as { inputs: ComfyInputsSpec; key: string }[]).map( |
22 | | - ({ key, inputs }) => [key, inputs] |
23 | | - ) |
| 20 | + inputData[1].options.map(({ key, inputs }) => [key, inputs]) |
24 | 21 | ) |
| 22 | + for (const option of Object.values(options)) |
| 23 | + for (const inputType of [option.required, option.optional]) |
| 24 | + for (const key in inputType ?? {}) { |
| 25 | + inputType![key][1] ??= {} |
| 26 | + inputType![key][1].label = key |
| 27 | + } |
25 | 28 |
|
26 | 29 | const subSpec: ComboInputSpec = [Object.keys(options), {}] |
27 | 30 | const { widget, minWidth, minHeight } = app.widgets['COMBO']( |
@@ -55,25 +58,18 @@ function COMFY_DYNAMICCOMBO_V3( |
55 | 58 | throw new Error("Dynamic widget doesn't exist on node") |
56 | 59 | //FIXME: inputs MUST be well ordered |
57 | 60 | //FIXME check for duplicates |
58 | | - |
59 | | - if (newSpec.required) |
60 | | - for (const name in newSpec.required) { |
61 | | - //@ts-expect-error temporary duck violence |
62 | | - node._addInput( |
63 | | - transformInputSpecV1ToV2(newSpec.required[name], { |
64 | | - name, |
65 | | - isOptional: false |
66 | | - }) |
67 | | - ) |
68 | | - currentDynamicNames.push(name) |
69 | | - } |
70 | | - if (newSpec.optional) |
71 | | - for (const name in newSpec.optional) { |
| 61 | + const inputTypes: [Record<string, InputSpec> | undefined, boolean][] = [ |
| 62 | + [newSpec.required, false], |
| 63 | + [newSpec.optional, true] |
| 64 | + ] |
| 65 | + for (const [inputType, isOptional] of inputTypes) |
| 66 | + for (const key in inputType ?? {}) { |
| 67 | + const name = `${widget.name}.${key}` |
72 | 68 | //@ts-expect-error temporary duck violence |
73 | 69 | node._addInput( |
74 | | - transformInputSpecV1ToV2(newSpec.optional[name], { |
| 70 | + transformInputSpecV1ToV2(inputType![key], { |
75 | 71 | name, |
76 | | - isOptional: false |
| 72 | + isOptional |
77 | 73 | }) |
78 | 74 | ) |
79 | 75 | currentDynamicNames.push(name) |
|
0 commit comments