Skip to content

Commit fe0d63e

Browse files
authored
Use consistent NodeId and SlotIndex in schema (#359)
* Use consistent NodeId and SlotIndex in schema * Add test
1 parent 3c76554 commit fe0d63e

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

src/types/apiTypes.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { ZodType, z } from 'zod'
2-
import { zComfyWorkflow } from './comfyWorkflow'
2+
import { zComfyWorkflow, zNodeId } from './comfyWorkflow'
33
import { fromZodError } from 'zod-validation-error'
44

5-
const zNodeId = z.union([z.number(), z.string()])
65
const zNodeType = z.string()
76
const zQueueIndex = z.number()
87
const zPromptId = z.string()

src/types/comfyWorkflow.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
import { z } from 'zod'
22
import { fromZodError } from 'zod-validation-error'
33

4+
// GroupNode is hacking node id to be a string, so we need to allow that.
5+
// innerNode.id = `${this.node.id}:${i}`
6+
// Remove it after GroupNode is redesigned.
7+
export const zNodeId = z.union([z.number().int(), z.string()])
8+
export const zSlotIndex = z.union([
9+
z.number().int(),
10+
z
11+
.string()
12+
.transform((val) => parseInt(val))
13+
.refine((val) => !isNaN(val), {
14+
message: 'Invalid number'
15+
})
16+
])
17+
418
// Definition of an AI model file used in the workflow.
519
const zModelFile = z.object({
620
name: z.string(),
@@ -12,10 +26,10 @@ const zModelFile = z.object({
1226

1327
const zComfyLink = z.tuple([
1428
z.number(), // Link id
15-
z.number(), // Node id of source node
16-
z.number(), // Output slot# of source node
17-
z.number(), // Node id of destination node
18-
z.number(), // Input slot# of destination node
29+
zNodeId, // Node id of source node
30+
zSlotIndex, // Output slot# of source node
31+
zNodeId, // Node id of destination node
32+
zSlotIndex, // Input slot# of destination node
1933
z.string() // Data type
2034
])
2135

@@ -24,7 +38,7 @@ const zNodeOutput = z
2438
name: z.string(),
2539
type: z.string(),
2640
links: z.array(z.number()).nullable(),
27-
slot_index: z.number().optional()
41+
slot_index: zSlotIndex.optional()
2842
})
2943
.passthrough()
3044

@@ -33,7 +47,7 @@ const zNodeInput = z
3347
name: z.string(),
3448
type: z.string(),
3549
link: z.number().nullable(),
36-
slot_index: z.number().optional()
50+
slot_index: zSlotIndex.optional()
3751
})
3852
.passthrough()
3953

@@ -62,7 +76,7 @@ const zWidgetValues = z.union([z.array(z.any()), z.record(z.any())])
6276

6377
const zComfyNode = z
6478
.object({
65-
id: z.number(),
79+
id: zNodeId,
6680
type: z.string(),
6781
pos: zVector2,
6882
size: zVector2,
@@ -123,7 +137,7 @@ const zExtra = z
123137

124138
export const zComfyWorkflow = z
125139
.object({
126-
last_node_id: z.number(),
140+
last_node_id: zNodeId,
127141
last_link_id: z.number(),
128142
nodes: z.array(zComfyNode),
129143
links: z.array(zComfyLink),

tests-ui/tests/comfyWorkflow.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,20 @@ describe('parseComfyWorkflow', () => {
8888
const validatedWorkflow = await validateComfyWorkflow(workflow)
8989
expect(validatedWorkflow.nodes[0].widgets_values).toEqual({ foo: 'bar' })
9090
})
91+
92+
it('workflow.links', async () => {
93+
const workflow = JSON.parse(JSON.stringify(defaultGraph))
94+
95+
workflow.links = [
96+
[
97+
1, // Link id
98+
'100:1', // Node id of source node
99+
'12', // Output slot# of source node
100+
'100:2', // Node id of destination node
101+
15, // Input slot# of destination node
102+
'INT' // Data type
103+
]
104+
]
105+
expect(await validateComfyWorkflow(workflow)).not.toBeNull()
106+
})
91107
})

0 commit comments

Comments
 (0)