Skip to content

Commit d07e4ab

Browse files
AustinMrozDrJKL
authored andcommitted
less duplication, more typechecking
1 parent 9ab7852 commit d07e4ab

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

src/extensions/core/dynamicCombo.ts

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
22
import { transformInputSpecV1ToV2 } from '@/schemas/nodeDef/migration'
33

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'
96
import { app } from '@/scripts/app'
107
import type { ComfyApp } from '@/scripts/app'
118

129
function COMFY_DYNAMICCOMBO_V3(
1310
node: LGraphNode,
1411
inputName: string,
15-
inputData: InputSpec,
12+
untypedInputData: InputSpec,
1613
appArg: ComfyApp,
1714
widgetName?: string
1815
) {
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
2019
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])
2421
)
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+
}
2528

2629
const subSpec: ComboInputSpec = [Object.keys(options), {}]
2730
const { widget, minWidth, minHeight } = app.widgets['COMBO'](
@@ -55,25 +58,18 @@ function COMFY_DYNAMICCOMBO_V3(
5558
throw new Error("Dynamic widget doesn't exist on node")
5659
//FIXME: inputs MUST be well ordered
5760
//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}`
7268
//@ts-expect-error temporary duck violence
7369
node._addInput(
74-
transformInputSpecV1ToV2(newSpec.optional[name], {
70+
transformInputSpecV1ToV2(inputType![key], {
7571
name,
76-
isOptional: false
72+
isOptional
7773
})
7874
)
7975
currentDynamicNames.push(name)

src/schemas/nodeDefSchema.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ const zInputSpec = z.union([
186186
zCustomInputSpec
187187
])
188188

189-
const zComfyInputsSpec = z.object({
189+
export const zComfyInputsSpec = z.object({
190190
required: z.record(zInputSpec).optional(),
191191
optional: z.record(zInputSpec).optional(),
192192
// Frontend repo is not using it, but some custom nodes are using the
@@ -230,6 +230,18 @@ export const zComfyNodeDef = z.object({
230230
input_order: z.record(z.array(z.string())).optional()
231231
})
232232

233+
export const zDynamicComboInputSpec = z.tuple([
234+
z.literal('COMFY_DYNAMICCOMBO_V3'),
235+
zComboInputOptions.extend({
236+
options: z.array(
237+
z.object({
238+
inputs: zComfyInputsSpec,
239+
key: z.string()
240+
})
241+
)
242+
})
243+
])
244+
233245
// `/object_info`
234246
export type ComfyInputsSpec = z.infer<typeof zComfyInputsSpec>
235247
export type ComfyOutputTypesSpec = z.infer<typeof zComfyOutputTypesSpec>

0 commit comments

Comments
 (0)