Skip to content

Commit a86dd5e

Browse files
committed
Add support for Zod 4 in schema-to-json
This change enhances the schema-to-json package by adding support for Zod version 4, which introduces the native `toJsonSchema` method. This method facilitates a direct conversion of Zod schemas to JSON Schema format, improving performance and reducing reliance on the `zod-to-json-schema` library. - Updated README to reflect Zod 4 support with native method and retained support for Zod 3 via existing library. - Modified package.json to allow installation of both Zod 3 and 4 versions. - Implemented handling for Zod 4 schemas in `src/index.ts` using their native method. - Added a test case to verify the proper conversion of Zod 4 schemas to JSON Schema. - Included a script for updating the package version based on the root package.json. - Introduced a specific TypeScript config for source files.
1 parent 4b840a2 commit a86dd5e

6 files changed

Lines changed: 83 additions & 4 deletions

File tree

packages/schema-to-json/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ npm install @trigger.dev/schema-to-json
1010

1111
## Supported Schema Libraries
1212

13-
-**Zod** - Full support via `zod-to-json-schema`
13+
-**Zod** - Full support
14+
- Zod 4: Native support via built-in `toJsonSchema` method
15+
- Zod 3: Support via `zod-to-json-schema` library
1416
-**Yup** - Full support via `@sodaru/yup-to-json-schema`
1517
-**ArkType** - Native support (built-in `toJsonSchema` method)
1618
-**Effect/Schema** - Full support via Effect's JSONSchema module

packages/schema-to-json/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"valibot": "^1.0.0-beta.8",
5858
"vitest": "^2.1.8",
5959
"yup": "^1.6.1",
60-
"zod": "^3.24.1"
60+
"zod": "^3.24.1 || ^4.0.0"
6161
},
6262
"peerDependencies": {
6363
"@effect/schema": "^0.76.5",
@@ -68,7 +68,7 @@
6868
"typebox": "^0.34.3",
6969
"valibot": "^1.0.0-beta.8",
7070
"yup": "^1.6.1",
71-
"zod": "^3.24.1"
71+
"zod": "^3.24.1 || ^4.0.0"
7272
},
7373
"peerDependenciesMeta": {
7474
"@effect/schema": {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env node
2+
3+
import { readFileSync, writeFileSync } from "fs";
4+
import { fileURLToPath } from "url";
5+
import { dirname, join } from "path";
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = dirname(__filename);
9+
10+
// Read the package.json
11+
const packageJsonPath = join(__dirname, "..", "package.json");
12+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
13+
14+
// Read the root package.json to get the version
15+
const rootPackageJsonPath = join(__dirname, "..", "..", "..", "package.json");
16+
const rootPackageJson = JSON.parse(readFileSync(rootPackageJsonPath, "utf-8"));
17+
18+
// Update the version
19+
packageJson.version = rootPackageJson.version;
20+
21+
// Write back the package.json
22+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
23+
24+
console.log(`Updated @trigger.dev/schema-to-json version to ${packageJson.version}`);

packages/schema-to-json/src/__tests__/index.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,35 @@ describe('schemaToJsonSchema', () => {
6262
expect(result?.jsonSchema).toBeDefined();
6363
// The exact structure depends on zod-to-json-schema implementation
6464
});
65+
66+
it('should handle Zod 4 schema with built-in toJsonSchema method', () => {
67+
// Mock a Zod 4 schema with toJsonSchema method
68+
const mockZod4Schema = {
69+
parse: (val: unknown) => val,
70+
parseAsync: async (val: unknown) => val,
71+
toJsonSchema: () => ({
72+
type: 'object',
73+
properties: {
74+
id: { type: 'string' },
75+
count: { type: 'number' }
76+
},
77+
required: ['id', 'count']
78+
})
79+
};
80+
81+
const result = schemaToJsonSchema(mockZod4Schema);
82+
83+
expect(result).toBeDefined();
84+
expect(result?.schemaType).toBe('zod');
85+
expect(result?.jsonSchema).toEqual({
86+
type: 'object',
87+
properties: {
88+
id: { type: 'string' },
89+
count: { type: 'number' }
90+
},
91+
required: ['id', 'count']
92+
});
93+
});
6594
});
6695

6796
describe('Yup schemas', () => {

packages/schema-to-json/src/index.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ export function schemaToJsonSchema(schema: Schema, options?: ConversionOptions):
4848

4949
// Check if it's a Zod schema
5050
if (typeof parser.parseAsync === "function" || typeof parser.parse === "function") {
51+
// Check if it's Zod 4 with built-in toJsonSchema method
52+
if (typeof parser.toJsonSchema === "function") {
53+
try {
54+
const jsonSchema = parser.toJsonSchema();
55+
return {
56+
jsonSchema: options?.additionalProperties ? { ...jsonSchema, ...options.additionalProperties } : jsonSchema,
57+
schemaType: 'zod'
58+
};
59+
} catch (error) {
60+
console.warn('Failed to convert Zod 4 schema using built-in toJsonSchema:', error);
61+
}
62+
}
63+
64+
// Fall back to zod-to-json-schema library (for Zod 3 or if built-in method fails)
5165
try {
5266
const { zodToJsonSchema } = require('zod-to-json-schema');
5367
const jsonSchema = options?.name
@@ -68,7 +82,7 @@ export function schemaToJsonSchema(schema: Schema, options?: ConversionOptions):
6882
schemaType: 'zod'
6983
};
7084
} catch (error) {
71-
console.warn('Failed to convert Zod schema to JSON Schema:', error);
85+
console.warn('Failed to convert Zod schema to JSON Schema using zod-to-json-schema:', error);
7286
return undefined;
7387
}
7488
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../../.configs/tsconfig.base.json",
3+
"compilerOptions": {
4+
"rootDir": "./src",
5+
"outDir": "./dist",
6+
"types": ["node"]
7+
},
8+
"include": ["./src/**/*.ts"],
9+
"exclude": ["./src/**/*.test.ts"]
10+
}

0 commit comments

Comments
 (0)