@gabrielbryk/json-schema-to-zod 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/RELEASE_SETUP.md +120 -0
- package/.github/TOOLING_GUIDE.md +169 -0
- package/.github/dependabot.yml +52 -0
- package/.github/workflows/ci.yml +33 -0
- package/.github/workflows/release.yml +12 -4
- package/.github/workflows/security.yml +40 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +1 -0
- package/.lintstagedrc.json +3 -0
- package/.prettierrc +20 -0
- package/AGENTS.md +7 -0
- package/CHANGELOG.md +13 -4
- package/README.md +9 -9
- package/commitlint.config.js +24 -0
- package/createIndex.ts +4 -4
- package/dist/cli.js +3 -4
- package/dist/core/analyzeSchema.js +28 -5
- package/dist/core/emitZod.js +11 -4
- package/dist/generators/generateBundle.js +67 -92
- package/dist/parsers/parseAllOf.js +11 -12
- package/dist/parsers/parseAnyOf.js +2 -2
- package/dist/parsers/parseArray.js +38 -12
- package/dist/parsers/parseMultipleType.js +2 -2
- package/dist/parsers/parseNumber.js +44 -102
- package/dist/parsers/parseObject.js +138 -393
- package/dist/parsers/parseOneOf.js +57 -100
- package/dist/parsers/parseSchema.js +132 -55
- package/dist/parsers/parseSimpleDiscriminatedOneOf.js +2 -2
- package/dist/parsers/parseString.js +113 -253
- package/dist/types/Types.d.ts +22 -1
- package/dist/types/core/analyzeSchema.d.ts +1 -0
- package/dist/types/generators/generateBundle.d.ts +1 -1
- package/dist/utils/cliTools.js +1 -2
- package/dist/utils/esmEmitter.js +6 -2
- package/dist/utils/extractInlineObject.js +1 -3
- package/dist/utils/jsdocs.js +1 -4
- package/dist/utils/liftInlineObjects.js +76 -15
- package/dist/utils/resolveRef.js +35 -10
- package/dist/utils/schemaRepresentation.js +35 -66
- package/dist/zodToJsonSchema.js +1 -2
- package/docs/IMPROVEMENT-PLAN.md +30 -12
- package/docs/ZOD-V4-RECURSIVE-TYPE-LIMITATIONS.md +70 -25
- package/docs/proposals/allof-required-merging.md +10 -4
- package/docs/proposals/bundle-refactor.md +10 -4
- package/docs/proposals/discriminated-union-with-default.md +18 -14
- package/docs/proposals/inline-object-lifting.md +15 -5
- package/docs/proposals/ref-anchor-support.md +11 -0
- package/output.txt +67 -0
- package/package.json +18 -5
- package/scripts/generateWorkflowSchema.ts +5 -14
- package/scripts/regenerate_bundle.ts +25 -0
- package/tsc_output.txt +542 -0
- package/tsc_output_2.txt +489 -0
package/output.txt
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
> @gabrielbryk/json-schema-to-zod@2.12.0 test
|
|
3
|
+
> NODE_OPTIONS=--experimental-vm-modules jest test/jsonSchemaToZod.test.ts
|
|
4
|
+
|
|
5
|
+
console.log
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
const _Node = z.object({ "value": z.string(), get "next"(): z.ZodOptional<typeof Node> { return Node.optional(); } });
|
|
8
|
+
export const Node = _Node.passthrough();
|
|
9
|
+
export default Node;
|
|
10
|
+
|
|
11
|
+
at test/jsonSchemaToZod.test.ts:341:13
|
|
12
|
+
|
|
13
|
+
(node:175) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
|
|
14
|
+
(Use `node --trace-warnings ...` to show where the warning was created)
|
|
15
|
+
FAIL test/jsonSchemaToZod.test.ts
|
|
16
|
+
jsonSchemaToZod
|
|
17
|
+
✓ should accept json schema 7 and 4 (6 ms)
|
|
18
|
+
✓ should produce a string of JS code creating a Zod schema from a simple JSON schema (1 ms)
|
|
19
|
+
✓ should be possible to skip the import line
|
|
20
|
+
✓ should be possible to add types (1 ms)
|
|
21
|
+
✓ should be possible to add types with a custom name template
|
|
22
|
+
✓ should throw when given type but no name
|
|
23
|
+
✓ should include defaults
|
|
24
|
+
✓ should include falsy defaults
|
|
25
|
+
✓ should include falsy defaults (1 ms)
|
|
26
|
+
✓ can exclude defaults
|
|
27
|
+
✓ should include describes (1 ms)
|
|
28
|
+
✓ can exclude describes
|
|
29
|
+
✓ can include jsdocs (2 ms)
|
|
30
|
+
✓ will remove optionality if default is present (1 ms)
|
|
31
|
+
✓ will handle falsy defaults
|
|
32
|
+
✓ will ignore undefined as default
|
|
33
|
+
✓ should be possible to define a custom parser (1 ms)
|
|
34
|
+
✓ can output with name
|
|
35
|
+
✓ can output without name
|
|
36
|
+
✕ declares $refs as named schemas and uses getters for recursion (10 ms)
|
|
37
|
+
✓ uses upgraded discriminatedUnion map syntax (1 ms)
|
|
38
|
+
✓ supports propertyNames validation (1 ms)
|
|
39
|
+
✓ supports dependentSchemas (1 ms)
|
|
40
|
+
✓ supports contains with min/max contains (1 ms)
|
|
41
|
+
✓ supports contains on tuples (1 ms)
|
|
42
|
+
✓ can export reference declarations when requested
|
|
43
|
+
|
|
44
|
+
● jsonSchemaToZod › declares $refs as named schemas and uses getters for recursion
|
|
45
|
+
|
|
46
|
+
expect(received).toStrictEqual(expected) // deep equality
|
|
47
|
+
|
|
48
|
+
Expected: true
|
|
49
|
+
Received: false
|
|
50
|
+
|
|
51
|
+
71 | }
|
|
52
|
+
72 |
|
|
53
|
+
> 73 | expect(result).toStrictEqual(expected);
|
|
54
|
+
| ^
|
|
55
|
+
74 | });
|
|
56
|
+
75 | });
|
|
57
|
+
76 | });
|
|
58
|
+
|
|
59
|
+
at test/suite.ts:73:26
|
|
60
|
+
at test/jsonSchemaToZod.test.ts:344:5
|
|
61
|
+
at Object.<anonymous> (test/suite.ts:19:9)
|
|
62
|
+
|
|
63
|
+
Test Suites: 1 failed, 1 total
|
|
64
|
+
Tests: 1 failed, 25 passed, 26 total
|
|
65
|
+
Snapshots: 0 total
|
|
66
|
+
Time: 0.363 s, estimated 1 s
|
|
67
|
+
Ran all test suites matching /test\/jsonSchemaToZod.test.ts/i.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gabrielbryk/json-schema-to-zod",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Converts JSON schema objects or files into Zod schemas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -60,19 +60,24 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@changesets/cli": "^2.29.8",
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@types/json-schema": "^7.0.15",
|
|
63
|
+
"@commitlint/cli": "^20.2.0",
|
|
64
|
+
"@commitlint/config-conventional": "^20.2.0",
|
|
66
65
|
"@types/jest": "^29.5.14",
|
|
66
|
+
"@types/json-schema": "^7.0.15",
|
|
67
67
|
"@types/node": "^20.9.0",
|
|
68
|
+
"@typescript-eslint/eslint-plugin": "^8.49.0",
|
|
69
|
+
"@typescript-eslint/parser": "^8.49.0",
|
|
68
70
|
"eslint": "^9.39.1",
|
|
71
|
+
"husky": "^9.1.7",
|
|
69
72
|
"jest": "^29.7.0",
|
|
70
73
|
"js-yaml": "^4.1.0",
|
|
74
|
+
"lint-staged": "^16.2.7",
|
|
75
|
+
"prettier": "^3.7.4",
|
|
71
76
|
"rimraf": "^5.0.5",
|
|
72
77
|
"ts-jest": "^29.3.4",
|
|
73
78
|
"tsx": "^4.1.1",
|
|
74
79
|
"typescript": "^5.2.2",
|
|
75
|
-
"zod": "^4.
|
|
80
|
+
"zod": "^4.3.5"
|
|
76
81
|
},
|
|
77
82
|
"scripts": {
|
|
78
83
|
"build:esm": "tsc -p tsconfig.build.json",
|
|
@@ -82,6 +87,14 @@
|
|
|
82
87
|
"gen": "tsx ./createIndex.ts",
|
|
83
88
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
|
84
89
|
"lint": "eslint \"src/**/*.{ts,tsx}\" \"test/**/*.ts\"",
|
|
90
|
+
"lint:fix": "eslint \"src/**/*.{ts,tsx}\" \"test/**/*.ts\" --fix",
|
|
91
|
+
"format:write": "prettier --write .",
|
|
92
|
+
"format:check": "prettier --check .",
|
|
93
|
+
"audit": "pnpm audit --audit-level=moderate",
|
|
94
|
+
"ci": "pnpm run build && pnpm run format:check && pnpm run lint",
|
|
95
|
+
"lint-staged": "lint-staged",
|
|
96
|
+
"local-release": "changeset version && changeset publish",
|
|
97
|
+
"release": "changeset publish",
|
|
85
98
|
"smoke:esm": "pnpm build:esm && node --input-type=module -e \"import { jsonSchemaToZod } from './dist/index.js'; console.log(jsonSchemaToZod({type:'string'}));\""
|
|
86
99
|
}
|
|
87
100
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync, mkdirSync, writeFileSync } from "fs";
|
|
2
|
-
import {
|
|
2
|
+
import { join } from "path";
|
|
3
3
|
import yaml from "js-yaml";
|
|
4
4
|
import jsonSchemaToZod from "../src/index.js";
|
|
5
5
|
|
|
@@ -45,32 +45,23 @@ function main() {
|
|
|
45
45
|
|
|
46
46
|
for (const block of blocks) {
|
|
47
47
|
const normalizedLines = block.lines.map((l, idx) =>
|
|
48
|
-
idx === 0 ? l.replace(/^\s*(export\s+)?const\s+/, "export const ") : l
|
|
48
|
+
idx === 0 ? l.replace(/^\s*(export\s+)?const\s+/, "export const ") : l
|
|
49
49
|
);
|
|
50
50
|
const content = normalizedLines.join("\n");
|
|
51
51
|
const deps = Array.from(names)
|
|
52
52
|
.filter((n) => n !== block.name)
|
|
53
53
|
.filter((n) => new RegExp(`\\b${n}\\b`).test(content));
|
|
54
54
|
|
|
55
|
-
const importDepLines = deps.map(
|
|
56
|
-
(dep) => `import { ${dep} } from "./${dep}.js"`,
|
|
57
|
-
);
|
|
55
|
+
const importDepLines = deps.map((dep) => `import { ${dep} } from "./${dep}.js"`);
|
|
58
56
|
|
|
59
|
-
const fileContent = [
|
|
60
|
-
...importLines,
|
|
61
|
-
...importDepLines,
|
|
62
|
-
content,
|
|
63
|
-
"",
|
|
64
|
-
].join("\n");
|
|
57
|
+
const fileContent = [...importLines, ...importDepLines, content, ""].join("\n");
|
|
65
58
|
|
|
66
59
|
writeFileSync(join(SCHEMA_DIR, `${block.name}.ts`), fileContent);
|
|
67
60
|
}
|
|
68
61
|
|
|
69
62
|
// index exports all and the root schema
|
|
70
63
|
const exportLines = Array.from(
|
|
71
|
-
new Set(
|
|
72
|
-
blocks.map((b) => `export { ${b.name} } from "./schemas/${b.name}.js"`),
|
|
73
|
-
),
|
|
64
|
+
new Set(blocks.map((b) => `export { ${b.name} } from "./schemas/${b.name}.js"`))
|
|
74
65
|
);
|
|
75
66
|
|
|
76
67
|
writeFileSync(OUTPUT_INDEX, exportLines.join("\n") + "\n");
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import yaml from "js-yaml";
|
|
4
|
+
import { generateSchemaBundle } from "../src/index.ts";
|
|
5
|
+
|
|
6
|
+
const schema = yaml.load(readFileSync("test/fixtures/workflow.yaml", "utf8")) as any;
|
|
7
|
+
|
|
8
|
+
const toPascalCase = (str: string) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
9
|
+
|
|
10
|
+
const result = generateSchemaBundle(schema, {
|
|
11
|
+
name: "workflowSchema",
|
|
12
|
+
splitDefs: {
|
|
13
|
+
fileName: (defName) => `${toPascalCase(defName)}.schema.ts`,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Ensure directory exists
|
|
18
|
+
const outputDir = "test/output/workflow/schemas";
|
|
19
|
+
mkdirSync(outputDir, { recursive: true });
|
|
20
|
+
|
|
21
|
+
result.files.forEach((file) => {
|
|
22
|
+
writeFileSync(join(outputDir, file.fileName), file.contents);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log(`Generated ${result.files.length} files in ${outputDir}`);
|