@gabrielbryk/json-schema-to-zod 2.10.1 → 2.11.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/AGENTS.md +44 -0
- package/CHANGELOG.md +28 -0
- package/README.md +6 -33
- package/check-types-lift.sh +23 -0
- package/check-types.sh +20 -0
- package/dist/{esm/cli.js → cli.js} +0 -6
- package/dist/{esm/core → core}/analyzeSchema.js +4 -5
- package/dist/core/emitZod.js +263 -0
- package/dist/{esm/generators → generators}/generateBundle.js +26 -13
- package/dist/{esm/index.js → index.js} +6 -0
- package/dist/jsonSchemaToZod.js +17 -0
- package/dist/parsers/parseAllOf.js +125 -0
- package/dist/parsers/parseAnyOf.js +28 -0
- package/dist/{esm/parsers → parsers}/parseArray.js +27 -11
- package/dist/parsers/parseBoolean.js +4 -0
- package/dist/parsers/parseConst.js +22 -0
- package/dist/parsers/parseEnum.js +35 -0
- package/dist/{esm/parsers → parsers}/parseIfThenElse.js +10 -6
- package/dist/parsers/parseMultipleType.js +10 -0
- package/dist/parsers/parseNot.js +14 -0
- package/dist/parsers/parseNull.js +4 -0
- package/dist/parsers/parseNullable.js +12 -0
- package/dist/{esm/parsers → parsers}/parseNumber.js +4 -1
- package/dist/{esm/parsers → parsers}/parseObject.js +167 -31
- package/dist/parsers/parseOneOf.js +365 -0
- package/dist/{esm/parsers → parsers}/parseSchema.js +55 -117
- package/dist/parsers/parseSimpleDiscriminatedOneOf.js +24 -0
- package/dist/{esm/parsers → parsers}/parseString.js +29 -18
- package/dist/types/Types.d.ts +32 -4
- package/dist/types/core/analyzeSchema.d.ts +3 -2
- package/dist/types/generators/generateBundle.d.ts +0 -2
- package/dist/types/index.d.ts +6 -0
- package/dist/types/parsers/parseAllOf.d.ts +2 -2
- package/dist/types/parsers/parseAnyOf.d.ts +2 -2
- package/dist/types/parsers/parseArray.d.ts +2 -2
- package/dist/types/parsers/parseBoolean.d.ts +2 -1
- package/dist/types/parsers/parseConst.d.ts +2 -2
- package/dist/types/parsers/parseDefault.d.ts +2 -2
- package/dist/types/parsers/parseEnum.d.ts +2 -2
- package/dist/types/parsers/parseIfThenElse.d.ts +2 -2
- package/dist/types/parsers/parseMultipleType.d.ts +2 -2
- package/dist/types/parsers/parseNot.d.ts +2 -2
- package/dist/types/parsers/parseNull.d.ts +2 -1
- package/dist/types/parsers/parseNullable.d.ts +2 -2
- package/dist/types/parsers/parseNumber.d.ts +2 -2
- package/dist/types/parsers/parseObject.d.ts +2 -2
- package/dist/types/parsers/parseOneOf.d.ts +2 -2
- package/dist/types/parsers/parseSchema.d.ts +2 -2
- package/dist/types/parsers/parseSimpleDiscriminatedOneOf.d.ts +2 -2
- package/dist/types/parsers/parseString.d.ts +2 -2
- package/dist/types/utils/anyOrUnknown.d.ts +5 -4
- package/dist/types/utils/esmEmitter.d.ts +29 -0
- package/dist/types/utils/extractInlineObject.d.ts +15 -0
- package/dist/types/utils/liftInlineObjects.d.ts +21 -0
- package/dist/types/utils/namingService.d.ts +21 -0
- package/dist/types/utils/resolveRef.d.ts +7 -0
- package/dist/types/utils/schemaRepresentation.d.ts +71 -0
- package/dist/utils/anyOrUnknown.js +13 -0
- package/dist/{esm/utils → utils}/buildRefRegistry.js +4 -0
- package/dist/utils/esmEmitter.js +87 -0
- package/dist/utils/extractInlineObject.js +119 -0
- package/dist/utils/liftInlineObjects.js +476 -0
- package/dist/utils/namingService.js +58 -0
- package/dist/utils/resolveRef.js +92 -0
- package/dist/utils/schemaRepresentation.js +569 -0
- package/docs/IMPROVEMENT-PLAN.md +243 -0
- package/docs/ZOD-V4-RECURSIVE-TYPE-LIMITATIONS.md +292 -0
- package/docs/proposals/bundle-refactor.md +1 -1
- package/docs/proposals/discriminated-union-with-default.md +248 -0
- package/docs/proposals/inline-object-lifting.md +77 -0
- package/eslint.config.js +4 -2
- package/jest.config.mjs +19 -0
- package/package.json +17 -20
- package/scripts/generateWorkflowSchema.ts +0 -1
- package/dist/cjs/Types.js +0 -2
- package/dist/cjs/cli.js +0 -70
- package/dist/cjs/core/analyzeSchema.js +0 -62
- package/dist/cjs/core/emitZod.js +0 -157
- package/dist/cjs/generators/generateBundle.js +0 -510
- package/dist/cjs/index.js +0 -50
- package/dist/cjs/jsonSchemaToZod.js +0 -10
- package/dist/cjs/package.json +0 -1
- package/dist/cjs/parsers/parseAllOf.js +0 -46
- package/dist/cjs/parsers/parseAnyOf.js +0 -18
- package/dist/cjs/parsers/parseArray.js +0 -90
- package/dist/cjs/parsers/parseBoolean.js +0 -5
- package/dist/cjs/parsers/parseConst.js +0 -7
- package/dist/cjs/parsers/parseDefault.js +0 -8
- package/dist/cjs/parsers/parseEnum.js +0 -21
- package/dist/cjs/parsers/parseIfThenElse.js +0 -35
- package/dist/cjs/parsers/parseMultipleType.js +0 -10
- package/dist/cjs/parsers/parseNot.js +0 -12
- package/dist/cjs/parsers/parseNull.js +0 -5
- package/dist/cjs/parsers/parseNullable.js +0 -12
- package/dist/cjs/parsers/parseNumber.js +0 -116
- package/dist/cjs/parsers/parseObject.js +0 -318
- package/dist/cjs/parsers/parseOneOf.js +0 -53
- package/dist/cjs/parsers/parseSchema.js +0 -419
- package/dist/cjs/parsers/parseSimpleDiscriminatedOneOf.js +0 -21
- package/dist/cjs/parsers/parseString.js +0 -317
- package/dist/cjs/utils/anyOrUnknown.js +0 -14
- package/dist/cjs/utils/buildRefRegistry.js +0 -56
- package/dist/cjs/utils/cliTools.js +0 -108
- package/dist/cjs/utils/cycles.js +0 -113
- package/dist/cjs/utils/half.js +0 -7
- package/dist/cjs/utils/jsdocs.js +0 -20
- package/dist/cjs/utils/omit.js +0 -11
- package/dist/cjs/utils/resolveUri.js +0 -16
- package/dist/cjs/utils/withMessage.js +0 -21
- package/dist/cjs/zodToJsonSchema.js +0 -89
- package/dist/esm/core/emitZod.js +0 -153
- package/dist/esm/jsonSchemaToZod.js +0 -6
- package/dist/esm/package.json +0 -1
- package/dist/esm/parsers/parseAllOf.js +0 -43
- package/dist/esm/parsers/parseAnyOf.js +0 -14
- package/dist/esm/parsers/parseBoolean.js +0 -1
- package/dist/esm/parsers/parseConst.js +0 -3
- package/dist/esm/parsers/parseEnum.js +0 -17
- package/dist/esm/parsers/parseMultipleType.js +0 -6
- package/dist/esm/parsers/parseNot.js +0 -8
- package/dist/esm/parsers/parseNull.js +0 -1
- package/dist/esm/parsers/parseNullable.js +0 -8
- package/dist/esm/parsers/parseOneOf.js +0 -49
- package/dist/esm/parsers/parseSimpleDiscriminatedOneOf.js +0 -17
- package/dist/esm/utils/anyOrUnknown.js +0 -10
- package/jest.config.cjs +0 -4
- package/postcjs.cjs +0 -1
- package/postesm.cjs +0 -1
- /package/dist/{esm/Types.js → Types.js} +0 -0
- /package/dist/{esm/parsers → parsers}/parseDefault.js +0 -0
- /package/dist/{esm/utils → utils}/cliTools.js +0 -0
- /package/dist/{esm/utils → utils}/cycles.js +0 -0
- /package/dist/{esm/utils → utils}/half.js +0 -0
- /package/dist/{esm/utils → utils}/jsdocs.js +0 -0
- /package/dist/{esm/utils → utils}/omit.js +0 -0
- /package/dist/{esm/utils → utils}/resolveUri.js +0 -0
- /package/dist/{esm/utils → utils}/withMessage.js +0 -0
- /package/dist/{esm/zodToJsonSchema.js → zodToJsonSchema.js} +0 -0
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.withMessage = withMessage;
|
|
4
|
-
function withMessage(schema, key, get) {
|
|
5
|
-
const value = schema[key];
|
|
6
|
-
let r = "";
|
|
7
|
-
if (value !== undefined) {
|
|
8
|
-
const got = get({ value, json: JSON.stringify(value) });
|
|
9
|
-
if (got) {
|
|
10
|
-
const { opener, closer, messagePrefix = "", messageCloser } = got;
|
|
11
|
-
r += opener;
|
|
12
|
-
if (schema.errorMessage?.[key] !== undefined) {
|
|
13
|
-
r += messagePrefix + JSON.stringify(schema.errorMessage[key]);
|
|
14
|
-
r += messageCloser ?? closer;
|
|
15
|
-
return r;
|
|
16
|
-
}
|
|
17
|
-
r += closer;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return r;
|
|
21
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Post-processor for Zod's z.toJSONSchema() output.
|
|
4
|
-
*
|
|
5
|
-
* When `preserveJsonSchemaForRoundTrip` was used during JSON Schema → Zod conversion,
|
|
6
|
-
* this function reconstructs the original JSON Schema features from the stored __jsonSchema meta.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* 1. Convert JSON Schema to Zod code with `preserveJsonSchemaForRoundTrip: true`
|
|
10
|
-
* 2. Evaluate the Zod code to get a schema instance
|
|
11
|
-
* 3. Call Zod's `z.toJSONSchema(schema)` to get JSON Schema output
|
|
12
|
-
* 4. Pass that output to `reconstructJsonSchema()` to restore preserved features
|
|
13
|
-
*
|
|
14
|
-
* Handles:
|
|
15
|
-
* - patternProperties (stored in __jsonSchema.patternProperties)
|
|
16
|
-
* - if/then/else conditionals (stored in __jsonSchema.conditional)
|
|
17
|
-
*/
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.reconstructJsonSchema = reconstructJsonSchema;
|
|
20
|
-
/**
|
|
21
|
-
* Recursively process a JSON Schema to reconstruct original features from __jsonSchema meta.
|
|
22
|
-
*
|
|
23
|
-
* Handles special cases:
|
|
24
|
-
* - allOf[object, {__jsonSchema: {conditional: ...}}] -> object with if/then/else at top level
|
|
25
|
-
* - patternProperties meta -> patternProperties at current level
|
|
26
|
-
*/
|
|
27
|
-
function reconstructJsonSchema(schema) {
|
|
28
|
-
if (typeof schema !== "object" || schema === null) {
|
|
29
|
-
return schema;
|
|
30
|
-
}
|
|
31
|
-
const result = { ...schema };
|
|
32
|
-
// Handle allOf structures created by .and() with conditionals
|
|
33
|
-
// Pattern: allOf: [mainSchema, {__jsonSchema: {conditional: ...}, anyOf: [...]}]
|
|
34
|
-
if (Array.isArray(result.allOf) &&
|
|
35
|
-
result.allOf.length === 2 &&
|
|
36
|
-
typeof result.allOf[1] === "object" &&
|
|
37
|
-
result.allOf[1] !== null) {
|
|
38
|
-
const secondElement = result.allOf[1];
|
|
39
|
-
// Check if second element has conditional meta
|
|
40
|
-
if (secondElement.__jsonSchema &&
|
|
41
|
-
typeof secondElement.__jsonSchema === "object" &&
|
|
42
|
-
secondElement.__jsonSchema.conditional) {
|
|
43
|
-
// Extract the main schema and conditional
|
|
44
|
-
const mainSchema = reconstructJsonSchema(result.allOf[0]);
|
|
45
|
-
const conditionalMeta = secondElement.__jsonSchema
|
|
46
|
-
.conditional;
|
|
47
|
-
// Merge: main schema + if/then/else at top level
|
|
48
|
-
const merged = {
|
|
49
|
-
...mainSchema,
|
|
50
|
-
if: conditionalMeta.if,
|
|
51
|
-
then: conditionalMeta.then,
|
|
52
|
-
else: conditionalMeta.else,
|
|
53
|
-
};
|
|
54
|
-
// Recursively process the merged result
|
|
55
|
-
return reconstructJsonSchema(merged);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// Check for __jsonSchema meta at this level
|
|
59
|
-
if (result.__jsonSchema && typeof result.__jsonSchema === "object") {
|
|
60
|
-
const preserved = result.__jsonSchema;
|
|
61
|
-
// Reconstruct patternProperties
|
|
62
|
-
if (preserved.patternProperties) {
|
|
63
|
-
result.patternProperties = preserved.patternProperties;
|
|
64
|
-
}
|
|
65
|
-
// Reconstruct if/then/else conditional (for non-allOf cases)
|
|
66
|
-
if (preserved.conditional) {
|
|
67
|
-
const conditional = preserved.conditional;
|
|
68
|
-
result.if = conditional.if;
|
|
69
|
-
result.then = conditional.then;
|
|
70
|
-
result.else = conditional.else;
|
|
71
|
-
}
|
|
72
|
-
// Remove the __jsonSchema meta from the output
|
|
73
|
-
delete result.__jsonSchema;
|
|
74
|
-
}
|
|
75
|
-
// Recursively process nested schemas
|
|
76
|
-
for (const [key, value] of Object.entries(result)) {
|
|
77
|
-
if (typeof value === "object" && value !== null) {
|
|
78
|
-
if (Array.isArray(value)) {
|
|
79
|
-
result[key] = value.map((item) => typeof item === "object" && item !== null
|
|
80
|
-
? reconstructJsonSchema(item)
|
|
81
|
-
: item);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
result[key] = reconstructJsonSchema(value);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return result;
|
|
89
|
-
}
|
package/dist/esm/core/emitZod.js
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { parseSchema } from "../parsers/parseSchema.js";
|
|
2
|
-
import { expandJsdocs } from "../utils/jsdocs.js";
|
|
3
|
-
const orderDeclarations = (entries, dependencies) => {
|
|
4
|
-
const valueByName = new Map(entries);
|
|
5
|
-
const depGraph = new Map();
|
|
6
|
-
for (const [from, set] of dependencies.entries()) {
|
|
7
|
-
const onlyKnown = new Set();
|
|
8
|
-
for (const dep of set) {
|
|
9
|
-
if (valueByName.has(dep) && dep !== from) {
|
|
10
|
-
onlyKnown.add(dep);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
if (onlyKnown.size)
|
|
14
|
-
depGraph.set(from, onlyKnown);
|
|
15
|
-
}
|
|
16
|
-
const names = Array.from(valueByName.keys());
|
|
17
|
-
for (const [name, value] of entries) {
|
|
18
|
-
const deps = depGraph.get(name) ?? new Set();
|
|
19
|
-
for (const candidate of names) {
|
|
20
|
-
if (candidate === name)
|
|
21
|
-
continue;
|
|
22
|
-
const matcher = new RegExp(`\\b${candidate}\\b`);
|
|
23
|
-
if (matcher.test(value)) {
|
|
24
|
-
deps.add(candidate);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
if (deps.size)
|
|
28
|
-
depGraph.set(name, deps);
|
|
29
|
-
}
|
|
30
|
-
const ordered = [];
|
|
31
|
-
const perm = new Set();
|
|
32
|
-
const temp = new Set();
|
|
33
|
-
const visit = (name) => {
|
|
34
|
-
if (perm.has(name))
|
|
35
|
-
return;
|
|
36
|
-
if (temp.has(name)) {
|
|
37
|
-
temp.delete(name);
|
|
38
|
-
perm.add(name);
|
|
39
|
-
ordered.push(name);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
temp.add(name);
|
|
43
|
-
const deps = depGraph.get(name);
|
|
44
|
-
if (deps) {
|
|
45
|
-
for (const dep of deps) {
|
|
46
|
-
if (valueByName.has(dep)) {
|
|
47
|
-
visit(dep);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
temp.delete(name);
|
|
52
|
-
perm.add(name);
|
|
53
|
-
ordered.push(name);
|
|
54
|
-
};
|
|
55
|
-
for (const name of valueByName.keys()) {
|
|
56
|
-
visit(name);
|
|
57
|
-
}
|
|
58
|
-
const unique = [];
|
|
59
|
-
const seen = new Set();
|
|
60
|
-
for (const name of ordered) {
|
|
61
|
-
if (!seen.has(name)) {
|
|
62
|
-
seen.add(name);
|
|
63
|
-
unique.push(name);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return unique.map((name) => [name, valueByName.get(name)]);
|
|
67
|
-
};
|
|
68
|
-
export const emitZod = (analysis) => {
|
|
69
|
-
const { schema, options, refNameByPointer, usedNames, cycleRefNames, cycleComponentByName, } = analysis;
|
|
70
|
-
const { module, name, type, noImport, exportRefs, withMeta, ...rest } = options;
|
|
71
|
-
const declarations = new Map();
|
|
72
|
-
const dependencies = new Map();
|
|
73
|
-
const reserveName = (base) => {
|
|
74
|
-
let candidate = base;
|
|
75
|
-
let i = 1;
|
|
76
|
-
while (usedNames.has(candidate) || declarations.has(candidate)) {
|
|
77
|
-
candidate = `${base}${i}`;
|
|
78
|
-
i += 1;
|
|
79
|
-
}
|
|
80
|
-
usedNames.add(candidate);
|
|
81
|
-
return candidate;
|
|
82
|
-
};
|
|
83
|
-
const parsedSchema = parseSchema(schema, {
|
|
84
|
-
module,
|
|
85
|
-
name,
|
|
86
|
-
path: [],
|
|
87
|
-
seen: new Map(),
|
|
88
|
-
declarations,
|
|
89
|
-
dependencies,
|
|
90
|
-
inProgress: new Set(),
|
|
91
|
-
refNameByPointer,
|
|
92
|
-
usedNames,
|
|
93
|
-
root: schema,
|
|
94
|
-
currentSchemaName: name,
|
|
95
|
-
cycleRefNames,
|
|
96
|
-
cycleComponentByName,
|
|
97
|
-
refRegistry: analysis.refRegistry,
|
|
98
|
-
rootBaseUri: analysis.rootBaseUri,
|
|
99
|
-
...rest,
|
|
100
|
-
withMeta,
|
|
101
|
-
});
|
|
102
|
-
const declarationBlock = declarations.size
|
|
103
|
-
? orderDeclarations(Array.from(declarations.entries()), dependencies)
|
|
104
|
-
.flatMap(([refName, value]) => {
|
|
105
|
-
const shouldExport = exportRefs && module === "esm";
|
|
106
|
-
const isCycle = cycleRefNames.has(refName);
|
|
107
|
-
if (!isCycle) {
|
|
108
|
-
return [`${shouldExport ? "export " : ""}const ${refName} = ${value}`];
|
|
109
|
-
}
|
|
110
|
-
const baseName = `${refName}Def`;
|
|
111
|
-
const lines = [`const ${baseName} = ${value}`];
|
|
112
|
-
lines.push(`${shouldExport ? "export " : ""}const ${refName} = ${baseName}`);
|
|
113
|
-
return lines;
|
|
114
|
-
})
|
|
115
|
-
.join("\n")
|
|
116
|
-
: "";
|
|
117
|
-
const jsdocs = rest.withJsdocs && typeof schema === "object" && schema !== null && "description" in schema
|
|
118
|
-
? expandJsdocs(String(schema.description ?? ""))
|
|
119
|
-
: "";
|
|
120
|
-
const lines = [];
|
|
121
|
-
if (module === "cjs" && !noImport) {
|
|
122
|
-
lines.push(`const { z } = require("zod")`);
|
|
123
|
-
}
|
|
124
|
-
if (module === "esm" && !noImport) {
|
|
125
|
-
lines.push(`import { z } from "zod"`);
|
|
126
|
-
}
|
|
127
|
-
if (declarationBlock) {
|
|
128
|
-
lines.push(declarationBlock);
|
|
129
|
-
}
|
|
130
|
-
if (module === "cjs") {
|
|
131
|
-
const payload = name ? `{ ${JSON.stringify(name)}: ${parsedSchema} }` : parsedSchema;
|
|
132
|
-
lines.push(`${jsdocs}module.exports = ${payload}`);
|
|
133
|
-
}
|
|
134
|
-
else if (module === "esm") {
|
|
135
|
-
const exportLine = `${jsdocs}export ${name ? `const ${name} =` : `default`} ${parsedSchema}`;
|
|
136
|
-
lines.push(exportLine);
|
|
137
|
-
}
|
|
138
|
-
else if (name) {
|
|
139
|
-
lines.push(`${jsdocs}const ${name} = ${parsedSchema}`);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
lines.push(`${jsdocs}${parsedSchema}`);
|
|
143
|
-
}
|
|
144
|
-
let typeLine;
|
|
145
|
-
if (type && name) {
|
|
146
|
-
const typeName = typeof type === "string" ? type : `${name[0].toUpperCase()}${name.substring(1)}`;
|
|
147
|
-
typeLine = `export type ${typeName} = z.infer<typeof ${name}>`;
|
|
148
|
-
}
|
|
149
|
-
const joined = lines.filter(Boolean).join("\n\n");
|
|
150
|
-
const combined = typeLine ? `${joined}\n${typeLine}` : joined;
|
|
151
|
-
const shouldEndWithNewline = module === "esm" || module === "cjs";
|
|
152
|
-
return `${combined}${shouldEndWithNewline ? "\n" : ""}`;
|
|
153
|
-
};
|
package/dist/esm/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"type":"module"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { parseSchema } from "./parseSchema.js";
|
|
2
|
-
import { half } from "../utils/half.js";
|
|
3
|
-
const originalIndexKey = "__originalIndex";
|
|
4
|
-
const ensureOriginalIndex = (arr) => {
|
|
5
|
-
const newArr = [];
|
|
6
|
-
for (let i = 0; i < arr.length; i++) {
|
|
7
|
-
const item = arr[i];
|
|
8
|
-
if (typeof item === "boolean") {
|
|
9
|
-
newArr.push(item ? { [originalIndexKey]: i } : { [originalIndexKey]: i, not: {} });
|
|
10
|
-
}
|
|
11
|
-
else if (typeof item === "object" &&
|
|
12
|
-
item !== null &&
|
|
13
|
-
originalIndexKey in item) {
|
|
14
|
-
return arr;
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
newArr.push({ ...item, [originalIndexKey]: i });
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return newArr;
|
|
21
|
-
};
|
|
22
|
-
export function parseAllOf(schema, refs) {
|
|
23
|
-
if (schema.allOf.length === 0) {
|
|
24
|
-
return "z.never()";
|
|
25
|
-
}
|
|
26
|
-
else if (schema.allOf.length === 1) {
|
|
27
|
-
const item = schema.allOf[0];
|
|
28
|
-
return parseSchema(item, {
|
|
29
|
-
...refs,
|
|
30
|
-
path: [
|
|
31
|
-
...refs.path,
|
|
32
|
-
"allOf",
|
|
33
|
-
item[originalIndexKey] ?? 0,
|
|
34
|
-
],
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
const [left, right] = half(ensureOriginalIndex(schema.allOf));
|
|
39
|
-
return `z.intersection(${parseAllOf({ allOf: left }, refs)}, ${parseAllOf({
|
|
40
|
-
allOf: right,
|
|
41
|
-
}, refs)})`;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { parseSchema } from "./parseSchema.js";
|
|
2
|
-
import { anyOrUnknown } from "../utils/anyOrUnknown.js";
|
|
3
|
-
export const parseAnyOf = (schema, refs) => {
|
|
4
|
-
return schema.anyOf.length
|
|
5
|
-
? schema.anyOf.length === 1
|
|
6
|
-
? parseSchema(schema.anyOf[0], {
|
|
7
|
-
...refs,
|
|
8
|
-
path: [...refs.path, "anyOf", 0],
|
|
9
|
-
})
|
|
10
|
-
: `z.union([${schema.anyOf
|
|
11
|
-
.map((schema, i) => parseSchema(schema, { ...refs, path: [...refs.path, "anyOf", i] }))
|
|
12
|
-
.join(", ")}])`
|
|
13
|
-
: anyOrUnknown(refs);
|
|
14
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const parseBoolean = () => "z.boolean()";
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const parseEnum = (schema) => {
|
|
2
|
-
if (schema.enum.length === 0) {
|
|
3
|
-
return "z.never()";
|
|
4
|
-
}
|
|
5
|
-
else if (schema.enum.length === 1) {
|
|
6
|
-
// union does not work when there is only one element
|
|
7
|
-
return `z.literal(${JSON.stringify(schema.enum[0])})`;
|
|
8
|
-
}
|
|
9
|
-
else if (schema.enum.every((x) => typeof x === "string")) {
|
|
10
|
-
return `z.enum([${schema.enum.map((x) => JSON.stringify(x))}])`;
|
|
11
|
-
}
|
|
12
|
-
else {
|
|
13
|
-
return `z.union([${schema.enum
|
|
14
|
-
.map((x) => `z.literal(${JSON.stringify(x)})`)
|
|
15
|
-
.join(", ")}])`;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { parseSchema } from "./parseSchema.js";
|
|
2
|
-
import { anyOrUnknown } from "../utils/anyOrUnknown.js";
|
|
3
|
-
export const parseNot = (schema, refs) => {
|
|
4
|
-
return `${anyOrUnknown(refs)}.refine((value) => !${parseSchema(schema.not, {
|
|
5
|
-
...refs,
|
|
6
|
-
path: [...refs.path, "not"],
|
|
7
|
-
})}.safeParse(value).success, "Invalid input: Should NOT be valid against schema")`;
|
|
8
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const parseNull = () => "z.null()";
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { omit } from "../utils/omit.js";
|
|
2
|
-
import { parseSchema } from "./parseSchema.js";
|
|
3
|
-
/**
|
|
4
|
-
* For compatibility with open api 3.0 nullable
|
|
5
|
-
*/
|
|
6
|
-
export const parseNullable = (schema, refs) => {
|
|
7
|
-
return `${parseSchema(omit(schema, "nullable"), refs, true)}.nullable()`;
|
|
8
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { parseSchema } from "./parseSchema.js";
|
|
2
|
-
import { anyOrUnknown } from "../utils/anyOrUnknown.js";
|
|
3
|
-
export const parseOneOf = (schema, refs) => {
|
|
4
|
-
if (!schema.oneOf.length) {
|
|
5
|
-
return anyOrUnknown(refs);
|
|
6
|
-
}
|
|
7
|
-
if (schema.oneOf.length === 1) {
|
|
8
|
-
return parseSchema(schema.oneOf[0], {
|
|
9
|
-
...refs,
|
|
10
|
-
path: [...refs.path, "oneOf", 0],
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
// Generate parsed schemas for each oneOf option
|
|
14
|
-
const parsedSchemas = schema.oneOf.map((s, i) => parseSchema(s, {
|
|
15
|
-
...refs,
|
|
16
|
-
path: [...refs.path, "oneOf", i],
|
|
17
|
-
}));
|
|
18
|
-
// JSON Schema oneOf = exactly one must match (exclusive OR)
|
|
19
|
-
// Zod union = at least one must match (inclusive OR)
|
|
20
|
-
//
|
|
21
|
-
// By default, use simple z.union() which provides "at least one must match".
|
|
22
|
-
// This is more practical for most use cases, as strict oneOf enforcement
|
|
23
|
-
// often fails when schemas have overlapping base types.
|
|
24
|
-
//
|
|
25
|
-
// If strictOneOf is enabled, add superRefine to enforce "exactly one" constraint.
|
|
26
|
-
if (refs.strictOneOf) {
|
|
27
|
-
return `z.union([${parsedSchemas.join(", ")}]).superRefine((x, ctx) => {
|
|
28
|
-
const schemas = [${parsedSchemas.join(", ")}];
|
|
29
|
-
const errors = schemas.reduce<z.ZodError[]>(
|
|
30
|
-
(errors, schema) =>
|
|
31
|
-
((result) =>
|
|
32
|
-
result.error ? [...errors, result.error] : errors)(
|
|
33
|
-
schema.safeParse(x),
|
|
34
|
-
),
|
|
35
|
-
[],
|
|
36
|
-
);
|
|
37
|
-
if (schemas.length - errors.length !== 1) {
|
|
38
|
-
ctx.addIssue({
|
|
39
|
-
path: [],
|
|
40
|
-
code: "invalid_union",
|
|
41
|
-
errors: errors.map(e => e.issues),
|
|
42
|
-
message: "Invalid input: Should pass single schema",
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
})`;
|
|
46
|
-
}
|
|
47
|
-
// Default: use simple z.union() (at least one must match)
|
|
48
|
-
return `z.union([${parsedSchemas.join(", ")}])`;
|
|
49
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { parseSchema } from "./parseSchema.js";
|
|
2
|
-
import { anyOrUnknown } from "../utils/anyOrUnknown.js";
|
|
3
|
-
export const parseSimpleDiscriminatedOneOf = (schema, refs) => {
|
|
4
|
-
const discriminator = schema.discriminator.propertyName;
|
|
5
|
-
const options = schema.oneOf.map((option, i) => parseSchema(option, {
|
|
6
|
-
...refs,
|
|
7
|
-
path: [...refs.path, "oneOf", i],
|
|
8
|
-
}));
|
|
9
|
-
return schema.oneOf.length
|
|
10
|
-
? schema.oneOf.length === 1
|
|
11
|
-
? parseSchema(schema.oneOf[0], {
|
|
12
|
-
...refs,
|
|
13
|
-
path: [...refs.path, "oneOf", 0],
|
|
14
|
-
})
|
|
15
|
-
: `z.discriminatedUnion("${discriminator}", [${options.join(", ")}])`
|
|
16
|
-
: anyOrUnknown(refs);
|
|
17
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns "z.unknown()" if the useUnknown option is enabled, otherwise "z.any()".
|
|
3
|
-
* This helper is used throughout the library for fallback cases.
|
|
4
|
-
*
|
|
5
|
-
* @param refs - The refs object containing options
|
|
6
|
-
* @returns The appropriate Zod schema string
|
|
7
|
-
*/
|
|
8
|
-
export const anyOrUnknown = (refs) => {
|
|
9
|
-
return refs?.useUnknown ? "z.unknown()" : "z.any()";
|
|
10
|
-
};
|
package/jest.config.cjs
DELETED
package/postcjs.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require("fs").writeFileSync("./dist/cjs/package.json", '{"type":"commonjs"}', "utf-8")
|
package/postesm.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require("fs").writeFileSync("./dist/esm/package.json", '{"type":"module"}', "utf-8")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|