@gabrielbryk/json-schema-to-zod 2.7.2 → 2.7.3
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/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/.github/workflows/release.yml +50 -0
- package/CHANGELOG.md +7 -0
- package/dist/cjs/parsers/parseIfThenElse.js +1 -1
- package/dist/cjs/parsers/parseObject.js +11 -10
- package/dist/cjs/parsers/parseSimpleDiscriminatedOneOf.js +5 -13
- package/dist/esm/parsers/parseIfThenElse.js +1 -1
- package/dist/esm/parsers/parseObject.js +11 -10
- package/dist/esm/parsers/parseSimpleDiscriminatedOneOf.js +5 -13
- package/package.json +2 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "public",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
pull-requests: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
release:
|
|
16
|
+
environment: npm-publish
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v5
|
|
20
|
+
|
|
21
|
+
- uses: pnpm/action-setup@v4
|
|
22
|
+
with:
|
|
23
|
+
run_install: false
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-node@v4
|
|
26
|
+
with:
|
|
27
|
+
node-version: 24
|
|
28
|
+
cache: pnpm
|
|
29
|
+
registry-url: https://registry.npmjs.org
|
|
30
|
+
|
|
31
|
+
- name: Update npm (trusted publishing requires >=11.5.1)
|
|
32
|
+
run: npm install -g npm@latest
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: pnpm install --frozen-lockfile
|
|
36
|
+
|
|
37
|
+
- name: Build
|
|
38
|
+
run: pnpm build
|
|
39
|
+
|
|
40
|
+
- name: Release with Changesets
|
|
41
|
+
uses: changesets/action@v1
|
|
42
|
+
with:
|
|
43
|
+
commit: "ci: release"
|
|
44
|
+
title: "ci: release"
|
|
45
|
+
version: pnpm changeset version
|
|
46
|
+
publish: pnpm changeset publish --access public
|
|
47
|
+
env:
|
|
48
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
49
|
+
NPM_TOKEN: ""
|
|
50
|
+
NODE_AUTH_TOKEN: ""
|
package/CHANGELOG.md
ADDED
|
@@ -17,7 +17,7 @@ const parseIfThenElse = (schema, refs) => {
|
|
|
17
17
|
? ${$then}.safeParse(value)
|
|
18
18
|
: ${$else}.safeParse(value);
|
|
19
19
|
if (!result.success) {
|
|
20
|
-
result.error.
|
|
20
|
+
result.error.errors.forEach((error) => ctx.addIssue(error))
|
|
21
21
|
}
|
|
22
22
|
})`;
|
|
23
23
|
// Store original if/then/else for JSON Schema round-trip
|
|
@@ -78,16 +78,16 @@ function parseObject(objectSchema, refs) {
|
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
80
80
|
if (additionalProperties) {
|
|
81
|
-
patternProperties += `z.record(z.
|
|
81
|
+
patternProperties += `z.record(z.union([${[
|
|
82
82
|
...Object.values(parsedPatternProperties),
|
|
83
83
|
additionalProperties,
|
|
84
84
|
].join(", ")}]))`;
|
|
85
85
|
}
|
|
86
86
|
else if (Object.keys(parsedPatternProperties).length > 1) {
|
|
87
|
-
patternProperties += `z.record(z.
|
|
87
|
+
patternProperties += `z.record(z.union([${Object.values(parsedPatternProperties).join(", ")}]))`;
|
|
88
88
|
}
|
|
89
89
|
else {
|
|
90
|
-
patternProperties += `z.record(
|
|
90
|
+
patternProperties += `z.record(${Object.values(parsedPatternProperties)})`;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
patternProperties += ".superRefine((value, ctx) => {\n";
|
|
@@ -103,8 +103,9 @@ function parseObject(objectSchema, refs) {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
for (const key in objectSchema.patternProperties) {
|
|
106
|
+
const escapedPattern = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
106
107
|
patternProperties +=
|
|
107
|
-
"if (key.match(new RegExp(" + JSON.stringify(
|
|
108
|
+
"if (key.match(new RegExp(" + JSON.stringify(escapedPattern) + "))) {\n";
|
|
108
109
|
if (additionalProperties) {
|
|
109
110
|
patternProperties += "evaluated = true\n";
|
|
110
111
|
}
|
|
@@ -114,7 +115,7 @@ function parseObject(objectSchema, refs) {
|
|
|
114
115
|
".safeParse(value[key])\n";
|
|
115
116
|
patternProperties += "if (!result.success) {\n";
|
|
116
117
|
patternProperties += `ctx.addIssue({
|
|
117
|
-
path: [key],
|
|
118
|
+
path: [...ctx.path, key],
|
|
118
119
|
code: 'custom',
|
|
119
120
|
message: \`Invalid input: Key matching regex /\${key}/ must match schema\`,
|
|
120
121
|
params: {
|
|
@@ -130,7 +131,7 @@ function parseObject(objectSchema, refs) {
|
|
|
130
131
|
"const result = " + additionalProperties + ".safeParse(value[key])\n";
|
|
131
132
|
patternProperties += "if (!result.success) {\n";
|
|
132
133
|
patternProperties += `ctx.addIssue({
|
|
133
|
-
path: [key],
|
|
134
|
+
path: [...ctx.path, key],
|
|
134
135
|
code: 'custom',
|
|
135
136
|
message: \`Invalid input: must match catchall schema\`,
|
|
136
137
|
params: {
|
|
@@ -151,10 +152,10 @@ function parseObject(objectSchema, refs) {
|
|
|
151
152
|
patternProperties += `.meta({ __jsonSchema: { patternProperties: ${patternPropsJson} } })`;
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
|
-
// Check if there will be an .and() call that adds properties from oneOf/anyOf/allOf
|
|
155
|
+
// Check if there will be an .and() call that adds properties from oneOf/anyOf/allOf/if-then-else
|
|
155
156
|
// In that case, we should NOT use .strict() because it will reject the additional keys
|
|
156
157
|
// before the union gets a chance to validate them.
|
|
157
|
-
const hasCompositionKeywords = parseSchema_js_1.its.an.anyOf(objectSchema) || parseSchema_js_1.its.a.oneOf(objectSchema) || parseSchema_js_1.its.an.allOf(objectSchema);
|
|
158
|
+
const hasCompositionKeywords = parseSchema_js_1.its.an.anyOf(objectSchema) || parseSchema_js_1.its.a.oneOf(objectSchema) || parseSchema_js_1.its.an.allOf(objectSchema) || parseSchema_js_1.its.a.conditional(objectSchema);
|
|
158
159
|
let output = properties
|
|
159
160
|
? patternProperties
|
|
160
161
|
? properties + patternProperties
|
|
@@ -169,8 +170,8 @@ function parseObject(objectSchema, refs) {
|
|
|
169
170
|
: patternProperties
|
|
170
171
|
? patternProperties
|
|
171
172
|
: additionalProperties
|
|
172
|
-
? `z.record(
|
|
173
|
-
: `z.record(
|
|
173
|
+
? `z.record(${additionalProperties})`
|
|
174
|
+
: `z.record(${(0, anyOrUnknown_js_1.anyOrUnknown)(refs)})`;
|
|
174
175
|
if (unevaluated === false && properties && !hasCompositionKeywords) {
|
|
175
176
|
output += ".strict()";
|
|
176
177
|
}
|
|
@@ -5,25 +5,17 @@ const parseSchema_js_1 = require("./parseSchema.js");
|
|
|
5
5
|
const anyOrUnknown_js_1 = require("../utils/anyOrUnknown.js");
|
|
6
6
|
const parseSimpleDiscriminatedOneOf = (schema, refs) => {
|
|
7
7
|
const discriminator = schema.discriminator.propertyName;
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
(discriminatorSchema.enum && discriminatorSchema.enum[0]);
|
|
13
|
-
const parsed = (0, parseSchema_js_1.parseSchema)(option, {
|
|
14
|
-
...refs,
|
|
15
|
-
path: [...refs.path, "oneOf", i],
|
|
16
|
-
});
|
|
17
|
-
const key = typeof value === "string" ? JSON.stringify(value) : JSON.stringify(String(value));
|
|
18
|
-
return `${key}: ${parsed}`;
|
|
19
|
-
});
|
|
8
|
+
const options = schema.oneOf.map((option, i) => (0, parseSchema_js_1.parseSchema)(option, {
|
|
9
|
+
...refs,
|
|
10
|
+
path: [...refs.path, "oneOf", i],
|
|
11
|
+
}));
|
|
20
12
|
return schema.oneOf.length
|
|
21
13
|
? schema.oneOf.length === 1
|
|
22
14
|
? (0, parseSchema_js_1.parseSchema)(schema.oneOf[0], {
|
|
23
15
|
...refs,
|
|
24
16
|
path: [...refs.path, "oneOf", 0],
|
|
25
17
|
})
|
|
26
|
-
: `z.discriminatedUnion("${discriminator}",
|
|
18
|
+
: `z.discriminatedUnion("${discriminator}", [${options.join(", ")}])`
|
|
27
19
|
: (0, anyOrUnknown_js_1.anyOrUnknown)(refs);
|
|
28
20
|
};
|
|
29
21
|
exports.parseSimpleDiscriminatedOneOf = parseSimpleDiscriminatedOneOf;
|
|
@@ -14,7 +14,7 @@ export const parseIfThenElse = (schema, refs) => {
|
|
|
14
14
|
? ${$then}.safeParse(value)
|
|
15
15
|
: ${$else}.safeParse(value);
|
|
16
16
|
if (!result.success) {
|
|
17
|
-
result.error.
|
|
17
|
+
result.error.errors.forEach((error) => ctx.addIssue(error))
|
|
18
18
|
}
|
|
19
19
|
})`;
|
|
20
20
|
// Store original if/then/else for JSON Schema round-trip
|
|
@@ -75,16 +75,16 @@ export function parseObject(objectSchema, refs) {
|
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
77
|
if (additionalProperties) {
|
|
78
|
-
patternProperties += `z.record(z.
|
|
78
|
+
patternProperties += `z.record(z.union([${[
|
|
79
79
|
...Object.values(parsedPatternProperties),
|
|
80
80
|
additionalProperties,
|
|
81
81
|
].join(", ")}]))`;
|
|
82
82
|
}
|
|
83
83
|
else if (Object.keys(parsedPatternProperties).length > 1) {
|
|
84
|
-
patternProperties += `z.record(z.
|
|
84
|
+
patternProperties += `z.record(z.union([${Object.values(parsedPatternProperties).join(", ")}]))`;
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
patternProperties += `z.record(
|
|
87
|
+
patternProperties += `z.record(${Object.values(parsedPatternProperties)})`;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
patternProperties += ".superRefine((value, ctx) => {\n";
|
|
@@ -100,8 +100,9 @@ export function parseObject(objectSchema, refs) {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
for (const key in objectSchema.patternProperties) {
|
|
103
|
+
const escapedPattern = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
103
104
|
patternProperties +=
|
|
104
|
-
"if (key.match(new RegExp(" + JSON.stringify(
|
|
105
|
+
"if (key.match(new RegExp(" + JSON.stringify(escapedPattern) + "))) {\n";
|
|
105
106
|
if (additionalProperties) {
|
|
106
107
|
patternProperties += "evaluated = true\n";
|
|
107
108
|
}
|
|
@@ -111,7 +112,7 @@ export function parseObject(objectSchema, refs) {
|
|
|
111
112
|
".safeParse(value[key])\n";
|
|
112
113
|
patternProperties += "if (!result.success) {\n";
|
|
113
114
|
patternProperties += `ctx.addIssue({
|
|
114
|
-
path: [key],
|
|
115
|
+
path: [...ctx.path, key],
|
|
115
116
|
code: 'custom',
|
|
116
117
|
message: \`Invalid input: Key matching regex /\${key}/ must match schema\`,
|
|
117
118
|
params: {
|
|
@@ -127,7 +128,7 @@ export function parseObject(objectSchema, refs) {
|
|
|
127
128
|
"const result = " + additionalProperties + ".safeParse(value[key])\n";
|
|
128
129
|
patternProperties += "if (!result.success) {\n";
|
|
129
130
|
patternProperties += `ctx.addIssue({
|
|
130
|
-
path: [key],
|
|
131
|
+
path: [...ctx.path, key],
|
|
131
132
|
code: 'custom',
|
|
132
133
|
message: \`Invalid input: must match catchall schema\`,
|
|
133
134
|
params: {
|
|
@@ -148,10 +149,10 @@ export function parseObject(objectSchema, refs) {
|
|
|
148
149
|
patternProperties += `.meta({ __jsonSchema: { patternProperties: ${patternPropsJson} } })`;
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
|
-
// Check if there will be an .and() call that adds properties from oneOf/anyOf/allOf
|
|
152
|
+
// Check if there will be an .and() call that adds properties from oneOf/anyOf/allOf/if-then-else
|
|
152
153
|
// In that case, we should NOT use .strict() because it will reject the additional keys
|
|
153
154
|
// before the union gets a chance to validate them.
|
|
154
|
-
const hasCompositionKeywords = its.an.anyOf(objectSchema) || its.a.oneOf(objectSchema) || its.an.allOf(objectSchema);
|
|
155
|
+
const hasCompositionKeywords = its.an.anyOf(objectSchema) || its.a.oneOf(objectSchema) || its.an.allOf(objectSchema) || its.a.conditional(objectSchema);
|
|
155
156
|
let output = properties
|
|
156
157
|
? patternProperties
|
|
157
158
|
? properties + patternProperties
|
|
@@ -166,8 +167,8 @@ export function parseObject(objectSchema, refs) {
|
|
|
166
167
|
: patternProperties
|
|
167
168
|
? patternProperties
|
|
168
169
|
: additionalProperties
|
|
169
|
-
? `z.record(
|
|
170
|
-
: `z.record(
|
|
170
|
+
? `z.record(${additionalProperties})`
|
|
171
|
+
: `z.record(${anyOrUnknown(refs)})`;
|
|
171
172
|
if (unevaluated === false && properties && !hasCompositionKeywords) {
|
|
172
173
|
output += ".strict()";
|
|
173
174
|
}
|
|
@@ -2,24 +2,16 @@ import { parseSchema } from "./parseSchema.js";
|
|
|
2
2
|
import { anyOrUnknown } from "../utils/anyOrUnknown.js";
|
|
3
3
|
export const parseSimpleDiscriminatedOneOf = (schema, refs) => {
|
|
4
4
|
const discriminator = schema.discriminator.propertyName;
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
(discriminatorSchema.enum && discriminatorSchema.enum[0]);
|
|
10
|
-
const parsed = parseSchema(option, {
|
|
11
|
-
...refs,
|
|
12
|
-
path: [...refs.path, "oneOf", i],
|
|
13
|
-
});
|
|
14
|
-
const key = typeof value === "string" ? JSON.stringify(value) : JSON.stringify(String(value));
|
|
15
|
-
return `${key}: ${parsed}`;
|
|
16
|
-
});
|
|
5
|
+
const options = schema.oneOf.map((option, i) => parseSchema(option, {
|
|
6
|
+
...refs,
|
|
7
|
+
path: [...refs.path, "oneOf", i],
|
|
8
|
+
}));
|
|
17
9
|
return schema.oneOf.length
|
|
18
10
|
? schema.oneOf.length === 1
|
|
19
11
|
? parseSchema(schema.oneOf[0], {
|
|
20
12
|
...refs,
|
|
21
13
|
path: [...refs.path, "oneOf", 0],
|
|
22
14
|
})
|
|
23
|
-
: `z.discriminatedUnion("${discriminator}",
|
|
15
|
+
: `z.discriminatedUnion("${discriminator}", [${options.join(", ")}])`
|
|
24
16
|
: anyOrUnknown(refs);
|
|
25
17
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gabrielbryk/json-schema-to-zod",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.3",
|
|
4
4
|
"description": "Converts JSON schema objects or files into Zod schemas",
|
|
5
5
|
"types": "./dist/types/index.d.ts",
|
|
6
6
|
"bin": "./dist/cjs/cli.js",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"access": "public"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
+
"@changesets/cli": "^2.29.8",
|
|
64
65
|
"@types/json-schema": "^7.0.15",
|
|
65
66
|
"@types/node": "^20.9.0",
|
|
66
67
|
"fast-diff": "^1.3.0",
|