Skip to content

Commit a4952e9

Browse files
dante01yoonclaudeactions-user
authored
feat: add Ingest API codegen with Zod schema generation (#9932)
## Summary - Add `packages/ingest-types/` package that auto-generates TypeScript types and Zod schemas from the Ingest service OpenAPI spec - Uses `@hey-api/openapi-ts` with built-in Zod plugin (Zod v3 compatible) - Filters out overlapping endpoints shared with the local ComfyUI Python backend - Generates **493 TypeScript types** and **256 Zod schemas** covering cloud-only endpoints - Configure knip to ignore generated files ## CI automation The cloud repo pushes generated types to this repo (push model, no private repo cloning). See: Comfy-Org/cloud#2858 ## How endpoint filtering works Codegen targets are controlled by the **exclude list** in `packages/ingest-types/openapi-ts.config.ts`. Everything in the Ingest `openapi.yaml` is included **except** overlapping endpoints that also exist in the local ComfyUI Python backend: **Excluded (overlapping with ComfyUI Python):** `/prompt`, `/queue`, `/history`, `/object_info`, `/features`, `/settings`, `/system_stats`, `/interrupt`, `/upload/*`, `/view`, `/jobs`, `/userdata`, `/webhooks/*`, `/internal/*` **Included (cloud-only, codegen targets):** `/workspaces/*`, `/billing/*`, `/secrets/*`, `/assets/*`, `/tasks/*`, `/auth/*`, `/workflows/*`, `/workspace/*`, `/user`, `/settings/{key}`, `/tags`, `/feedback`, `/invite_code/*`, `/experiment/models/*`, `/global_subgraphs/*` ## Follow-up: replace manual types with generated ones This PR only sets up the codegen infrastructure. A follow-up PR should replace manually maintained types with imports from `@comfyorg/ingest-types`: | File | Lines | Current | Replace with | |------|-------|---------|-------------| | `src/platform/workspace/api/workspaceApi.ts` | ~270 | TS interfaces | `import type { ... } from '@comfyorg/ingest-types'` | | `src/platform/secrets/types.ts` | ~32 | TS interfaces | `import type { ... } from '@comfyorg/ingest-types'` | | `src/platform/assets/schemas/assetSchema.ts` | ~125 | Zod schemas | `import { ... } from '@comfyorg/ingest-types/zod'` | | `src/platform/assets/schemas/mediaAssetSchema.ts` | ~50 | Zod schemas | `import { ... } from '@comfyorg/ingest-types/zod'` | | `src/platform/tasks/services/taskService.ts` | ~70 | Zod schemas | `import { ... } from '@comfyorg/ingest-types/zod'` | | `src/platform/workspace/workspaceTypes.ts` | ~6 | TS interface | `export type { ... } from '@comfyorg/ingest-types'` | ## Test plan - [x] `pnpm generate` in `packages/ingest-types/` produces `types.gen.ts` and `zod.gen.ts` - [x] `pnpm typecheck` passes - [x] Pre-commit hooks pass (lint, typecheck, format) - [x] Generated Zod schemas validate correct data and reject invalid data - [x] No import conflicts with existing code (generated types are isolated in separate package) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: GitHub Action <action@github.com>
1 parent 64c852b commit a4952e9

File tree

10 files changed

+7797
-2
lines changed

10 files changed

+7797
-2
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33

44
# Generated files
55
packages/registry-types/src/comfyRegistryTypes.ts linguist-generated=true
6+
packages/ingest-types/src/types.gen.ts linguist-generated=true
7+
packages/ingest-types/src/zod.gen.ts linguist-generated=true
68
src/workbench/extensions/manager/types/generatedManagerTypes.ts linguist-generated=true

knip.config.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ const config: KnipConfig = {
2626
},
2727
'packages/registry-types': {
2828
project: ['src/**/*.{js,ts}']
29+
},
30+
'packages/ingest-types': {
31+
project: ['src/**/*.{js,ts}'],
32+
entry: ['src/index.ts']
2933
}
3034
},
31-
ignoreBinaries: ['python3', 'gh'],
35+
ignoreBinaries: ['python3', 'gh', 'generate'],
3236
ignoreDependencies: [
3337
// Weird importmap things
3438
'@iconify-json/lucide',
@@ -41,9 +45,12 @@ const config: KnipConfig = {
4145
'@iconify/utils'
4246
],
4347
ignore: [
44-
// Auto generated manager types
48+
// Auto generated API types
4549
'src/workbench/extensions/manager/types/generatedManagerTypes.ts',
4650
'packages/registry-types/src/comfyRegistryTypes.ts',
51+
'packages/ingest-types/src/types.gen.ts',
52+
'packages/ingest-types/src/zod.gen.ts',
53+
'packages/ingest-types/openapi-ts.config.ts',
4754
// Used by a custom node (that should move off of this)
4855
'src/scripts/ui/components/splitButton.ts',
4956
// Used by stacked PR (feat/glsl-live-preview)

packages/ingest-types/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# OpenAPI spec is fetched from cloud repo during CI
2+
openapi.yaml
3+
# Crash logs
4+
openapi-ts-error-*.log
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { defineConfig } from '@hey-api/openapi-ts'
2+
3+
export default defineConfig({
4+
input: './openapi.yaml',
5+
output: {
6+
path: './src',
7+
clean: true
8+
},
9+
parser: {
10+
filters: {
11+
operations: {
12+
// Exclude endpoints that overlap with ComfyUI Python backend.
13+
// These are shared between local and cloud, with separate Zod
14+
// schemas already maintained in src/schemas/apiSchema.ts.
15+
exclude: [
16+
'/^GET \\/api\\/prompt$/',
17+
'/^POST \\/api\\/prompt$/',
18+
'/^GET \\/api\\/queue$/',
19+
'/^POST \\/api\\/queue$/',
20+
'/^GET \\/api\\/history$/',
21+
'/^POST \\/api\\/history$/',
22+
'/^GET \\/api\\/history_v2/',
23+
'/^GET \\/api\\/object_info$/',
24+
'/^GET \\/api\\/features$/',
25+
'/^GET \\/api\\/settings$/',
26+
'/^POST \\/api\\/settings$/',
27+
'/^GET \\/api\\/system_stats$/',
28+
'/^(GET|POST) \\/api\\/interrupt$/',
29+
'/^POST \\/api\\/upload\\//',
30+
'/^GET \\/api\\/view$/',
31+
'/^GET \\/api\\/jobs/',
32+
'/\\/api\\/userdata/',
33+
// Webhooks are server-to-server, not called by frontend
34+
'/\\/api\\/webhooks\\//',
35+
// Internal analytics endpoint
36+
'/\\/api\\/internal\\//'
37+
]
38+
}
39+
}
40+
},
41+
plugins: [
42+
'@hey-api/typescript',
43+
{
44+
name: 'zod',
45+
compatibilityVersion: 3,
46+
definitions: true,
47+
requests: true,
48+
responses: true
49+
}
50+
]
51+
})

packages/ingest-types/package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "@comfyorg/ingest-types",
3+
"version": "1.0.0",
4+
"description": "Comfy Cloud Ingest API TypeScript types and Zod schemas",
5+
"type": "module",
6+
"exports": {
7+
".": "./src/index.ts",
8+
"./zod": "./src/zod.gen.ts"
9+
},
10+
"scripts": {
11+
"generate": "openapi-ts && node -e \"const fs=require('fs'); ['src/zod.gen.ts'].forEach(f => fs.writeFileSync(f, fs.readFileSync(f,'utf8').replaceAll(\\\"from 'zod/v3'\\\", \\\"from 'zod'\\\")));\""
12+
},
13+
"dependencies": {
14+
"zod": "catalog:"
15+
},
16+
"devDependencies": {
17+
"@hey-api/openapi-ts": "0.93.0"
18+
},
19+
"packageManager": "pnpm@10.17.1",
20+
"nx": {
21+
"tags": [
22+
"scope:shared",
23+
"type:types"
24+
]
25+
}
26+
}

0 commit comments

Comments
 (0)