feat(cli): build and send json-schema per function#5572
feat(cli): build and send json-schema per function#5572
Conversation
| webhookSubscriptions: z.array(z.string().max(255)).optional(), | ||
| models_json_schema: z | ||
| .object({ | ||
| $schema: z.literal('http://json-schema.org/draft-07/schema#'), |
There was a problem hiding this comment.
Felt like this is unnecessary and will increase storage with redundancy.
There was a problem hiding this comment.
Schema generation may be invalid due to missing top-level $schema in output.
Status: Changes Suggested | Risk: Medium
Issues Identified & Suggestions
- Add top-level $schema to keep JSON Schema valid and tests passing:
packages/cli/lib/zeroYaml/json-schema.ts
Review Details
📁 20 files reviewed | 💬 1 comments
Instruction Files
├── .claude/
│ ├── agents/
│ │ └── nango-docs-migrator.md
│ └── skills/
│ ├── agent-builder-skill/
│ │ ├── EXAMPLES.md
│ │ └── SKILL.md
│ ├── creating-integration-docs/
│ │ └── SKILL.md
│ └── creating-skills-skill/
│ └── SKILL.md
├── AGENTS.md
└── GEMINI.md
👍 / 👎 individual comments to help improve reviews for you
| return { | ||
| definitions | ||
| }; |
There was a problem hiding this comment.
[Logic] The new buildJsonSchemaDefinitionsFromZodModels return value omits the top-level $schema, but the added snapshot expects it. This will fail the unit test and produces a non-standard JSON Schema document. Add $schema at the top-level return so the output matches the snapshot and stays valid JSON Schema.
| return { | |
| definitions | |
| }; | |
| return { | |
| $schema: 'http://json-schema.org/draft-07/schema#', | |
| definitions | |
| }; |
Context for Agents
The new `buildJsonSchemaDefinitionsFromZodModels` return value omits the top-level `$schema`, but the added snapshot expects it. This will fail the unit test and produces a non-standard JSON Schema document. Add `$schema` at the top-level return so the output matches the snapshot and stays valid JSON Schema.
```suggestion
return {
$schema: 'http://json-schema.org/draft-07/schema#',
definitions
};
```
File: packages/cli/lib/zeroYaml/json-schema.ts
Line: 52There was a problem hiding this comment.
Changes suggested due to a potential runtime error when JSON schema definitions are missing.
Status: Changes Suggested | Risk: Medium
Issues Identified & Suggestions
- Guard missing JSON schema definitions before casting to avoid runtime errors:
packages/cli/lib/services/docs.service.ts
Review Details
📁 22 files reviewed | 💬 1 comments
Instruction Files
├── .claude/
│ ├── agents/
│ │ └── nango-docs-migrator.md
│ └── skills/
│ ├── agent-builder-skill/
│ │ ├── EXAMPLES.md
│ │ └── SKILL.md
│ ├── creating-integration-docs/
│ │ └── SKILL.md
│ └── creating-skills-skill/
│ └── SKILL.md
├── AGENTS.md
└── GEMINI.md
👍 / 👎 individual comments to help improve reviews for you
| endpointType: entry.type, | ||
| scriptConfig: entry, | ||
| models: entry.usedModels.map((name) => ({ name, def: jsonSchema.definitions![name]! })), | ||
| models: entry.usedModels.map((name) => ({ name, def: entry.json_schema?.definitions?.[name] as JSONSchema7Definition })), |
There was a problem hiding this comment.
[Logic] # Potential Runtime Error: Missing json_schema on Flows
In packages/cli/lib/services/docs.service.ts on line 63, the code uses optional chaining for entry.json_schema?.definitions?.[name] but then casts to JSONSchema7Definition without handling the undefined case. If a function doesn't have json_schema populated, this will pass undefined to the models array, causing potential errors when the documentation generator tries to use these definitions.
Specific scenario that fails:
- Legacy syncs/actions that don't have
json_schemapopulated yet (the field is optional during transition) - Doc generation tries to access
undefined.definitions[name] - Results in broken documentation or runtime errors
Fix:
Add proper fallback handling:
models: entry.usedModels.map((name) => {
const def = entry.json_schema?.definitions?.[name];
if (!def) {
throw new Error(`Missing JSON schema definition for model "${name}" in ${entry.type} "${entry.name}"`);
}
return { name, def: def as JSONSchema7Definition };
}),Or provide a safe default:
models: entry.usedModels
.map((name) => {
const def = entry.json_schema?.definitions?.[name];
return def ? { name, def: def as JSONSchema7Definition } : null;
})
.filter((model): model is { name: string; def: JSONSchema7Definition } => model !== null),Context for Agents
# Potential Runtime Error: Missing `json_schema` on Flows
In `packages/cli/lib/services/docs.service.ts` on line 63, the code uses optional chaining for `entry.json_schema?.definitions?.[name]` but then casts to `JSONSchema7Definition` without handling the `undefined` case. If a function doesn't have `json_schema` populated, this will pass `undefined` to the models array, causing potential errors when the documentation generator tries to use these definitions.
**Specific scenario that fails:**
- Legacy syncs/actions that don't have `json_schema` populated yet (the field is optional during transition)
- Doc generation tries to access `undefined.definitions[name]`
- Results in broken documentation or runtime errors
**Fix:**
Add proper fallback handling:
```typescript
models: entry.usedModels.map((name) => {
const def = entry.json_schema?.definitions?.[name];
if (!def) {
throw new Error(`Missing JSON schema definition for model "${name}" in ${entry.type} "${entry.name}"`);
}
return { name, def: def as JSONSchema7Definition };
}),
```
Or provide a safe default:
```typescript
models: entry.usedModels
.map((name) => {
const def = entry.json_schema?.definitions?.[name];
return def ? { name, def: def as JSONSchema7Definition } : null;
})
.filter((model): model is { name: string; def: JSONSchema7Definition } => model !== null),
```
File: packages/cli/lib/services/docs.service.ts
Line: 63| import type { JSONSchema7 } from 'json-schema'; | ||
|
|
||
| function zodSchemaToJsonSchema(schema: z.ZodTypeAny): JSONSchema7 | null { | ||
| if (schema.constructor.name === 'ZodVoid') { |
There was a problem hiding this comment.
would it be less fragile to use instanceOf instead of .name === or at least use the _zod private api?
| * Converts a map of named Zod schemas into a single JSON Schema document | ||
| * with a `definitions` block containing each model. | ||
| * | ||
| * Zod schemas that resolve to `void` are silently skipped. |
There was a problem hiding this comment.
that's not what the code above is saying
We currently generate a "global" json schema with all the models in the integration folders and save it to
schema.json. When deploying / generating docs / dry-running, we load that big schema and use it as the source of truth. We send the full json-schema for deploying, and let the server filter the schemas for each function (aka. sync_config, flow).Furthermore, we take a very convoluted path to generate
schema.json:NangoModelNangoModelto generateschema.tsts-to-json-schema-generatorto generateschema.jsonfromschema.tsIn my previous PR, I made the server accept function-level json-schemas. Each function can now be sent with it's own json-schema, as opposed to a single top-level json-schema in
POST /sync/deploy.This PR:
schema.tsandschema.jsonAS IS (adds a deprecation notice comment onschema.ts)cliandrunner-sdkpackages to v4.3.6 (currently latest)cli/example/package.json. This is what will make our customers packages be updated as soon as a cli command is run.z.toJsonSchema(introduced in zod v4) to generate json-schemas directly from the zod schemas.schema.json.deploy,dry-runandgenerate:docswill re-generate them in-memory for use. The source is the compiledcjsfiles, and not the typescript files themselves.This PR shifts schema handling from a single aggregated
schema.jsonto per-function JSON schemas generated directly from Zod v4 viaz.toJSONSchema. The CLI now attachesmodels_json_schemato each sync/action in deploy payloads, and dry-run and docs generation consume the function-level schemas instead of loading a top-level file.It updates
zodto4.3.6inpackages/cli,packages/runner-sdk, andpackages/cli/example, introduces a newbuildJsonSchemaDefinitionsFromZodModelshelper, adds deprecation notices for legacyschema.ts/schema.json, and adjusts server validation/types/tests to accept schemas without a required `` field.Possible Issues
• Docs generation now relies on
entry.json_schemabeing present; missingjson_schemacould yield undefined model definitions• Per-function schemas omit a top-level ``, which could affect external consumers expecting it
This summary was automatically generated by @propel-code-bot