@gabrielbryk/json-schema-to-zod 2.10.1 → 2.11.1
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 +38 -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 +200 -37
- 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,419 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.its = exports.parseSchema = void 0;
|
|
4
|
-
const parseAnyOf_js_1 = require("./parseAnyOf.js");
|
|
5
|
-
const parseBoolean_js_1 = require("./parseBoolean.js");
|
|
6
|
-
const parseDefault_js_1 = require("./parseDefault.js");
|
|
7
|
-
const parseMultipleType_js_1 = require("./parseMultipleType.js");
|
|
8
|
-
const parseNot_js_1 = require("./parseNot.js");
|
|
9
|
-
const parseNull_js_1 = require("./parseNull.js");
|
|
10
|
-
const parseAllOf_js_1 = require("./parseAllOf.js");
|
|
11
|
-
const parseArray_js_1 = require("./parseArray.js");
|
|
12
|
-
const parseConst_js_1 = require("./parseConst.js");
|
|
13
|
-
const parseEnum_js_1 = require("./parseEnum.js");
|
|
14
|
-
const parseIfThenElse_js_1 = require("./parseIfThenElse.js");
|
|
15
|
-
const parseNumber_js_1 = require("./parseNumber.js");
|
|
16
|
-
const parseObject_js_1 = require("./parseObject.js");
|
|
17
|
-
const parseString_js_1 = require("./parseString.js");
|
|
18
|
-
const parseOneOf_js_1 = require("./parseOneOf.js");
|
|
19
|
-
const parseSimpleDiscriminatedOneOf_js_1 = require("./parseSimpleDiscriminatedOneOf.js");
|
|
20
|
-
const parseNullable_js_1 = require("./parseNullable.js");
|
|
21
|
-
const anyOrUnknown_js_1 = require("../utils/anyOrUnknown.js");
|
|
22
|
-
const resolveUri_js_1 = require("../utils/resolveUri.js");
|
|
23
|
-
const buildRefRegistry_js_1 = require("../utils/buildRefRegistry.js");
|
|
24
|
-
const parseSchema = (schema, refs = { seen: new Map(), path: [] }, blockMeta) => {
|
|
25
|
-
// Ensure ref bookkeeping exists so $ref declarations and getter-based recursion work
|
|
26
|
-
refs.root = refs.root ?? schema;
|
|
27
|
-
refs.rootBaseUri = refs.rootBaseUri ?? "root:///";
|
|
28
|
-
refs.declarations = refs.declarations ?? new Map();
|
|
29
|
-
refs.dependencies = refs.dependencies ?? new Map();
|
|
30
|
-
refs.inProgress = refs.inProgress ?? new Set();
|
|
31
|
-
refs.refNameByPointer = refs.refNameByPointer ?? new Map();
|
|
32
|
-
refs.usedNames = refs.usedNames ?? new Set();
|
|
33
|
-
if (typeof schema !== "object")
|
|
34
|
-
return schema ? (0, anyOrUnknown_js_1.anyOrUnknown)(refs) : "z.never()";
|
|
35
|
-
const parentBase = refs.currentBaseUri ?? refs.rootBaseUri ?? "root:///";
|
|
36
|
-
const baseUri = typeof schema.$id === "string" ? (0, resolveUri_js_1.resolveUri)(parentBase, schema.$id) : parentBase;
|
|
37
|
-
const dynamicAnchors = Array.isArray(refs.dynamicAnchors) ? [...refs.dynamicAnchors] : [];
|
|
38
|
-
if (typeof schema.$dynamicAnchor === "string") {
|
|
39
|
-
dynamicAnchors.push({
|
|
40
|
-
name: schema.$dynamicAnchor,
|
|
41
|
-
uri: baseUri,
|
|
42
|
-
path: refs.path,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
if (refs.parserOverride) {
|
|
46
|
-
const custom = refs.parserOverride(schema, { ...refs, currentBaseUri: baseUri, dynamicAnchors });
|
|
47
|
-
if (typeof custom === "string") {
|
|
48
|
-
return custom;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
let seen = refs.seen.get(schema);
|
|
52
|
-
if (seen) {
|
|
53
|
-
if (seen.r !== undefined) {
|
|
54
|
-
return seen.r;
|
|
55
|
-
}
|
|
56
|
-
if (refs.depth === undefined || seen.n >= refs.depth) {
|
|
57
|
-
return (0, anyOrUnknown_js_1.anyOrUnknown)(refs);
|
|
58
|
-
}
|
|
59
|
-
seen.n += 1;
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
seen = { r: undefined, n: 0 };
|
|
63
|
-
refs.seen.set(schema, seen);
|
|
64
|
-
}
|
|
65
|
-
if (exports.its.a.ref(schema)) {
|
|
66
|
-
const parsedRef = parseRef(schema, { ...refs, currentBaseUri: baseUri, dynamicAnchors });
|
|
67
|
-
seen.r = parsedRef;
|
|
68
|
-
return parsedRef;
|
|
69
|
-
}
|
|
70
|
-
let parsed = selectParser(schema, { ...refs, currentBaseUri: baseUri, dynamicAnchors });
|
|
71
|
-
if (!blockMeta) {
|
|
72
|
-
if (!refs.withoutDescribes) {
|
|
73
|
-
parsed = addDescribes(schema, parsed, { ...refs, currentBaseUri: baseUri, dynamicAnchors });
|
|
74
|
-
}
|
|
75
|
-
if (!refs.withoutDefaults) {
|
|
76
|
-
parsed = addDefaults(schema, parsed);
|
|
77
|
-
}
|
|
78
|
-
parsed = addAnnotations(schema, parsed);
|
|
79
|
-
}
|
|
80
|
-
seen.r = parsed;
|
|
81
|
-
return parsed;
|
|
82
|
-
};
|
|
83
|
-
exports.parseSchema = parseSchema;
|
|
84
|
-
const parseRef = (schema, refs) => {
|
|
85
|
-
const refValue = schema.$dynamicRef ?? schema.$ref;
|
|
86
|
-
if (typeof refValue !== "string") {
|
|
87
|
-
return (0, anyOrUnknown_js_1.anyOrUnknown)(refs);
|
|
88
|
-
}
|
|
89
|
-
const resolved = resolveRef(schema, refValue, refs);
|
|
90
|
-
if (!resolved) {
|
|
91
|
-
refs.onUnresolvedRef?.(refValue, refs.path);
|
|
92
|
-
return (0, anyOrUnknown_js_1.anyOrUnknown)(refs);
|
|
93
|
-
}
|
|
94
|
-
const { schema: target, path, pointerKey } = resolved;
|
|
95
|
-
const refName = getOrCreateRefName(pointerKey, path, refs);
|
|
96
|
-
if (!refs.declarations.has(refName) && !refs.inProgress.has(refName)) {
|
|
97
|
-
refs.inProgress.add(refName);
|
|
98
|
-
const declaration = (0, exports.parseSchema)(target, {
|
|
99
|
-
...refs,
|
|
100
|
-
path,
|
|
101
|
-
currentBaseUri: resolved.baseUri,
|
|
102
|
-
currentSchemaName: refName,
|
|
103
|
-
root: refs.root,
|
|
104
|
-
});
|
|
105
|
-
refs.inProgress.delete(refName);
|
|
106
|
-
refs.declarations.set(refName, declaration);
|
|
107
|
-
}
|
|
108
|
-
const current = refs.currentSchemaName;
|
|
109
|
-
if (current) {
|
|
110
|
-
const deps = refs.dependencies;
|
|
111
|
-
const set = deps.get(current) ?? new Set();
|
|
112
|
-
set.add(refName);
|
|
113
|
-
deps.set(current, set);
|
|
114
|
-
}
|
|
115
|
-
const currentComponent = refs.currentSchemaName
|
|
116
|
-
? refs.cycleComponentByName?.get(refs.currentSchemaName)
|
|
117
|
-
: undefined;
|
|
118
|
-
const targetComponent = refs.cycleComponentByName?.get(refName);
|
|
119
|
-
const isSameCycle = currentComponent !== undefined &&
|
|
120
|
-
targetComponent !== undefined &&
|
|
121
|
-
currentComponent === targetComponent &&
|
|
122
|
-
refs.cycleRefNames?.has(refName);
|
|
123
|
-
// Only lazy if the ref stays inside the current strongly-connected component
|
|
124
|
-
// (or is currently being resolved). This avoids TDZ on true cycles while
|
|
125
|
-
// letting ordered, acyclic refs stay direct.
|
|
126
|
-
if (isSameCycle || refs.inProgress.has(refName)) {
|
|
127
|
-
const inObjectProperty = refs.path.includes("properties") ||
|
|
128
|
-
refs.path.includes("patternProperties") ||
|
|
129
|
-
refs.path.includes("additionalProperties");
|
|
130
|
-
if (inObjectProperty && refName === refs.currentSchemaName) {
|
|
131
|
-
// Getter properties defer evaluation, so a direct reference avoids extra lazies
|
|
132
|
-
// for self-recursion.
|
|
133
|
-
return refName;
|
|
134
|
-
}
|
|
135
|
-
return `z.lazy(() => ${refName})`;
|
|
136
|
-
}
|
|
137
|
-
return refName;
|
|
138
|
-
};
|
|
139
|
-
const addDescribes = (schema, parsed, refs) => {
|
|
140
|
-
// Use .meta() for richer metadata when withMeta is enabled
|
|
141
|
-
if (refs?.withMeta) {
|
|
142
|
-
const meta = {};
|
|
143
|
-
if (schema.$id)
|
|
144
|
-
meta.id = schema.$id;
|
|
145
|
-
if (schema.title)
|
|
146
|
-
meta.title = schema.title;
|
|
147
|
-
if (schema.description)
|
|
148
|
-
meta.description = schema.description;
|
|
149
|
-
if (schema.examples)
|
|
150
|
-
meta.examples = schema.examples;
|
|
151
|
-
if (schema.deprecated)
|
|
152
|
-
meta.deprecated = schema.deprecated;
|
|
153
|
-
if (Object.keys(meta).length > 0) {
|
|
154
|
-
parsed += `.meta(${JSON.stringify(meta)})`;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else if (schema.description) {
|
|
158
|
-
parsed += `.describe(${JSON.stringify(schema.description)})`;
|
|
159
|
-
}
|
|
160
|
-
return parsed;
|
|
161
|
-
};
|
|
162
|
-
const resolveRef = (schemaNode, ref, refs) => {
|
|
163
|
-
const base = refs.currentBaseUri ?? refs.rootBaseUri ?? "root:///";
|
|
164
|
-
// Handle dynamicRef lookup via dynamicAnchors stack
|
|
165
|
-
const isDynamic = typeof schemaNode.$dynamicRef === "string";
|
|
166
|
-
if (isDynamic && refs.dynamicAnchors && ref.startsWith("#")) {
|
|
167
|
-
const name = ref.slice(1);
|
|
168
|
-
for (let i = refs.dynamicAnchors.length - 1; i >= 0; i -= 1) {
|
|
169
|
-
const entry = refs.dynamicAnchors[i];
|
|
170
|
-
if (entry.name === name) {
|
|
171
|
-
const key = `${entry.uri}#${name}`;
|
|
172
|
-
const target = refs.refRegistry?.get(key);
|
|
173
|
-
if (target) {
|
|
174
|
-
return { schema: target.schema, path: target.path, baseUri: target.baseUri, pointerKey: key };
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
// Resolve URI against base
|
|
180
|
-
const resolvedUri = (0, resolveUri_js_1.resolveUri)(base, ref);
|
|
181
|
-
const [uriBase, fragment] = resolvedUri.split("#");
|
|
182
|
-
const key = fragment ? `${uriBase}#${fragment}` : uriBase;
|
|
183
|
-
let regEntry = refs.refRegistry?.get(key);
|
|
184
|
-
if (regEntry) {
|
|
185
|
-
return { schema: regEntry.schema, path: regEntry.path, baseUri: regEntry.baseUri, pointerKey: key };
|
|
186
|
-
}
|
|
187
|
-
// Legacy recursive ref: treat as dynamic to __recursive__
|
|
188
|
-
if (schemaNode.$recursiveRef) {
|
|
189
|
-
const recursiveKey = `${base}#__recursive__`;
|
|
190
|
-
regEntry = refs.refRegistry?.get(recursiveKey);
|
|
191
|
-
if (regEntry) {
|
|
192
|
-
return {
|
|
193
|
-
schema: regEntry.schema,
|
|
194
|
-
path: regEntry.path,
|
|
195
|
-
baseUri: regEntry.baseUri,
|
|
196
|
-
pointerKey: recursiveKey,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
// External resolver hook
|
|
201
|
-
const extBase = uriBaseFromRef(resolvedUri);
|
|
202
|
-
if (refs.resolveExternalRef && extBase && !isLocalBase(extBase, refs.rootBaseUri ?? "")) {
|
|
203
|
-
const loaded = refs.resolveExternalRef(extBase);
|
|
204
|
-
if (loaded) {
|
|
205
|
-
// If async resolver is used synchronously here, it will be ignored; keep simple sync for now
|
|
206
|
-
const maybePromise = loaded;
|
|
207
|
-
const schema = typeof maybePromise.then === "function"
|
|
208
|
-
? undefined
|
|
209
|
-
: loaded;
|
|
210
|
-
if (schema) {
|
|
211
|
-
const { registry } = (0, buildRefRegistry_js_1.buildRefRegistry)(schema, extBase);
|
|
212
|
-
registry.forEach((entry, k) => refs.refRegistry?.set(k, entry));
|
|
213
|
-
regEntry = refs.refRegistry?.get(key);
|
|
214
|
-
if (regEntry) {
|
|
215
|
-
return {
|
|
216
|
-
schema: regEntry.schema,
|
|
217
|
-
path: regEntry.path,
|
|
218
|
-
baseUri: regEntry.baseUri,
|
|
219
|
-
pointerKey: key,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
// Backward compatibility: JSON Pointer into root
|
|
226
|
-
if (refs.root && ref.startsWith("#/")) {
|
|
227
|
-
const rawSegments = ref
|
|
228
|
-
.slice(2)
|
|
229
|
-
.split("/")
|
|
230
|
-
.filter((segment) => segment.length > 0)
|
|
231
|
-
.map(decodePointerSegment);
|
|
232
|
-
let current = refs.root;
|
|
233
|
-
for (const segment of rawSegments) {
|
|
234
|
-
if (typeof current !== "object" || current === null)
|
|
235
|
-
return undefined;
|
|
236
|
-
current = current[segment];
|
|
237
|
-
}
|
|
238
|
-
return { schema: current, path: rawSegments, baseUri: base, pointerKey: ref };
|
|
239
|
-
}
|
|
240
|
-
return undefined;
|
|
241
|
-
};
|
|
242
|
-
const decodePointerSegment = (segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
243
|
-
const uriBaseFromRef = (resolvedUri) => {
|
|
244
|
-
const hashIdx = resolvedUri.indexOf("#");
|
|
245
|
-
return hashIdx === -1 ? resolvedUri : resolvedUri.slice(0, hashIdx);
|
|
246
|
-
};
|
|
247
|
-
const isLocalBase = (base, rootBase) => {
|
|
248
|
-
if (!rootBase)
|
|
249
|
-
return false;
|
|
250
|
-
return base === rootBase;
|
|
251
|
-
};
|
|
252
|
-
const getOrCreateRefName = (pointer, path, refs) => {
|
|
253
|
-
if (refs.refNameByPointer?.has(pointer)) {
|
|
254
|
-
return refs.refNameByPointer.get(pointer);
|
|
255
|
-
}
|
|
256
|
-
const preferred = buildNameFromPath(path, refs.usedNames);
|
|
257
|
-
refs.refNameByPointer?.set(pointer, preferred);
|
|
258
|
-
refs.usedNames?.add(preferred);
|
|
259
|
-
return preferred;
|
|
260
|
-
};
|
|
261
|
-
const buildNameFromPath = (path, used) => {
|
|
262
|
-
const filtered = path
|
|
263
|
-
.map((segment, idx) => {
|
|
264
|
-
if (idx === 0 && (segment === "$defs" || segment === "definitions")) {
|
|
265
|
-
return undefined; // root-level defs prefix is redundant for naming
|
|
266
|
-
}
|
|
267
|
-
if (segment === "properties")
|
|
268
|
-
return undefined; // skip noisy properties segment
|
|
269
|
-
if (segment === "$defs" || segment === "definitions")
|
|
270
|
-
return "Defs";
|
|
271
|
-
return segment;
|
|
272
|
-
})
|
|
273
|
-
.filter((segment) => segment !== undefined);
|
|
274
|
-
const base = filtered.length
|
|
275
|
-
? filtered
|
|
276
|
-
.map((segment) => typeof segment === "number"
|
|
277
|
-
? `Ref${segment}`
|
|
278
|
-
: segment
|
|
279
|
-
.toString()
|
|
280
|
-
.replace(/[^a-zA-Z0-9_$]/g, " ")
|
|
281
|
-
.split(" ")
|
|
282
|
-
.filter(Boolean)
|
|
283
|
-
.map(capitalize)
|
|
284
|
-
.join(""))
|
|
285
|
-
.join("")
|
|
286
|
-
: "Ref";
|
|
287
|
-
const sanitized = sanitizeIdentifier(base || "Ref");
|
|
288
|
-
if (!used || !used.has(sanitized))
|
|
289
|
-
return sanitized;
|
|
290
|
-
let counter = 2;
|
|
291
|
-
let candidate = `${sanitized}${counter}`;
|
|
292
|
-
while (used.has(candidate)) {
|
|
293
|
-
counter += 1;
|
|
294
|
-
candidate = `${sanitized}${counter}`;
|
|
295
|
-
}
|
|
296
|
-
return candidate;
|
|
297
|
-
};
|
|
298
|
-
const sanitizeIdentifier = (value) => {
|
|
299
|
-
const cleaned = value.replace(/^[^a-zA-Z_$]+/, "").replace(/[^a-zA-Z0-9_$]/g, "");
|
|
300
|
-
return cleaned || "Ref";
|
|
301
|
-
};
|
|
302
|
-
const capitalize = (value) => value.length ? value[0].toUpperCase() + value.slice(1) : value;
|
|
303
|
-
const addDefaults = (schema, parsed) => {
|
|
304
|
-
if (schema.default !== undefined) {
|
|
305
|
-
parsed += `.default(${JSON.stringify(schema.default)})`;
|
|
306
|
-
}
|
|
307
|
-
return parsed;
|
|
308
|
-
};
|
|
309
|
-
const addAnnotations = (schema, parsed) => {
|
|
310
|
-
if (schema.readOnly) {
|
|
311
|
-
parsed += ".readonly()";
|
|
312
|
-
}
|
|
313
|
-
return parsed;
|
|
314
|
-
};
|
|
315
|
-
const selectParser = (schema, refs) => {
|
|
316
|
-
if (exports.its.a.nullable(schema)) {
|
|
317
|
-
return (0, parseNullable_js_1.parseNullable)(schema, refs);
|
|
318
|
-
}
|
|
319
|
-
else if (exports.its.an.object(schema)) {
|
|
320
|
-
return (0, parseObject_js_1.parseObject)(schema, refs);
|
|
321
|
-
}
|
|
322
|
-
else if (exports.its.an.array(schema)) {
|
|
323
|
-
return (0, parseArray_js_1.parseArray)(schema, refs);
|
|
324
|
-
}
|
|
325
|
-
else if (exports.its.an.anyOf(schema)) {
|
|
326
|
-
return (0, parseAnyOf_js_1.parseAnyOf)(schema, refs);
|
|
327
|
-
}
|
|
328
|
-
else if (exports.its.an.allOf(schema)) {
|
|
329
|
-
return (0, parseAllOf_js_1.parseAllOf)(schema, refs);
|
|
330
|
-
}
|
|
331
|
-
else if (exports.its.a.simpleDiscriminatedOneOf(schema)) {
|
|
332
|
-
return (0, parseSimpleDiscriminatedOneOf_js_1.parseSimpleDiscriminatedOneOf)(schema, refs);
|
|
333
|
-
}
|
|
334
|
-
else if (exports.its.a.oneOf(schema)) {
|
|
335
|
-
return (0, parseOneOf_js_1.parseOneOf)(schema, refs);
|
|
336
|
-
}
|
|
337
|
-
else if (exports.its.a.not(schema)) {
|
|
338
|
-
return (0, parseNot_js_1.parseNot)(schema, refs);
|
|
339
|
-
}
|
|
340
|
-
else if (exports.its.an.enum(schema)) {
|
|
341
|
-
return (0, parseEnum_js_1.parseEnum)(schema); //<-- needs to come before primitives
|
|
342
|
-
}
|
|
343
|
-
else if (exports.its.a.const(schema)) {
|
|
344
|
-
return (0, parseConst_js_1.parseConst)(schema);
|
|
345
|
-
}
|
|
346
|
-
else if (exports.its.a.multipleType(schema)) {
|
|
347
|
-
return (0, parseMultipleType_js_1.parseMultipleType)(schema, refs);
|
|
348
|
-
}
|
|
349
|
-
else if (exports.its.a.primitive(schema, "string")) {
|
|
350
|
-
return (0, parseString_js_1.parseString)(schema, refs);
|
|
351
|
-
}
|
|
352
|
-
else if (exports.its.a.primitive(schema, "number") ||
|
|
353
|
-
exports.its.a.primitive(schema, "integer")) {
|
|
354
|
-
return (0, parseNumber_js_1.parseNumber)(schema);
|
|
355
|
-
}
|
|
356
|
-
else if (exports.its.a.primitive(schema, "boolean")) {
|
|
357
|
-
return (0, parseBoolean_js_1.parseBoolean)();
|
|
358
|
-
}
|
|
359
|
-
else if (exports.its.a.primitive(schema, "null")) {
|
|
360
|
-
return (0, parseNull_js_1.parseNull)();
|
|
361
|
-
}
|
|
362
|
-
else if (exports.its.a.conditional(schema)) {
|
|
363
|
-
return (0, parseIfThenElse_js_1.parseIfThenElse)(schema, refs);
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
return (0, parseDefault_js_1.parseDefault)(schema, refs);
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
exports.its = {
|
|
370
|
-
an: {
|
|
371
|
-
object: (x) => x.type === "object",
|
|
372
|
-
array: (x) => x.type === "array",
|
|
373
|
-
anyOf: (x) => x.anyOf !== undefined,
|
|
374
|
-
allOf: (x) => x.allOf !== undefined,
|
|
375
|
-
enum: (x) => x.enum !== undefined,
|
|
376
|
-
},
|
|
377
|
-
a: {
|
|
378
|
-
nullable: (x) => x.nullable === true,
|
|
379
|
-
multipleType: (x) => Array.isArray(x.type),
|
|
380
|
-
not: (x) => x.not !== undefined,
|
|
381
|
-
ref: (x) => typeof x.$ref === "string" || typeof x.$dynamicRef === "string",
|
|
382
|
-
const: (x) => x.const !== undefined,
|
|
383
|
-
primitive: (x, p) => x.type === p,
|
|
384
|
-
conditional: (x) => Boolean("if" in x && x.if && "then" in x && "else" in x && x.then && x.else),
|
|
385
|
-
simpleDiscriminatedOneOf: (x) => {
|
|
386
|
-
if (!x.oneOf ||
|
|
387
|
-
!Array.isArray(x.oneOf) ||
|
|
388
|
-
x.oneOf.length === 0 ||
|
|
389
|
-
!x.discriminator ||
|
|
390
|
-
typeof x.discriminator !== "object" ||
|
|
391
|
-
!("propertyName" in x.discriminator) ||
|
|
392
|
-
typeof x.discriminator.propertyName !== "string") {
|
|
393
|
-
return false;
|
|
394
|
-
}
|
|
395
|
-
const discriminatorProp = x.discriminator.propertyName;
|
|
396
|
-
return x.oneOf.every((schema) => {
|
|
397
|
-
if (!schema ||
|
|
398
|
-
typeof schema !== "object" ||
|
|
399
|
-
schema.type !== "object" ||
|
|
400
|
-
!schema.properties ||
|
|
401
|
-
typeof schema.properties !== "object" ||
|
|
402
|
-
!(discriminatorProp in schema.properties)) {
|
|
403
|
-
return false;
|
|
404
|
-
}
|
|
405
|
-
const property = schema.properties[discriminatorProp];
|
|
406
|
-
return (property &&
|
|
407
|
-
typeof property === "object" &&
|
|
408
|
-
(property.type === undefined || property.type === "string") &&
|
|
409
|
-
// Ensure discriminator has a constant value (const or single-value enum)
|
|
410
|
-
(property.const !== undefined ||
|
|
411
|
-
(property.enum && Array.isArray(property.enum) && property.enum.length === 1)) &&
|
|
412
|
-
// Ensure discriminator property is required
|
|
413
|
-
Array.isArray(schema.required) &&
|
|
414
|
-
schema.required.includes(discriminatorProp));
|
|
415
|
-
});
|
|
416
|
-
},
|
|
417
|
-
oneOf: (x) => x.oneOf !== undefined,
|
|
418
|
-
},
|
|
419
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseSimpleDiscriminatedOneOf = void 0;
|
|
4
|
-
const parseSchema_js_1 = require("./parseSchema.js");
|
|
5
|
-
const anyOrUnknown_js_1 = require("../utils/anyOrUnknown.js");
|
|
6
|
-
const parseSimpleDiscriminatedOneOf = (schema, refs) => {
|
|
7
|
-
const discriminator = schema.discriminator.propertyName;
|
|
8
|
-
const options = schema.oneOf.map((option, i) => (0, parseSchema_js_1.parseSchema)(option, {
|
|
9
|
-
...refs,
|
|
10
|
-
path: [...refs.path, "oneOf", i],
|
|
11
|
-
}));
|
|
12
|
-
return schema.oneOf.length
|
|
13
|
-
? schema.oneOf.length === 1
|
|
14
|
-
? (0, parseSchema_js_1.parseSchema)(schema.oneOf[0], {
|
|
15
|
-
...refs,
|
|
16
|
-
path: [...refs.path, "oneOf", 0],
|
|
17
|
-
})
|
|
18
|
-
: `z.discriminatedUnion("${discriminator}", [${options.join(", ")}])`
|
|
19
|
-
: (0, anyOrUnknown_js_1.anyOrUnknown)(refs);
|
|
20
|
-
};
|
|
21
|
-
exports.parseSimpleDiscriminatedOneOf = parseSimpleDiscriminatedOneOf;
|