@amritk/generate-parsers 0.1.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/README.md +122 -0
- package/dist/generators/build-schema.d.ts +62 -0
- package/dist/generators/generate-default-from-pattern.d.ts +5 -0
- package/dist/generators/generate-discriminated-union-validation.d.ts +6 -0
- package/dist/generators/generate-enum-check.d.ts +5 -0
- package/dist/generators/generate-files.d.ts +58 -0
- package/dist/generators/generate-non-discriminated-union-validation.d.ts +6 -0
- package/dist/generators/generate-parser-function.d.ts +47 -0
- package/dist/generators/generate-schema-checks.d.ts +5 -0
- package/dist/generators/generate-validation-expression.d.ts +7 -0
- package/dist/helpers/apply-schema-extensions.d.ts +35 -0
- package/dist/helpers/collect-helpers.d.ts +2 -0
- package/dist/helpers/collect-imports.d.ts +64 -0
- package/dist/helpers/find-discriminator.d.ts +6 -0
- package/dist/helpers/get-default-value.d.ts +7 -0
- package/dist/helpers/get-discriminator-value.d.ts +6 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2412 -0
- package/dist/types/schema-extensions.d.ts +34 -0
- package/package.json +51 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2412 @@
|
|
|
1
|
+
// ../helpers/dist/build-dynamic-ref-map.js
|
|
2
|
+
var isSchemaObject = (schema) => {
|
|
3
|
+
return typeof schema === "object" && schema !== null && typeof schema !== "boolean";
|
|
4
|
+
};
|
|
5
|
+
var buildDynamicRefMap = (rootSchema) => {
|
|
6
|
+
const map = {};
|
|
7
|
+
if (!isSchemaObject(rootSchema) || !("$defs" in rootSchema)) {
|
|
8
|
+
return map;
|
|
9
|
+
}
|
|
10
|
+
const defs = rootSchema.$defs;
|
|
11
|
+
for (const [key, value] of Object.entries(defs)) {
|
|
12
|
+
if (typeof value === "object" && value !== null && "$dynamicAnchor" in value && typeof value["$dynamicAnchor"] === "string") {
|
|
13
|
+
const anchor = value["$dynamicAnchor"];
|
|
14
|
+
map[`#${anchor}`] = `#/$defs/${key}`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return map;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// ../helpers/dist/extract-refs.js
|
|
21
|
+
var isResolvableRef = (ref) => {
|
|
22
|
+
if (ref === "#")
|
|
23
|
+
return false;
|
|
24
|
+
if (ref.startsWith("#"))
|
|
25
|
+
return true;
|
|
26
|
+
if (ref.startsWith("http://") || ref.startsWith("https://"))
|
|
27
|
+
return true;
|
|
28
|
+
return false;
|
|
29
|
+
};
|
|
30
|
+
var extractRefs = (schema) => {
|
|
31
|
+
const refs = new Set;
|
|
32
|
+
const traverse = (obj) => {
|
|
33
|
+
if (typeof obj !== "object" || obj === null) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(obj)) {
|
|
37
|
+
for (const item of obj) {
|
|
38
|
+
traverse(item);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const record = obj;
|
|
43
|
+
if ("$ref" in record && typeof record["$ref"] === "string" && isResolvableRef(record["$ref"])) {
|
|
44
|
+
refs.add(record["$ref"]);
|
|
45
|
+
}
|
|
46
|
+
for (const key in record) {
|
|
47
|
+
traverse(record[key]);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
traverse(schema);
|
|
51
|
+
return refs;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// ../helpers/dist/ref-to-filename.js
|
|
55
|
+
var toKebabCase = (value) => value.replace(/OAuth/g, "Oauth").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
|
|
56
|
+
var uriRefToFilename = (uri) => {
|
|
57
|
+
const hashIndex = uri.indexOf("#");
|
|
58
|
+
const baseUri = hashIndex === -1 ? uri : uri.slice(0, hashIndex);
|
|
59
|
+
const fragment = hashIndex === -1 ? "" : uri.slice(hashIndex + 1);
|
|
60
|
+
const withoutProtocol = baseUri.replace(/^https?:\/\/[^/]+\//, "");
|
|
61
|
+
const withoutExt = withoutProtocol.replace(/\.json$/, "");
|
|
62
|
+
const rawSegments = withoutExt.split("/");
|
|
63
|
+
const SKIP_KEYS = new Set(["definitions", "$defs"]);
|
|
64
|
+
const segments = [];
|
|
65
|
+
for (let i = 0;i < rawSegments.length; i++) {
|
|
66
|
+
const s = rawSegments[i];
|
|
67
|
+
if (SKIP_KEYS.has(s))
|
|
68
|
+
continue;
|
|
69
|
+
const prevRaw = rawSegments[i - 1];
|
|
70
|
+
if (/^\d+\.\d+/.test(s) && prevRaw !== undefined && SKIP_KEYS.has(prevRaw))
|
|
71
|
+
continue;
|
|
72
|
+
segments.push(s);
|
|
73
|
+
}
|
|
74
|
+
const baseName = segments.map((s) => toKebabCase(s).replace(/\./g, "-")).join("-");
|
|
75
|
+
if (!fragment)
|
|
76
|
+
return baseName;
|
|
77
|
+
const fragSegments = fragment.split("/").filter((s) => s && !SKIP_KEYS.has(s) && s !== "properties");
|
|
78
|
+
const fragLast = fragSegments[fragSegments.length - 1];
|
|
79
|
+
if (!fragLast)
|
|
80
|
+
return baseName;
|
|
81
|
+
return `${baseName}-${toKebabCase(fragLast)}`;
|
|
82
|
+
};
|
|
83
|
+
var refToFilename = (ref) => {
|
|
84
|
+
if (ref.startsWith("http://") || ref.startsWith("https://")) {
|
|
85
|
+
return uriRefToFilename(ref);
|
|
86
|
+
}
|
|
87
|
+
const segments = ref.split("/");
|
|
88
|
+
let filename = segments[segments.length - 1];
|
|
89
|
+
if (/[A-Z]/.test(filename)) {
|
|
90
|
+
filename = toKebabCase(filename);
|
|
91
|
+
}
|
|
92
|
+
return filename;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// ../helpers/dist/ref-to-name.js
|
|
96
|
+
var toKebabCase2 = (value) => value.replace(/OAuth/g, "Oauth").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
|
|
97
|
+
var uriRefToFilename2 = (uri) => {
|
|
98
|
+
const hashIndex = uri.indexOf("#");
|
|
99
|
+
const baseUri = hashIndex === -1 ? uri : uri.slice(0, hashIndex);
|
|
100
|
+
const fragment = hashIndex === -1 ? "" : uri.slice(hashIndex + 1);
|
|
101
|
+
const withoutProtocol = baseUri.replace(/^https?:\/\/[^/]+\//, "");
|
|
102
|
+
const withoutExt = withoutProtocol.replace(/\.json$/, "");
|
|
103
|
+
const rawSegments = withoutExt.split("/");
|
|
104
|
+
const SKIP_KEYS = new Set(["definitions", "$defs"]);
|
|
105
|
+
const segments = [];
|
|
106
|
+
for (let i = 0;i < rawSegments.length; i++) {
|
|
107
|
+
const s = rawSegments[i];
|
|
108
|
+
if (SKIP_KEYS.has(s))
|
|
109
|
+
continue;
|
|
110
|
+
const prevRaw = rawSegments[i - 1];
|
|
111
|
+
if (/^\d+\.\d+/.test(s) && prevRaw !== undefined && SKIP_KEYS.has(prevRaw))
|
|
112
|
+
continue;
|
|
113
|
+
segments.push(s);
|
|
114
|
+
}
|
|
115
|
+
const baseName = segments.map((s) => toKebabCase2(s).replace(/\./g, "-")).join("-");
|
|
116
|
+
if (!fragment)
|
|
117
|
+
return baseName;
|
|
118
|
+
const fragSegments = fragment.split("/").filter((s) => s && !SKIP_KEYS.has(s) && s !== "properties");
|
|
119
|
+
const fragLast = fragSegments[fragSegments.length - 1];
|
|
120
|
+
if (!fragLast)
|
|
121
|
+
return baseName;
|
|
122
|
+
return `${baseName}-${toKebabCase2(fragLast)}`;
|
|
123
|
+
};
|
|
124
|
+
var refToFilename2 = (ref) => {
|
|
125
|
+
if (ref.startsWith("http://") || ref.startsWith("https://")) {
|
|
126
|
+
return uriRefToFilename2(ref);
|
|
127
|
+
}
|
|
128
|
+
const segments = ref.split("/");
|
|
129
|
+
let filename = segments[segments.length - 1];
|
|
130
|
+
if (/[A-Z]/.test(filename)) {
|
|
131
|
+
filename = toKebabCase2(filename);
|
|
132
|
+
}
|
|
133
|
+
return filename;
|
|
134
|
+
};
|
|
135
|
+
var kebabToPascal = (kebab) => {
|
|
136
|
+
const words = kebab.split("-");
|
|
137
|
+
let pascalCase = "";
|
|
138
|
+
for (const word of words) {
|
|
139
|
+
pascalCase += word.charAt(0).toUpperCase() + word.slice(1);
|
|
140
|
+
}
|
|
141
|
+
return pascalCase + "Object";
|
|
142
|
+
};
|
|
143
|
+
var refToName = (ref) => kebabToPascal(refToFilename2(ref));
|
|
144
|
+
|
|
145
|
+
// ../helpers/dist/resolve-dynamic-refs.js
|
|
146
|
+
var resolveDynamicRefs = (schema, dynamicRefMap) => {
|
|
147
|
+
if (typeof schema !== "object" || schema === null) {
|
|
148
|
+
return schema;
|
|
149
|
+
}
|
|
150
|
+
if (Object.keys(dynamicRefMap).length === 0) {
|
|
151
|
+
return schema;
|
|
152
|
+
}
|
|
153
|
+
const clone = JSON.parse(JSON.stringify(schema));
|
|
154
|
+
const walk = (obj) => {
|
|
155
|
+
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const record = obj;
|
|
159
|
+
if ("$dynamicRef" in record && typeof record["$dynamicRef"] === "string") {
|
|
160
|
+
const resolved = dynamicRefMap[record["$dynamicRef"]];
|
|
161
|
+
if (resolved) {
|
|
162
|
+
record["$ref"] = resolved;
|
|
163
|
+
delete record["$dynamicRef"];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (const key in record) {
|
|
167
|
+
walk(record[key]);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
walk(clone);
|
|
171
|
+
return clone;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// ../helpers/dist/resolve-ref.js
|
|
175
|
+
var navigatePointer = (pointer, schema) => {
|
|
176
|
+
const parts = pointer.split("/").filter(Boolean);
|
|
177
|
+
let current = schema;
|
|
178
|
+
for (const part of parts) {
|
|
179
|
+
const decodedPart = part.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
180
|
+
if (current && typeof current === "object" && decodedPart in current) {
|
|
181
|
+
const next = current[decodedPart];
|
|
182
|
+
if (typeof next === "object" && next !== null) {
|
|
183
|
+
current = next;
|
|
184
|
+
} else {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return current;
|
|
192
|
+
};
|
|
193
|
+
var resolveRef = (ref, rootSchema) => {
|
|
194
|
+
if (ref.startsWith("#")) {
|
|
195
|
+
return navigatePointer(ref.slice(1), rootSchema);
|
|
196
|
+
}
|
|
197
|
+
const hashIndex = ref.indexOf("#");
|
|
198
|
+
const baseUri = hashIndex === -1 ? ref : ref.slice(0, hashIndex);
|
|
199
|
+
const rawFragment = hashIndex === -1 ? "" : ref.slice(hashIndex + 1);
|
|
200
|
+
const fragment = rawFragment === "" || rawFragment === "/" ? "" : rawFragment;
|
|
201
|
+
const defs = rootSchema["$defs"];
|
|
202
|
+
if (typeof defs !== "object" || defs === null)
|
|
203
|
+
return;
|
|
204
|
+
const defsRecord = defs;
|
|
205
|
+
const base = defsRecord[baseUri];
|
|
206
|
+
if (typeof base !== "object" || base === null)
|
|
207
|
+
return;
|
|
208
|
+
if (!fragment)
|
|
209
|
+
return base;
|
|
210
|
+
const normalizedFragment = fragment.replace(/^\/definitions\//, "/$defs/");
|
|
211
|
+
return navigatePointer(normalizedFragment, base);
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// ../helpers/dist/upgrade-draft07-schema.js
|
|
215
|
+
var toKebabCase3 = (value) => value.replace(/OAuth/g, "Oauth").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
|
|
216
|
+
var uriRefToFilename3 = (uri) => {
|
|
217
|
+
const hashIndex = uri.indexOf("#");
|
|
218
|
+
const baseUri = hashIndex === -1 ? uri : uri.slice(0, hashIndex);
|
|
219
|
+
const fragment = hashIndex === -1 ? "" : uri.slice(hashIndex + 1);
|
|
220
|
+
const withoutProtocol = baseUri.replace(/^https?:\/\/[^/]+\//, "");
|
|
221
|
+
const withoutExt = withoutProtocol.replace(/\.json$/, "");
|
|
222
|
+
const rawSegments = withoutExt.split("/");
|
|
223
|
+
const SKIP_KEYS = new Set(["definitions", "$defs"]);
|
|
224
|
+
const segments = [];
|
|
225
|
+
for (let i = 0;i < rawSegments.length; i++) {
|
|
226
|
+
const s = rawSegments[i];
|
|
227
|
+
if (SKIP_KEYS.has(s))
|
|
228
|
+
continue;
|
|
229
|
+
const prevRaw = rawSegments[i - 1];
|
|
230
|
+
if (/^\d+\.\d+/.test(s) && prevRaw !== undefined && SKIP_KEYS.has(prevRaw))
|
|
231
|
+
continue;
|
|
232
|
+
segments.push(s);
|
|
233
|
+
}
|
|
234
|
+
const baseName = segments.map((s) => toKebabCase3(s).replace(/\./g, "-")).join("-");
|
|
235
|
+
if (!fragment)
|
|
236
|
+
return baseName;
|
|
237
|
+
const fragSegments = fragment.split("/").filter((s) => s && !SKIP_KEYS.has(s) && s !== "properties");
|
|
238
|
+
const fragLast = fragSegments[fragSegments.length - 1];
|
|
239
|
+
if (!fragLast)
|
|
240
|
+
return baseName;
|
|
241
|
+
return `${baseName}-${toKebabCase3(fragLast)}`;
|
|
242
|
+
};
|
|
243
|
+
var refToFilename3 = (ref) => {
|
|
244
|
+
if (ref.startsWith("http://") || ref.startsWith("https://")) {
|
|
245
|
+
return uriRefToFilename3(ref);
|
|
246
|
+
}
|
|
247
|
+
const segments = ref.split("/");
|
|
248
|
+
let filename = segments[segments.length - 1];
|
|
249
|
+
if (/[A-Z]/.test(filename)) {
|
|
250
|
+
filename = toKebabCase3(filename);
|
|
251
|
+
}
|
|
252
|
+
return filename;
|
|
253
|
+
};
|
|
254
|
+
var isDraft07Schema = (schema) => typeof schema["$schema"] === "string" && schema["$schema"].includes("draft-07");
|
|
255
|
+
var rewriteRefs = (obj, refMap, selfRef) => {
|
|
256
|
+
if (typeof obj !== "object" || obj === null)
|
|
257
|
+
return obj;
|
|
258
|
+
if (Array.isArray(obj))
|
|
259
|
+
return obj.map((item) => rewriteRefs(item, refMap, selfRef));
|
|
260
|
+
const record = obj;
|
|
261
|
+
const result = {};
|
|
262
|
+
for (const [key, value] of Object.entries(record)) {
|
|
263
|
+
if (key === "$ref" && typeof value === "string") {
|
|
264
|
+
if (refMap.has(value)) {
|
|
265
|
+
result[key] = refMap.get(value);
|
|
266
|
+
} else if (value === "#" && selfRef) {
|
|
267
|
+
result[key] = selfRef;
|
|
268
|
+
} else {
|
|
269
|
+
result[key] = value;
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
result[key] = rewriteRefs(value, refMap, selfRef);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
};
|
|
277
|
+
var hoistNestedDefs = (defs) => {
|
|
278
|
+
const hoisted = {};
|
|
279
|
+
for (const [parentName, parentSchema] of Object.entries(defs)) {
|
|
280
|
+
if (typeof parentSchema !== "object" || parentSchema === null) {
|
|
281
|
+
hoisted[parentName] = parentSchema;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
const parentObj = parentSchema;
|
|
285
|
+
const nestedDefs = parentObj["$defs"];
|
|
286
|
+
if (!nestedDefs || typeof nestedDefs !== "object") {
|
|
287
|
+
hoisted[parentName] = parentSchema;
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const parentPrefix = parentName.startsWith("http://") || parentName.startsWith("https://") ? refToFilename3(parentName) : parentName;
|
|
291
|
+
const localToHoisted = new Map;
|
|
292
|
+
for (const localName of Object.keys(nestedDefs)) {
|
|
293
|
+
const hoistedName = `${parentPrefix}-${toKebabCase3(localName)}`;
|
|
294
|
+
localToHoisted.set(`#/$defs/${localName}`, `#/$defs/${hoistedName}`);
|
|
295
|
+
}
|
|
296
|
+
const selfRef = `#/$defs/${parentPrefix}`;
|
|
297
|
+
const rewrittenParent = rewriteRefs(parentObj, localToHoisted, selfRef);
|
|
298
|
+
hoisted[parentName] = rewrittenParent;
|
|
299
|
+
for (const [localName, localSchema] of Object.entries(nestedDefs)) {
|
|
300
|
+
const hoistedName = `${parentPrefix}-${toKebabCase3(localName)}`;
|
|
301
|
+
hoisted[hoistedName] = rewriteRefs(localSchema, localToHoisted, selfRef);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return hoisted;
|
|
305
|
+
};
|
|
306
|
+
var upgradeDraft07Schema = (schema) => {
|
|
307
|
+
if (!isDraft07Schema(schema))
|
|
308
|
+
return schema;
|
|
309
|
+
const { definitions, $schema: _, ...rest } = schema;
|
|
310
|
+
const rawDefs = definitions ?? {};
|
|
311
|
+
const renamedDefs = {};
|
|
312
|
+
for (const [key, value] of Object.entries(rawDefs)) {
|
|
313
|
+
renamedDefs[key] = renameNestedDefs(value);
|
|
314
|
+
}
|
|
315
|
+
const hoistedDefs = hoistNestedDefs(renamedDefs);
|
|
316
|
+
for (const key of Object.keys(hoistedDefs)) {
|
|
317
|
+
if (key.startsWith("http://") || key.startsWith("https://")) {
|
|
318
|
+
const shortName = refToFilename3(key);
|
|
319
|
+
if (shortName && !(shortName in hoistedDefs)) {
|
|
320
|
+
hoistedDefs[shortName] = hoistedDefs[key];
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
...rest,
|
|
326
|
+
$defs: hoistedDefs
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
var renameNestedDefs = (obj) => {
|
|
330
|
+
if (typeof obj !== "object" || obj === null)
|
|
331
|
+
return obj;
|
|
332
|
+
if (Array.isArray(obj))
|
|
333
|
+
return obj.map(renameNestedDefs);
|
|
334
|
+
const record = obj;
|
|
335
|
+
const result = {};
|
|
336
|
+
for (const [key, value] of Object.entries(record)) {
|
|
337
|
+
if (key === "$ref" && typeof value === "string" && value.startsWith("#/definitions/")) {
|
|
338
|
+
result[key] = value.replace("#/definitions/", "#/$defs/");
|
|
339
|
+
} else {
|
|
340
|
+
const outKey = key === "definitions" ? "$defs" : key;
|
|
341
|
+
result[outKey] = renameNestedDefs(value);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return result;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// src/helpers/apply-schema-extensions.ts
|
|
348
|
+
var applySchemaExtensions = (schema, definitionName, extensions) => {
|
|
349
|
+
const extensionProperties = extensions[definitionName];
|
|
350
|
+
if (!extensionProperties || Object.keys(extensionProperties).length === 0) {
|
|
351
|
+
return schema;
|
|
352
|
+
}
|
|
353
|
+
if (typeof schema !== "object" || schema === null) {
|
|
354
|
+
return schema;
|
|
355
|
+
}
|
|
356
|
+
const existingProperties = "properties" in schema && typeof schema.properties === "object" && schema.properties !== null ? schema.properties : {};
|
|
357
|
+
return {
|
|
358
|
+
...schema,
|
|
359
|
+
properties: {
|
|
360
|
+
...existingProperties,
|
|
361
|
+
...extensionProperties
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// ../helpers/dist/generate-type-definition.js
|
|
367
|
+
var isSchemaObject2 = (schema) => {
|
|
368
|
+
return typeof schema === "object" && schema !== null && typeof schema !== "boolean";
|
|
369
|
+
};
|
|
370
|
+
var isObjectSchema = (schema) => {
|
|
371
|
+
return isSchemaObject2(schema) && (("type" in schema) && schema.type === "object" || ("properties" in schema));
|
|
372
|
+
};
|
|
373
|
+
var toKebabCase4 = (value) => value.replace(/OAuth/g, "Oauth").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
|
|
374
|
+
var uriRefToFilename4 = (uri) => {
|
|
375
|
+
const hashIndex = uri.indexOf("#");
|
|
376
|
+
const baseUri = hashIndex === -1 ? uri : uri.slice(0, hashIndex);
|
|
377
|
+
const fragment = hashIndex === -1 ? "" : uri.slice(hashIndex + 1);
|
|
378
|
+
const withoutProtocol = baseUri.replace(/^https?:\/\/[^/]+\//, "");
|
|
379
|
+
const withoutExt = withoutProtocol.replace(/\.json$/, "");
|
|
380
|
+
const rawSegments = withoutExt.split("/");
|
|
381
|
+
const SKIP_KEYS = new Set(["definitions", "$defs"]);
|
|
382
|
+
const segments = [];
|
|
383
|
+
for (let i = 0;i < rawSegments.length; i++) {
|
|
384
|
+
const s = rawSegments[i];
|
|
385
|
+
if (SKIP_KEYS.has(s))
|
|
386
|
+
continue;
|
|
387
|
+
const prevRaw = rawSegments[i - 1];
|
|
388
|
+
if (/^\d+\.\d+/.test(s) && prevRaw !== undefined && SKIP_KEYS.has(prevRaw))
|
|
389
|
+
continue;
|
|
390
|
+
segments.push(s);
|
|
391
|
+
}
|
|
392
|
+
const baseName = segments.map((s) => toKebabCase4(s).replace(/\./g, "-")).join("-");
|
|
393
|
+
if (!fragment)
|
|
394
|
+
return baseName;
|
|
395
|
+
const fragSegments = fragment.split("/").filter((s) => s && !SKIP_KEYS.has(s) && s !== "properties");
|
|
396
|
+
const fragLast = fragSegments[fragSegments.length - 1];
|
|
397
|
+
if (!fragLast)
|
|
398
|
+
return baseName;
|
|
399
|
+
return `${baseName}-${toKebabCase4(fragLast)}`;
|
|
400
|
+
};
|
|
401
|
+
var refToFilename4 = (ref) => {
|
|
402
|
+
if (ref.startsWith("http://") || ref.startsWith("https://")) {
|
|
403
|
+
return uriRefToFilename4(ref);
|
|
404
|
+
}
|
|
405
|
+
const segments = ref.split("/");
|
|
406
|
+
let filename = segments[segments.length - 1];
|
|
407
|
+
if (/[A-Z]/.test(filename)) {
|
|
408
|
+
filename = toKebabCase4(filename);
|
|
409
|
+
}
|
|
410
|
+
return filename;
|
|
411
|
+
};
|
|
412
|
+
var kebabToPascal2 = (kebab) => {
|
|
413
|
+
const words = kebab.split("-");
|
|
414
|
+
let pascalCase = "";
|
|
415
|
+
for (const word of words) {
|
|
416
|
+
pascalCase += word.charAt(0).toUpperCase() + word.slice(1);
|
|
417
|
+
}
|
|
418
|
+
return pascalCase + "Object";
|
|
419
|
+
};
|
|
420
|
+
var refToName2 = (ref) => kebabToPascal2(refToFilename4(ref));
|
|
421
|
+
var JS_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
422
|
+
var safeKey = (key) => {
|
|
423
|
+
if (JS_IDENTIFIER.test(key)) {
|
|
424
|
+
return key;
|
|
425
|
+
}
|
|
426
|
+
return `'${key}'`;
|
|
427
|
+
};
|
|
428
|
+
var getConditionalObjectSchema = (schema) => {
|
|
429
|
+
if (!isSchemaObject2(schema)) {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
if (!("if" in schema) || !("then" in schema)) {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
const ifSchema = schema.if;
|
|
436
|
+
const thenSchema = schema.then;
|
|
437
|
+
if (!isSchemaObject2(ifSchema) || !isSchemaObject2(thenSchema)) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
const ifProperties = ifSchema.properties;
|
|
441
|
+
const thenProperties = thenSchema.properties;
|
|
442
|
+
const hasIfProperties = ifProperties && typeof ifProperties === "object";
|
|
443
|
+
const hasThenProperties = thenProperties && typeof thenProperties === "object";
|
|
444
|
+
if (!hasIfProperties && !hasThenProperties) {
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
const properties = {
|
|
448
|
+
...hasIfProperties ? ifProperties : {},
|
|
449
|
+
...hasThenProperties ? thenProperties : {}
|
|
450
|
+
};
|
|
451
|
+
const required = new Set;
|
|
452
|
+
if (Array.isArray(ifSchema.required)) {
|
|
453
|
+
for (const key of ifSchema.required) {
|
|
454
|
+
required.add(key);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (hasIfProperties) {
|
|
458
|
+
for (const key in ifProperties) {
|
|
459
|
+
required.add(key);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (Array.isArray(thenSchema.required)) {
|
|
463
|
+
for (const key of thenSchema.required) {
|
|
464
|
+
required.add(key);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (hasThenProperties) {
|
|
468
|
+
for (const key in thenProperties) {
|
|
469
|
+
required.add(key);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
const thenRef = typeof thenSchema.$ref === "string" ? thenSchema.$ref : null;
|
|
473
|
+
return {
|
|
474
|
+
schema: {
|
|
475
|
+
type: "object",
|
|
476
|
+
properties,
|
|
477
|
+
...required.size > 0 ? { required: Array.from(required) } : {}
|
|
478
|
+
},
|
|
479
|
+
thenRef
|
|
480
|
+
};
|
|
481
|
+
};
|
|
482
|
+
var isObjectLikeSchema = (schema) => {
|
|
483
|
+
if (!isSchemaObject2(schema)) {
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
if (isObjectSchema(schema)) {
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
return "patternProperties" in schema || "additionalProperties" in schema || "if" in schema && "then" in schema;
|
|
490
|
+
};
|
|
491
|
+
var getBooleanSubSchemaType = (schema) => {
|
|
492
|
+
return schema ? "unknown" : "never";
|
|
493
|
+
};
|
|
494
|
+
var buildJsDocBlock = (title, description, commentUrl) => {
|
|
495
|
+
let block = `/**
|
|
496
|
+
`;
|
|
497
|
+
block += `* ${title}
|
|
498
|
+
`;
|
|
499
|
+
block += `*
|
|
500
|
+
`;
|
|
501
|
+
block += `* ${description}
|
|
502
|
+
`;
|
|
503
|
+
if (commentUrl?.startsWith("http")) {
|
|
504
|
+
block += `*
|
|
505
|
+
`;
|
|
506
|
+
block += `* @see {@link ${commentUrl}}
|
|
507
|
+
`;
|
|
508
|
+
}
|
|
509
|
+
block += `*/
|
|
510
|
+
`;
|
|
511
|
+
return block;
|
|
512
|
+
};
|
|
513
|
+
var getTypeScriptType = (schema) => {
|
|
514
|
+
if (typeof schema === "boolean") {
|
|
515
|
+
return getBooleanSubSchemaType(schema);
|
|
516
|
+
}
|
|
517
|
+
if (typeof schema !== "object" || schema === null) {
|
|
518
|
+
return "unknown";
|
|
519
|
+
}
|
|
520
|
+
if (schema.$ref) {
|
|
521
|
+
if (!schema.$ref.startsWith("#")) {
|
|
522
|
+
return "unknown";
|
|
523
|
+
}
|
|
524
|
+
return refToName2(schema.$ref);
|
|
525
|
+
}
|
|
526
|
+
if (schema.$dynamicRef) {
|
|
527
|
+
if (schema.$dynamicRef === "#meta") {
|
|
528
|
+
return "Schema";
|
|
529
|
+
}
|
|
530
|
+
return refToName2(schema.$dynamicRef);
|
|
531
|
+
}
|
|
532
|
+
if (schema.const !== undefined) {
|
|
533
|
+
return JSON.stringify(schema.const);
|
|
534
|
+
}
|
|
535
|
+
if (schema.enum && schema.enum.length > 0) {
|
|
536
|
+
if (schema.enum.length === 1) {
|
|
537
|
+
return JSON.stringify(schema.enum[0]);
|
|
538
|
+
}
|
|
539
|
+
let enumUnion = JSON.stringify(schema.enum[0]);
|
|
540
|
+
for (let i = 1;i < schema.enum.length; i++) {
|
|
541
|
+
enumUnion += " | " + JSON.stringify(schema.enum[i]);
|
|
542
|
+
}
|
|
543
|
+
return enumUnion;
|
|
544
|
+
}
|
|
545
|
+
if (schema.enum && schema.enum.length > 1) {
|
|
546
|
+
let multiEnumUnion = JSON.stringify(schema.enum[0]);
|
|
547
|
+
for (let i = 1;i < schema.enum.length; i++) {
|
|
548
|
+
multiEnumUnion += " | " + JSON.stringify(schema.enum[i]);
|
|
549
|
+
}
|
|
550
|
+
return multiEnumUnion;
|
|
551
|
+
}
|
|
552
|
+
if (schema.oneOf && Array.isArray(schema.oneOf) && schema.oneOf.length > 0) {
|
|
553
|
+
let oneOfUnion = getTypeScriptType(schema.oneOf[0]);
|
|
554
|
+
for (let i = 1;i < schema.oneOf.length; i++) {
|
|
555
|
+
oneOfUnion += " | " + getTypeScriptType(schema.oneOf[i]);
|
|
556
|
+
}
|
|
557
|
+
return oneOfUnion;
|
|
558
|
+
}
|
|
559
|
+
if (schema.anyOf && Array.isArray(schema.anyOf) && schema.anyOf.length > 0) {
|
|
560
|
+
let anyOfUnion = getTypeScriptType(schema.anyOf[0]);
|
|
561
|
+
for (let i = 1;i < schema.anyOf.length; i++) {
|
|
562
|
+
anyOfUnion += " | " + getTypeScriptType(schema.anyOf[i]);
|
|
563
|
+
}
|
|
564
|
+
return anyOfUnion;
|
|
565
|
+
}
|
|
566
|
+
if (schema.allOf && Array.isArray(schema.allOf) && schema.allOf.length > 0) {
|
|
567
|
+
let intersectionTypes = getTypeScriptType(schema.allOf[0]);
|
|
568
|
+
for (let i = 1;i < schema.allOf.length; i++) {
|
|
569
|
+
intersectionTypes += " & " + getTypeScriptType(schema.allOf[i]);
|
|
570
|
+
}
|
|
571
|
+
return intersectionTypes;
|
|
572
|
+
}
|
|
573
|
+
const conditionalResult = getConditionalObjectSchema(schema);
|
|
574
|
+
if (conditionalResult) {
|
|
575
|
+
const baseType = getTypeScriptType(conditionalResult.schema);
|
|
576
|
+
if (conditionalResult.thenRef) {
|
|
577
|
+
return `(${baseType}) & ${refToName2(conditionalResult.thenRef)}`;
|
|
578
|
+
}
|
|
579
|
+
return baseType;
|
|
580
|
+
}
|
|
581
|
+
if (!schema.type) {
|
|
582
|
+
if (schema.additionalProperties !== undefined) {
|
|
583
|
+
if (typeof schema.additionalProperties === "boolean") {
|
|
584
|
+
return `Record<string, ${getBooleanSubSchemaType(schema.additionalProperties)}>`;
|
|
585
|
+
}
|
|
586
|
+
return `Record<string, ${getTypeScriptType(schema.additionalProperties)}>`;
|
|
587
|
+
}
|
|
588
|
+
if (schema.patternProperties && typeof schema.patternProperties === "object") {
|
|
589
|
+
const firstEntry = Object.entries(schema.patternProperties)[0];
|
|
590
|
+
if (firstEntry) {
|
|
591
|
+
const [pattern, value] = firstEntry;
|
|
592
|
+
if (value !== undefined) {
|
|
593
|
+
const valueType = typeof value === "boolean" ? getBooleanSubSchemaType(value) : getTypeScriptType(value);
|
|
594
|
+
if (pattern === "^x-") {
|
|
595
|
+
return `Record<\`x-\${string}\`, ${valueType}>`;
|
|
596
|
+
}
|
|
597
|
+
return `Record<string, ${valueType}>`;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
if (schema.default !== undefined) {
|
|
602
|
+
if (typeof schema.default === "string") {
|
|
603
|
+
return "string";
|
|
604
|
+
}
|
|
605
|
+
if (typeof schema.default === "number") {
|
|
606
|
+
return "number";
|
|
607
|
+
}
|
|
608
|
+
if (typeof schema.default === "boolean") {
|
|
609
|
+
return "boolean";
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return "unknown";
|
|
613
|
+
}
|
|
614
|
+
if (Array.isArray(schema.type)) {
|
|
615
|
+
const mapType = (t) => {
|
|
616
|
+
switch (t) {
|
|
617
|
+
case "string":
|
|
618
|
+
return "string";
|
|
619
|
+
case "number":
|
|
620
|
+
case "integer":
|
|
621
|
+
return "number";
|
|
622
|
+
case "boolean":
|
|
623
|
+
return "boolean";
|
|
624
|
+
case "null":
|
|
625
|
+
return "null";
|
|
626
|
+
case "array":
|
|
627
|
+
return "unknown[]";
|
|
628
|
+
case "object":
|
|
629
|
+
return "Record<string, unknown>";
|
|
630
|
+
default:
|
|
631
|
+
return "unknown";
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
let typeUnion = mapType(schema.type[0]);
|
|
635
|
+
for (let i = 1;i < schema.type.length; i++) {
|
|
636
|
+
typeUnion += " | " + mapType(schema.type[i]);
|
|
637
|
+
}
|
|
638
|
+
return typeUnion;
|
|
639
|
+
}
|
|
640
|
+
switch (schema.type) {
|
|
641
|
+
case "string":
|
|
642
|
+
return "string";
|
|
643
|
+
case "number":
|
|
644
|
+
case "integer":
|
|
645
|
+
return "number";
|
|
646
|
+
case "boolean":
|
|
647
|
+
return "boolean";
|
|
648
|
+
case "array":
|
|
649
|
+
if (schema.items) {
|
|
650
|
+
const itemType = getTypeScriptType(schema.items);
|
|
651
|
+
const wrappedItemType = itemType.includes(" | ") ? `(${itemType})` : itemType;
|
|
652
|
+
return `${wrappedItemType}[]`;
|
|
653
|
+
}
|
|
654
|
+
return "unknown[]";
|
|
655
|
+
case "object":
|
|
656
|
+
if (schema.properties) {
|
|
657
|
+
let properties = "";
|
|
658
|
+
let first = true;
|
|
659
|
+
for (const key in schema.properties) {
|
|
660
|
+
const propSchema = schema.properties[key];
|
|
661
|
+
const isRequired = schema.required?.includes(key) ?? false;
|
|
662
|
+
const optional = isRequired ? "" : "?";
|
|
663
|
+
const propType = getTypeScriptType(propSchema);
|
|
664
|
+
if (!first)
|
|
665
|
+
properties += "; ";
|
|
666
|
+
properties += safeKey(key) + optional + ": " + propType;
|
|
667
|
+
first = false;
|
|
668
|
+
}
|
|
669
|
+
return "{ " + properties + " }";
|
|
670
|
+
}
|
|
671
|
+
if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
672
|
+
const additionalPropType = getTypeScriptType(schema.additionalProperties);
|
|
673
|
+
return `Record<string, ${additionalPropType}>`;
|
|
674
|
+
}
|
|
675
|
+
if (schema.patternProperties && typeof schema.patternProperties === "object") {
|
|
676
|
+
const firstEntry = Object.entries(schema.patternProperties)[0];
|
|
677
|
+
if (firstEntry) {
|
|
678
|
+
const [pattern, patternVal] = firstEntry;
|
|
679
|
+
if (patternVal) {
|
|
680
|
+
const valueType = getTypeScriptType(patternVal);
|
|
681
|
+
if (pattern === "^x-") {
|
|
682
|
+
return `Record<\`x-\${string}\`, ${valueType}>`;
|
|
683
|
+
}
|
|
684
|
+
return `Record<string, ${valueType}>`;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
return "object";
|
|
689
|
+
default:
|
|
690
|
+
return "unknown";
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
var generateTypeDefinition = (schema, typeName) => {
|
|
694
|
+
if (!isObjectLikeSchema(schema)) {
|
|
695
|
+
const tsType = getTypeScriptType(schema);
|
|
696
|
+
let result = "";
|
|
697
|
+
if (isSchemaObject2(schema) && schema.$comment && typeof schema.$comment === "string") {
|
|
698
|
+
result += buildJsDocBlock(typeName, schema.$comment);
|
|
699
|
+
}
|
|
700
|
+
result += `export type ${typeName} = ${tsType};`;
|
|
701
|
+
return result;
|
|
702
|
+
}
|
|
703
|
+
if (isObjectLikeSchema(schema)) {
|
|
704
|
+
const conditionalResult = getConditionalObjectSchema(schema);
|
|
705
|
+
const normalizedSchema = conditionalResult?.schema ?? schema;
|
|
706
|
+
const conditionalThenRef = conditionalResult?.thenRef ?? null;
|
|
707
|
+
let jsDocTitle;
|
|
708
|
+
let jsDocDescription;
|
|
709
|
+
if (isSchemaObject2(schema) && schema.$comment && typeof schema.$comment === "string") {
|
|
710
|
+
jsDocTitle = typeName;
|
|
711
|
+
jsDocDescription = schema.$comment;
|
|
712
|
+
}
|
|
713
|
+
const hasProperties2 = normalizedSchema.properties && Object.keys(normalizedSchema.properties).length > 0;
|
|
714
|
+
const hasAdditionalProperties2 = normalizedSchema.additionalProperties && typeof normalizedSchema.additionalProperties === "object";
|
|
715
|
+
const hasPatternProperties = normalizedSchema.patternProperties && typeof normalizedSchema.patternProperties === "object" && Object.keys(normalizedSchema.patternProperties).length > 0;
|
|
716
|
+
if (!hasProperties2 && hasPatternProperties && normalizedSchema.patternProperties) {
|
|
717
|
+
const firstEntry = Object.entries(normalizedSchema.patternProperties)[0];
|
|
718
|
+
const firstPattern = firstEntry?.[0];
|
|
719
|
+
const firstPatternProperty = firstEntry?.[1];
|
|
720
|
+
if (firstPatternProperty === undefined) {
|
|
721
|
+
return `export type ${typeName} = Record<string, unknown>;`;
|
|
722
|
+
}
|
|
723
|
+
const patternPropType = typeof firstPatternProperty === "boolean" ? getBooleanSubSchemaType(firstPatternProperty) : getTypeScriptType(firstPatternProperty);
|
|
724
|
+
const keyType = firstPattern === "^x-" ? "`x-${string}`" : "string";
|
|
725
|
+
let result2 = "";
|
|
726
|
+
if (jsDocTitle && jsDocDescription) {
|
|
727
|
+
result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
|
|
728
|
+
}
|
|
729
|
+
result2 += `export type ${typeName} = Record<${keyType}, ${patternPropType}>;`;
|
|
730
|
+
return result2;
|
|
731
|
+
}
|
|
732
|
+
if (!hasProperties2 && hasAdditionalProperties2 && normalizedSchema.additionalProperties) {
|
|
733
|
+
const additionalPropType = getTypeScriptType(normalizedSchema.additionalProperties);
|
|
734
|
+
let result2 = "";
|
|
735
|
+
if (jsDocTitle && jsDocDescription) {
|
|
736
|
+
result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
|
|
737
|
+
}
|
|
738
|
+
result2 += `export type ${typeName} = {
|
|
739
|
+
[key: string]: ${additionalPropType};
|
|
740
|
+
};`;
|
|
741
|
+
return result2;
|
|
742
|
+
}
|
|
743
|
+
const schemaProps = normalizedSchema.properties ?? {};
|
|
744
|
+
let properties = "";
|
|
745
|
+
let isFirstProp = true;
|
|
746
|
+
for (const key in schemaProps) {
|
|
747
|
+
const propSchema = schemaProps[key];
|
|
748
|
+
const isRequired = normalizedSchema.required?.includes(key) ?? false;
|
|
749
|
+
const optional = isRequired ? "" : "?";
|
|
750
|
+
const propType = getTypeScriptType(propSchema);
|
|
751
|
+
const quotedKey = safeKey(key);
|
|
752
|
+
if (!isFirstProp)
|
|
753
|
+
properties += `
|
|
754
|
+
`;
|
|
755
|
+
isFirstProp = false;
|
|
756
|
+
const inlineDescription = isSchemaObject2(propSchema) && typeof propSchema.description === "string" ? propSchema.description : isSchemaObject2(propSchema) && typeof propSchema.$comment === "string" ? propSchema.$comment : undefined;
|
|
757
|
+
if (inlineDescription) {
|
|
758
|
+
properties += " /** " + inlineDescription + ` */
|
|
759
|
+
` + quotedKey + optional + ": " + propType + ";";
|
|
760
|
+
} else {
|
|
761
|
+
properties += " " + quotedKey + optional + ": " + propType + ";";
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
const allOfIntersections = [];
|
|
765
|
+
if (isSchemaObject2(schema) && Array.isArray(schema.allOf)) {
|
|
766
|
+
for (const entry of schema.allOf) {
|
|
767
|
+
if (isSchemaObject2(entry) && entry.$ref) {
|
|
768
|
+
allOfIntersections.push(refToName2(entry.$ref));
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
if (isSchemaObject2(schema) && typeof schema.$ref === "string" && schema.$ref.startsWith("#")) {
|
|
773
|
+
allOfIntersections.push(refToName2(schema.$ref));
|
|
774
|
+
}
|
|
775
|
+
let result = "";
|
|
776
|
+
if (jsDocTitle && jsDocDescription) {
|
|
777
|
+
result += buildJsDocBlock(jsDocTitle, jsDocDescription);
|
|
778
|
+
}
|
|
779
|
+
let typeBody = `{
|
|
780
|
+
` + properties + `
|
|
781
|
+
}`;
|
|
782
|
+
if (conditionalThenRef) {
|
|
783
|
+
typeBody += " & " + refToName2(conditionalThenRef);
|
|
784
|
+
}
|
|
785
|
+
for (const intersectionType of allOfIntersections) {
|
|
786
|
+
typeBody += " & " + intersectionType;
|
|
787
|
+
}
|
|
788
|
+
result += "export type " + typeName + " = " + typeBody + ";";
|
|
789
|
+
return result;
|
|
790
|
+
}
|
|
791
|
+
return "export type " + typeName + " = unknown;";
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
// src/helpers/collect-helpers.ts
|
|
795
|
+
var collectHelpers = (parserFunction) => {
|
|
796
|
+
const imports = [];
|
|
797
|
+
if (parserFunction.includes("validateArray")) {
|
|
798
|
+
imports.push("import { validateArray } from '@amritk/helpers/validate-array';");
|
|
799
|
+
}
|
|
800
|
+
if (parserFunction.includes("validateRecord")) {
|
|
801
|
+
imports.push("import { validateRecord } from '@amritk/helpers/validate-record';");
|
|
802
|
+
}
|
|
803
|
+
if (parserFunction.includes("isObject")) {
|
|
804
|
+
imports.push("import { isObject } from '@amritk/helpers/is-object';");
|
|
805
|
+
}
|
|
806
|
+
if (parserFunction.includes("hasRef(")) {
|
|
807
|
+
imports.push("import { hasRef } from '@amritk/helpers/schema-guards';");
|
|
808
|
+
}
|
|
809
|
+
return imports;
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
// ../helpers/dist/schema-guards.js
|
|
813
|
+
var isSchemaObject3 = (schema) => {
|
|
814
|
+
return typeof schema === "object" && schema !== null && typeof schema !== "boolean";
|
|
815
|
+
};
|
|
816
|
+
var hasType = (schema) => {
|
|
817
|
+
return isSchemaObject3(schema) && "type" in schema && typeof schema.type === "string";
|
|
818
|
+
};
|
|
819
|
+
var isObjectSchema2 = (schema) => {
|
|
820
|
+
return isSchemaObject3(schema) && (("type" in schema) && schema.type === "object" || ("properties" in schema));
|
|
821
|
+
};
|
|
822
|
+
var hasProperties = (schema) => {
|
|
823
|
+
return isSchemaObject3(schema) && "properties" in schema && typeof schema.properties === "object" && schema.properties !== null;
|
|
824
|
+
};
|
|
825
|
+
var hasEnum = (schema) => {
|
|
826
|
+
return isSchemaObject3(schema) && "enum" in schema && Array.isArray(schema.enum);
|
|
827
|
+
};
|
|
828
|
+
var hasConst = (schema) => {
|
|
829
|
+
return isSchemaObject3(schema) && "const" in schema;
|
|
830
|
+
};
|
|
831
|
+
var hasPattern = (schema) => {
|
|
832
|
+
return isSchemaObject3(schema) && "pattern" in schema && typeof schema.pattern === "string";
|
|
833
|
+
};
|
|
834
|
+
var hasDefault = (schema) => {
|
|
835
|
+
return isSchemaObject3(schema) && "default" in schema;
|
|
836
|
+
};
|
|
837
|
+
var hasExamples = (schema) => {
|
|
838
|
+
return isSchemaObject3(schema) && "examples" in schema && Array.isArray(schema.examples);
|
|
839
|
+
};
|
|
840
|
+
var hasOneOf = (schema) => {
|
|
841
|
+
return isSchemaObject3(schema) && "oneOf" in schema && Array.isArray(schema.oneOf);
|
|
842
|
+
};
|
|
843
|
+
var hasAnyOf = (schema) => {
|
|
844
|
+
return isSchemaObject3(schema) && "anyOf" in schema && Array.isArray(schema.anyOf);
|
|
845
|
+
};
|
|
846
|
+
var hasAllOf = (schema) => {
|
|
847
|
+
return isSchemaObject3(schema) && "allOf" in schema && Array.isArray(schema.allOf);
|
|
848
|
+
};
|
|
849
|
+
var hasRequired = (schema) => {
|
|
850
|
+
return isSchemaObject3(schema) && "required" in schema && Array.isArray(schema.required);
|
|
851
|
+
};
|
|
852
|
+
var hasItems = (schema) => {
|
|
853
|
+
return isSchemaObject3(schema) && "items" in schema && typeof schema.items === "object" && schema.items !== null && typeof schema.items !== "boolean";
|
|
854
|
+
};
|
|
855
|
+
var hasAdditionalProperties = (schema) => {
|
|
856
|
+
return isSchemaObject3(schema) && "additionalProperties" in schema;
|
|
857
|
+
};
|
|
858
|
+
var hasMinLength = (schema) => {
|
|
859
|
+
return isSchemaObject3(schema) && "minLength" in schema && typeof schema.minLength === "number";
|
|
860
|
+
};
|
|
861
|
+
var hasMaxLength = (schema) => {
|
|
862
|
+
return isSchemaObject3(schema) && "maxLength" in schema && typeof schema.maxLength === "number";
|
|
863
|
+
};
|
|
864
|
+
var hasMinimum = (schema) => {
|
|
865
|
+
return isSchemaObject3(schema) && "minimum" in schema && typeof schema.minimum === "number";
|
|
866
|
+
};
|
|
867
|
+
var hasMaximum = (schema) => {
|
|
868
|
+
return isSchemaObject3(schema) && "maximum" in schema && typeof schema.maximum === "number";
|
|
869
|
+
};
|
|
870
|
+
var hasExclusiveMinimum = (schema) => {
|
|
871
|
+
return isSchemaObject3(schema) && "exclusiveMinimum" in schema && typeof schema.exclusiveMinimum === "number";
|
|
872
|
+
};
|
|
873
|
+
var hasExclusiveMaximum = (schema) => {
|
|
874
|
+
return isSchemaObject3(schema) && "exclusiveMaximum" in schema && typeof schema.exclusiveMaximum === "number";
|
|
875
|
+
};
|
|
876
|
+
var hasMultipleOf = (schema) => {
|
|
877
|
+
return isSchemaObject3(schema) && "multipleOf" in schema && typeof schema.multipleOf === "number";
|
|
878
|
+
};
|
|
879
|
+
var hasMinItems = (schema) => {
|
|
880
|
+
return isSchemaObject3(schema) && "minItems" in schema && typeof schema.minItems === "number";
|
|
881
|
+
};
|
|
882
|
+
var hasMaxItems = (schema) => {
|
|
883
|
+
return isSchemaObject3(schema) && "maxItems" in schema && typeof schema.maxItems === "number";
|
|
884
|
+
};
|
|
885
|
+
var hasUniqueItems = (schema) => {
|
|
886
|
+
return isSchemaObject3(schema) && "uniqueItems" in schema && typeof schema.uniqueItems === "boolean";
|
|
887
|
+
};
|
|
888
|
+
var hasMinProperties = (schema) => {
|
|
889
|
+
return isSchemaObject3(schema) && "minProperties" in schema && typeof schema.minProperties === "number";
|
|
890
|
+
};
|
|
891
|
+
var hasMaxProperties = (schema) => {
|
|
892
|
+
return isSchemaObject3(schema) && "maxProperties" in schema && typeof schema.maxProperties === "number";
|
|
893
|
+
};
|
|
894
|
+
var hasRef = (schema) => {
|
|
895
|
+
return isSchemaObject3(schema) && "$ref" in schema && typeof schema.$ref === "string";
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
// src/helpers/collect-imports.ts
|
|
899
|
+
var getImportPathForFilename = (filename) => `./${filename}`;
|
|
900
|
+
var collectImports = (schema, options) => {
|
|
901
|
+
const typesOnly = options?.typesOnly === true;
|
|
902
|
+
const selfFilename = options?.selfRef ? refToFilename(options.selfRef) : undefined;
|
|
903
|
+
const rootSchema = options?.rootSchema;
|
|
904
|
+
const refs = new Set;
|
|
905
|
+
const collectRefsFromValue = (value) => {
|
|
906
|
+
if (typeof value !== "object" || value === null) {
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
if (Array.isArray(value)) {
|
|
910
|
+
for (const item of value) {
|
|
911
|
+
collectRefsFromValue(item);
|
|
912
|
+
}
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
const record = value;
|
|
916
|
+
if (hasRef(record)) {
|
|
917
|
+
const ref = record.$ref;
|
|
918
|
+
const isInternal = ref.startsWith("#");
|
|
919
|
+
const isUri = ref.startsWith("http://") || ref.startsWith("https://");
|
|
920
|
+
const isPropertyFragment = isUri && ref.includes("#/properties/");
|
|
921
|
+
if (isInternal || isUri && !isPropertyFragment) {
|
|
922
|
+
refs.add(ref);
|
|
923
|
+
}
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
if (hasAdditionalProperties(record) && hasRef(record.additionalProperties)) {
|
|
927
|
+
collectRefsFromValue(record.additionalProperties);
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
if (record.type === "array" && hasItems(record) && hasRef(record.items)) {
|
|
931
|
+
collectRefsFromValue(record.items);
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
if ("properties" in record && typeof record.properties === "object" && record.properties !== null) {
|
|
935
|
+
const props = record.properties;
|
|
936
|
+
for (const key in props) {
|
|
937
|
+
collectRefsFromValue(props[key]);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
if (hasOneOf(record)) {
|
|
941
|
+
for (const item of record.oneOf) {
|
|
942
|
+
collectRefsFromValue(item);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
if (hasAnyOf(record)) {
|
|
946
|
+
for (const item of record.anyOf) {
|
|
947
|
+
collectRefsFromValue(item);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
if (hasAllOf(record)) {
|
|
951
|
+
for (const item of record.allOf) {
|
|
952
|
+
collectRefsFromValue(item);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
if (hasItems(record)) {
|
|
956
|
+
collectRefsFromValue(record.items);
|
|
957
|
+
}
|
|
958
|
+
if (hasAdditionalProperties(record)) {
|
|
959
|
+
collectRefsFromValue(record.additionalProperties);
|
|
960
|
+
}
|
|
961
|
+
if ("patternProperties" in record && typeof record.patternProperties === "object" && record.patternProperties !== null) {
|
|
962
|
+
const patternProps = record.patternProperties;
|
|
963
|
+
for (const key in patternProps) {
|
|
964
|
+
collectRefsFromValue(patternProps[key]);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
if ("then" in record) {
|
|
968
|
+
collectRefsFromValue(record.then);
|
|
969
|
+
}
|
|
970
|
+
if ("else" in record) {
|
|
971
|
+
collectRefsFromValue(record.else);
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
if (typeof schema === "object" && schema !== null && hasRef(schema)) {
|
|
975
|
+
const ref = schema.$ref;
|
|
976
|
+
const isInternal = ref.startsWith("#");
|
|
977
|
+
const isUri = ref.startsWith("http://") || ref.startsWith("https://");
|
|
978
|
+
const isPropertyFragment = isUri && ref.includes("#/properties/");
|
|
979
|
+
if (isInternal || isUri && !isPropertyFragment) {
|
|
980
|
+
refs.add(ref);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
if (typeof schema === "object" && schema !== null && "properties" in schema) {
|
|
984
|
+
const properties = schema.properties;
|
|
985
|
+
for (const key in properties) {
|
|
986
|
+
collectRefsFromValue(properties[key]);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
if (typeof schema === "object" && schema !== null && "additionalProperties" in schema) {
|
|
990
|
+
collectRefsFromValue(schema.additionalProperties);
|
|
991
|
+
}
|
|
992
|
+
if (typeof schema === "object" && schema !== null && "patternProperties" in schema) {
|
|
993
|
+
const patternProps = schema.patternProperties;
|
|
994
|
+
for (const key in patternProps) {
|
|
995
|
+
collectRefsFromValue(patternProps[key]);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
if (typeof schema === "object" && schema !== null && hasItems(schema)) {
|
|
999
|
+
collectRefsFromValue(schema.items);
|
|
1000
|
+
}
|
|
1001
|
+
if (typeof schema === "object" && schema !== null && hasOneOf(schema)) {
|
|
1002
|
+
for (const item of schema.oneOf) {
|
|
1003
|
+
collectRefsFromValue(item);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
if (typeof schema === "object" && schema !== null && hasAnyOf(schema)) {
|
|
1007
|
+
for (const item of schema.anyOf) {
|
|
1008
|
+
collectRefsFromValue(item);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
if (typeof schema === "object" && schema !== null && hasAllOf(schema)) {
|
|
1012
|
+
for (const item of schema.allOf) {
|
|
1013
|
+
collectRefsFromValue(item);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
if (typeof schema === "object" && schema !== null && "if" in schema) {
|
|
1017
|
+
collectRefsFromValue(schema.if);
|
|
1018
|
+
}
|
|
1019
|
+
if (typeof schema === "object" && schema !== null && "then" in schema) {
|
|
1020
|
+
collectRefsFromValue(schema.then);
|
|
1021
|
+
}
|
|
1022
|
+
if (typeof schema === "object" && schema !== null && "else" in schema) {
|
|
1023
|
+
collectRefsFromValue(schema.else);
|
|
1024
|
+
}
|
|
1025
|
+
const importMap = new Map;
|
|
1026
|
+
for (const ref of refs) {
|
|
1027
|
+
if (rootSchema !== undefined && (ref.startsWith("http://") || ref.startsWith("https://"))) {
|
|
1028
|
+
if (!resolveRef(ref, rootSchema))
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
const typeName = refToName(ref);
|
|
1032
|
+
const filename = refToFilename(ref);
|
|
1033
|
+
if (selfFilename !== undefined && filename === selfFilename) {
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
const importPath = getImportPathForFilename(filename);
|
|
1037
|
+
const importStatement = typesOnly ? `import type { ${typeName} } from '${importPath}';` : `import { type ${typeName}, parse${typeName}, validate${typeName}Shape } from '${importPath}';`;
|
|
1038
|
+
importMap.set(filename, importStatement);
|
|
1039
|
+
}
|
|
1040
|
+
return Array.from(importMap.values()).sort();
|
|
1041
|
+
};
|
|
1042
|
+
|
|
1043
|
+
// ../helpers/dist/safe-accessor.js
|
|
1044
|
+
var JS_IDENTIFIER2 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
1045
|
+
var safeAccessor = (variable, key) => {
|
|
1046
|
+
if (JS_IDENTIFIER2.test(key)) {
|
|
1047
|
+
return `${variable}.${key}`;
|
|
1048
|
+
}
|
|
1049
|
+
if (variable.endsWith("?")) {
|
|
1050
|
+
return `${variable}.['${key}']`;
|
|
1051
|
+
}
|
|
1052
|
+
return `${variable}['${key}']`;
|
|
1053
|
+
};
|
|
1054
|
+
var safeKey2 = (key) => {
|
|
1055
|
+
if (JS_IDENTIFIER2.test(key)) {
|
|
1056
|
+
return key;
|
|
1057
|
+
}
|
|
1058
|
+
return `'${key}'`;
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
// src/generators/generate-default-from-pattern.ts
|
|
1062
|
+
var generateDefaultFromPattern = (pattern) => {
|
|
1063
|
+
if (pattern.includes("@") || pattern.includes("[a-zA-Z0-9]") && pattern.includes("\\.")) {
|
|
1064
|
+
return '"user@example.com"';
|
|
1065
|
+
}
|
|
1066
|
+
if (pattern.includes("[0-9a-f]") && pattern.includes("{8}") || pattern.includes("\\-")) {
|
|
1067
|
+
if (pattern.match(/[0-9a-f].*\{8\}/i) || pattern.match(/[0-9a-fA-F]{8}/)) {
|
|
1068
|
+
return '"00000000-0000-0000-0000-000000000000"';
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
if (pattern.includes("https?") || pattern.includes("http")) {
|
|
1072
|
+
return '"https://example.com"';
|
|
1073
|
+
}
|
|
1074
|
+
if (pattern.match(/\d.*\\\.\.*\d/)) {
|
|
1075
|
+
return '"1.0.0"';
|
|
1076
|
+
}
|
|
1077
|
+
if (pattern.includes("\\d{4}") && pattern.includes("\\d{2}")) {
|
|
1078
|
+
return '"2000-01-01"';
|
|
1079
|
+
}
|
|
1080
|
+
if (pattern.includes("\\d{3}") && (pattern.includes("\\d{4}") || pattern.includes("\\d{7}"))) {
|
|
1081
|
+
return '"+1234567890"';
|
|
1082
|
+
}
|
|
1083
|
+
return null;
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
// src/helpers/get-default-value.ts
|
|
1087
|
+
var getDefaultValue = (schema) => {
|
|
1088
|
+
if (!isSchemaObject3(schema)) {
|
|
1089
|
+
return "undefined";
|
|
1090
|
+
}
|
|
1091
|
+
if (hasDefault(schema)) {
|
|
1092
|
+
return JSON.stringify(schema.default);
|
|
1093
|
+
}
|
|
1094
|
+
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
1095
|
+
return JSON.stringify(schema.enum[0]);
|
|
1096
|
+
}
|
|
1097
|
+
if (hasExamples(schema) && schema.examples.length > 0) {
|
|
1098
|
+
return JSON.stringify(schema.examples[0]);
|
|
1099
|
+
}
|
|
1100
|
+
if (hasOneOf(schema) && schema.oneOf.length > 0) {
|
|
1101
|
+
const firstSchema = schema.oneOf[0];
|
|
1102
|
+
if (firstSchema !== undefined) {
|
|
1103
|
+
return getDefaultValue(firstSchema);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
if (hasAnyOf(schema) && schema.anyOf.length > 0) {
|
|
1107
|
+
const firstSchema = schema.anyOf[0];
|
|
1108
|
+
if (firstSchema !== undefined) {
|
|
1109
|
+
return getDefaultValue(firstSchema);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
if (hasAllOf(schema) && schema.allOf.length > 0) {
|
|
1113
|
+
const firstSchema = schema.allOf[0];
|
|
1114
|
+
if (firstSchema !== undefined) {
|
|
1115
|
+
return getDefaultValue(firstSchema);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
if (!hasType(schema)) {
|
|
1119
|
+
return "undefined";
|
|
1120
|
+
}
|
|
1121
|
+
switch (schema.type) {
|
|
1122
|
+
case "string": {
|
|
1123
|
+
if (hasPattern(schema)) {
|
|
1124
|
+
const patternDefault = generateDefaultFromPattern(schema.pattern);
|
|
1125
|
+
if (patternDefault) {
|
|
1126
|
+
return patternDefault;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
return '""';
|
|
1130
|
+
}
|
|
1131
|
+
case "number":
|
|
1132
|
+
case "integer":
|
|
1133
|
+
return "0";
|
|
1134
|
+
case "boolean":
|
|
1135
|
+
return "false";
|
|
1136
|
+
case "array":
|
|
1137
|
+
return "[]";
|
|
1138
|
+
case "object":
|
|
1139
|
+
return "{}";
|
|
1140
|
+
default:
|
|
1141
|
+
return "undefined";
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
|
|
1145
|
+
// src/helpers/find-discriminator.ts
|
|
1146
|
+
var findDiscriminator = (schemas) => {
|
|
1147
|
+
const propertyValues = new Map;
|
|
1148
|
+
for (const schema of schemas) {
|
|
1149
|
+
if (isObjectSchema2(schema) && hasProperties(schema)) {
|
|
1150
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
1151
|
+
if (!propertyValues.has(key)) {
|
|
1152
|
+
propertyValues.set(key, new Set);
|
|
1153
|
+
}
|
|
1154
|
+
if (isSchemaObject3(propSchema) && hasConst(propSchema)) {
|
|
1155
|
+
propertyValues.get(key)?.add(propSchema.const);
|
|
1156
|
+
} else if (isSchemaObject3(propSchema) && hasEnum(propSchema) && propSchema.enum.length === 1) {
|
|
1157
|
+
propertyValues.get(key)?.add(propSchema.enum[0]);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
for (const [key, values] of propertyValues.entries()) {
|
|
1163
|
+
if (values.size === schemas.length) {
|
|
1164
|
+
return key;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return null;
|
|
1168
|
+
};
|
|
1169
|
+
|
|
1170
|
+
// src/helpers/get-discriminator-value.ts
|
|
1171
|
+
var getDiscriminatorValue = (schema, discriminatorKey) => {
|
|
1172
|
+
if (isObjectSchema2(schema) && hasProperties(schema)) {
|
|
1173
|
+
const propSchema = schema.properties[discriminatorKey];
|
|
1174
|
+
if (propSchema && isSchemaObject3(propSchema)) {
|
|
1175
|
+
if (hasConst(propSchema)) {
|
|
1176
|
+
return propSchema.const;
|
|
1177
|
+
}
|
|
1178
|
+
if (hasEnum(propSchema) && propSchema.enum.length === 1) {
|
|
1179
|
+
return propSchema.enum[0];
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
return null;
|
|
1184
|
+
};
|
|
1185
|
+
|
|
1186
|
+
// src/generators/generate-enum-check.ts
|
|
1187
|
+
var generateEnumCheck = (accessor, enumValues) => {
|
|
1188
|
+
const serializedEnum = JSON.stringify(enumValues);
|
|
1189
|
+
return `${serializedEnum}.includes(${accessor} as never)`;
|
|
1190
|
+
};
|
|
1191
|
+
|
|
1192
|
+
// src/generators/generate-schema-checks.ts
|
|
1193
|
+
var generateSchemaChecks = (accessor, schema) => {
|
|
1194
|
+
const checks = [];
|
|
1195
|
+
if (!hasType(schema)) {
|
|
1196
|
+
return checks;
|
|
1197
|
+
}
|
|
1198
|
+
switch (schema.type) {
|
|
1199
|
+
case "string": {
|
|
1200
|
+
checks.push(`typeof ${accessor} === "string"`);
|
|
1201
|
+
if (hasPattern(schema)) {
|
|
1202
|
+
checks.push(`/${schema.pattern.replace(/\//g, "\\/")}/.test(${accessor})`);
|
|
1203
|
+
}
|
|
1204
|
+
if (hasMinLength(schema)) {
|
|
1205
|
+
checks.push(`${accessor}.length >= ${schema.minLength}`);
|
|
1206
|
+
}
|
|
1207
|
+
if (hasMaxLength(schema)) {
|
|
1208
|
+
checks.push(`${accessor}.length <= ${schema.maxLength}`);
|
|
1209
|
+
}
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1212
|
+
case "number":
|
|
1213
|
+
case "integer":
|
|
1214
|
+
checks.push(`typeof ${accessor} === "number"`);
|
|
1215
|
+
if (hasMinimum(schema)) {
|
|
1216
|
+
checks.push(`${accessor} >= ${schema.minimum}`);
|
|
1217
|
+
}
|
|
1218
|
+
if (hasMaximum(schema)) {
|
|
1219
|
+
checks.push(`${accessor} <= ${schema.maximum}`);
|
|
1220
|
+
}
|
|
1221
|
+
if (hasExclusiveMinimum(schema)) {
|
|
1222
|
+
checks.push(`${accessor} > ${schema.exclusiveMinimum}`);
|
|
1223
|
+
}
|
|
1224
|
+
if (hasExclusiveMaximum(schema)) {
|
|
1225
|
+
checks.push(`${accessor} < ${schema.exclusiveMaximum}`);
|
|
1226
|
+
}
|
|
1227
|
+
if (hasMultipleOf(schema)) {
|
|
1228
|
+
checks.push(`${accessor} % ${schema.multipleOf} === 0`);
|
|
1229
|
+
}
|
|
1230
|
+
break;
|
|
1231
|
+
case "boolean":
|
|
1232
|
+
checks.push(`typeof ${accessor} === "boolean"`);
|
|
1233
|
+
break;
|
|
1234
|
+
case "array":
|
|
1235
|
+
checks.push(`Array.isArray(${accessor})`);
|
|
1236
|
+
if (hasMinItems(schema)) {
|
|
1237
|
+
checks.push(`${accessor}.length >= ${schema.minItems}`);
|
|
1238
|
+
}
|
|
1239
|
+
if (hasMaxItems(schema)) {
|
|
1240
|
+
checks.push(`${accessor}.length <= ${schema.maxItems}`);
|
|
1241
|
+
}
|
|
1242
|
+
if (hasUniqueItems(schema) && schema.uniqueItems === true) {
|
|
1243
|
+
checks.push(`new Set(${accessor}).size === ${accessor}.length`);
|
|
1244
|
+
}
|
|
1245
|
+
break;
|
|
1246
|
+
case "object": {
|
|
1247
|
+
checks.push(`typeof ${accessor} === "object" && ${accessor} !== null && !Array.isArray(${accessor})`);
|
|
1248
|
+
if (hasRequired(schema) && schema.required.length > 0) {
|
|
1249
|
+
for (const requiredKey of schema.required) {
|
|
1250
|
+
checks.push(`"${requiredKey}" in ${accessor}`);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
if (hasMinProperties(schema)) {
|
|
1254
|
+
checks.push(`Object.keys(${accessor}).length >= ${schema.minProperties}`);
|
|
1255
|
+
}
|
|
1256
|
+
if (hasMaxProperties(schema)) {
|
|
1257
|
+
checks.push(`Object.keys(${accessor}).length <= ${schema.maxProperties}`);
|
|
1258
|
+
}
|
|
1259
|
+
if (hasAdditionalProperties(schema) && schema.additionalProperties === false && hasProperties(schema)) {
|
|
1260
|
+
const allowedKeys = Object.keys(schema.properties);
|
|
1261
|
+
const allowedKeysStr = JSON.stringify(allowedKeys);
|
|
1262
|
+
checks.push(`Object.keys(${accessor}).every(k => ${allowedKeysStr}.includes(k))`);
|
|
1263
|
+
}
|
|
1264
|
+
break;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
1268
|
+
checks.push(generateEnumCheck(accessor, schema.enum));
|
|
1269
|
+
}
|
|
1270
|
+
return checks;
|
|
1271
|
+
};
|
|
1272
|
+
|
|
1273
|
+
// src/generators/generate-discriminated-union-validation.ts
|
|
1274
|
+
var generateDiscriminatedUnionValidation = (accessor, schemas, discriminatorKey, defaultValue, isRequired) => {
|
|
1275
|
+
const cases = [];
|
|
1276
|
+
for (const schema of schemas) {
|
|
1277
|
+
const discriminatorValue = getDiscriminatorValue(schema, discriminatorKey);
|
|
1278
|
+
if (discriminatorValue !== null) {
|
|
1279
|
+
const schemaDefault = getDefaultValue(schema);
|
|
1280
|
+
const checks = generateSchemaChecks(accessor, schema);
|
|
1281
|
+
if (checks.length > 0) {
|
|
1282
|
+
let combinedChecks = checks[0];
|
|
1283
|
+
for (let i = 1;i < checks.length; i++) {
|
|
1284
|
+
combinedChecks += " && " + checks[i];
|
|
1285
|
+
}
|
|
1286
|
+
cases.push(`${accessor}?.${discriminatorKey} === ${JSON.stringify(discriminatorValue)} && ${combinedChecks} ? ${accessor} : ${schemaDefault}`);
|
|
1287
|
+
} else {
|
|
1288
|
+
cases.push(`${accessor}?.${discriminatorKey} === ${JSON.stringify(discriminatorValue)} ? ${accessor} : ${schemaDefault}`);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
if (cases.length === 0) {
|
|
1293
|
+
return isRequired ? `${accessor} ?? ${defaultValue}` : accessor;
|
|
1294
|
+
}
|
|
1295
|
+
let result = cases[0];
|
|
1296
|
+
for (let i = 1;i < cases.length; i++) {
|
|
1297
|
+
result = cases[i] + " : " + result;
|
|
1298
|
+
}
|
|
1299
|
+
return result;
|
|
1300
|
+
};
|
|
1301
|
+
|
|
1302
|
+
// src/generators/generate-non-discriminated-union-validation.ts
|
|
1303
|
+
var generateNonDiscriminatedUnionValidation = (accessor, schemas, defaultValue, isRequired) => {
|
|
1304
|
+
const cases = [];
|
|
1305
|
+
for (const schema of schemas) {
|
|
1306
|
+
const checks = generateSchemaChecks(accessor, schema);
|
|
1307
|
+
if (checks.length > 0) {
|
|
1308
|
+
let combinedChecks = checks[0];
|
|
1309
|
+
for (let i = 1;i < checks.length; i++) {
|
|
1310
|
+
combinedChecks += " && " + checks[i];
|
|
1311
|
+
}
|
|
1312
|
+
cases.push("(" + combinedChecks + ")");
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
if (cases.length === 0) {
|
|
1316
|
+
return isRequired ? `${accessor} ?? ${defaultValue}` : accessor;
|
|
1317
|
+
}
|
|
1318
|
+
let combinedCheck = cases[0];
|
|
1319
|
+
for (let i = 1;i < cases.length; i++) {
|
|
1320
|
+
combinedCheck += " || " + cases[i];
|
|
1321
|
+
}
|
|
1322
|
+
const finalDefault = isRequired ? defaultValue : "undefined";
|
|
1323
|
+
return `(${combinedCheck}) ? ${accessor} : ${finalDefault}`;
|
|
1324
|
+
};
|
|
1325
|
+
|
|
1326
|
+
// src/generators/generate-validation-expression.ts
|
|
1327
|
+
var getTypeCoercion = (accessor, schema, defaultValue) => {
|
|
1328
|
+
if (!hasType(schema)) {
|
|
1329
|
+
return null;
|
|
1330
|
+
}
|
|
1331
|
+
switch (schema.type) {
|
|
1332
|
+
case "string":
|
|
1333
|
+
return `String(${accessor})`;
|
|
1334
|
+
case "number":
|
|
1335
|
+
case "integer": {
|
|
1336
|
+
const n = `Number(${accessor})`;
|
|
1337
|
+
return `(Number.isFinite(${n}) ? ${n} : ${defaultValue})`;
|
|
1338
|
+
}
|
|
1339
|
+
case "boolean":
|
|
1340
|
+
return `Boolean(${accessor})`;
|
|
1341
|
+
case "array":
|
|
1342
|
+
return `[]`;
|
|
1343
|
+
case "object":
|
|
1344
|
+
return `typeof ${accessor} === "object" && ${accessor} !== null ? ${accessor} : {}`;
|
|
1345
|
+
default:
|
|
1346
|
+
return null;
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
var generateValidationExpression = (key, schema, defaultValue, isRequired, rootSchema, visitedRefs, accessorOverride, knownNotUndefined) => {
|
|
1350
|
+
const accessor = accessorOverride ?? safeAccessor("input?", key);
|
|
1351
|
+
const checks = [];
|
|
1352
|
+
if (!isSchemaObject3(schema)) {
|
|
1353
|
+
return isRequired ? `${accessor} ?? ${defaultValue}` : accessor;
|
|
1354
|
+
}
|
|
1355
|
+
if (hasRef(schema) && rootSchema) {
|
|
1356
|
+
const ref = schema.$ref;
|
|
1357
|
+
if (visitedRefs?.has(ref)) {
|
|
1358
|
+
return isRequired ? `${accessor} ?? ${defaultValue}` : accessor;
|
|
1359
|
+
}
|
|
1360
|
+
const resolvedSchema = resolveRef(ref, rootSchema);
|
|
1361
|
+
if (resolvedSchema) {
|
|
1362
|
+
const visited = new Set(visitedRefs);
|
|
1363
|
+
visited.add(ref);
|
|
1364
|
+
return generateValidationExpression(key, resolvedSchema, defaultValue, isRequired, rootSchema, visited);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
if (hasOneOf(schema) && schema.oneOf.length > 0) {
|
|
1368
|
+
const discriminator = findDiscriminator(schema.oneOf);
|
|
1369
|
+
if (discriminator) {
|
|
1370
|
+
return generateDiscriminatedUnionValidation(accessor, schema.oneOf, discriminator, defaultValue, isRequired);
|
|
1371
|
+
}
|
|
1372
|
+
return generateNonDiscriminatedUnionValidation(accessor, schema.oneOf, defaultValue, isRequired);
|
|
1373
|
+
}
|
|
1374
|
+
if (hasAnyOf(schema) && schema.anyOf.length > 0) {
|
|
1375
|
+
const discriminator = findDiscriminator(schema.anyOf);
|
|
1376
|
+
if (discriminator) {
|
|
1377
|
+
return generateDiscriminatedUnionValidation(accessor, schema.anyOf, discriminator, defaultValue, isRequired);
|
|
1378
|
+
}
|
|
1379
|
+
return generateNonDiscriminatedUnionValidation(accessor, schema.anyOf, defaultValue, isRequired);
|
|
1380
|
+
}
|
|
1381
|
+
if (hasAllOf(schema) && schema.allOf.length > 0) {
|
|
1382
|
+
const allChecks = [];
|
|
1383
|
+
for (const subSchema of schema.allOf) {
|
|
1384
|
+
const subChecks = generateSchemaChecks(accessor, subSchema);
|
|
1385
|
+
allChecks.push(...subChecks);
|
|
1386
|
+
}
|
|
1387
|
+
if (allChecks.length > 0) {
|
|
1388
|
+
let combinedCheck2 = allChecks[0];
|
|
1389
|
+
for (let i = 1;i < allChecks.length; i++) {
|
|
1390
|
+
combinedCheck2 += " && " + allChecks[i];
|
|
1391
|
+
}
|
|
1392
|
+
return `${combinedCheck2} ? ${accessor} : ${defaultValue}`;
|
|
1393
|
+
}
|
|
1394
|
+
return `${accessor} ?? ${defaultValue}`;
|
|
1395
|
+
}
|
|
1396
|
+
if ("not" in schema && schema.not) {
|
|
1397
|
+
const notChecks = generateSchemaChecks(accessor, schema.not);
|
|
1398
|
+
if (notChecks.length > 0) {
|
|
1399
|
+
let combinedNotCheck = notChecks[0];
|
|
1400
|
+
for (let i = 1;i < notChecks.length; i++) {
|
|
1401
|
+
combinedNotCheck += " && " + notChecks[i];
|
|
1402
|
+
}
|
|
1403
|
+
return `!(${combinedNotCheck}) ? ${accessor} : ${defaultValue}`;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
if (hasConst(schema)) {
|
|
1407
|
+
const constLiteral = JSON.stringify(schema.const);
|
|
1408
|
+
return isRequired ? `${accessor} === ${constLiteral} ? ${accessor} : ${constLiteral}` : `${accessor} === ${constLiteral} ? ${accessor} : (${accessor} !== undefined ? ${constLiteral} : undefined)`;
|
|
1409
|
+
}
|
|
1410
|
+
if (!hasType(schema) && !hasEnum(schema)) {
|
|
1411
|
+
return `${accessor} ?? ${defaultValue}`;
|
|
1412
|
+
}
|
|
1413
|
+
if (hasType(schema)) {
|
|
1414
|
+
switch (schema.type) {
|
|
1415
|
+
case "string": {
|
|
1416
|
+
checks.push(`typeof ${accessor} === "string"`);
|
|
1417
|
+
if (hasPattern(schema)) {
|
|
1418
|
+
checks.push(`/${schema.pattern.replace(/\//g, "\\/")}/.test(${accessor})`);
|
|
1419
|
+
}
|
|
1420
|
+
if (hasMinLength(schema)) {
|
|
1421
|
+
checks.push(`${accessor}.length >= ${schema.minLength}`);
|
|
1422
|
+
}
|
|
1423
|
+
if (hasMaxLength(schema)) {
|
|
1424
|
+
checks.push(`${accessor}.length <= ${schema.maxLength}`);
|
|
1425
|
+
}
|
|
1426
|
+
break;
|
|
1427
|
+
}
|
|
1428
|
+
case "number":
|
|
1429
|
+
case "integer": {
|
|
1430
|
+
checks.push(`typeof ${accessor} === "number"`);
|
|
1431
|
+
if (hasMinimum(schema)) {
|
|
1432
|
+
checks.push(`${accessor} >= ${schema.minimum}`);
|
|
1433
|
+
}
|
|
1434
|
+
if (hasMaximum(schema)) {
|
|
1435
|
+
checks.push(`${accessor} <= ${schema.maximum}`);
|
|
1436
|
+
}
|
|
1437
|
+
if (hasExclusiveMinimum(schema)) {
|
|
1438
|
+
checks.push(`${accessor} > ${schema.exclusiveMinimum}`);
|
|
1439
|
+
}
|
|
1440
|
+
if (hasExclusiveMaximum(schema)) {
|
|
1441
|
+
checks.push(`${accessor} < ${schema.exclusiveMaximum}`);
|
|
1442
|
+
}
|
|
1443
|
+
if (hasMultipleOf(schema)) {
|
|
1444
|
+
checks.push(`${accessor} % ${schema.multipleOf} === 0`);
|
|
1445
|
+
}
|
|
1446
|
+
break;
|
|
1447
|
+
}
|
|
1448
|
+
case "boolean":
|
|
1449
|
+
checks.push(`typeof ${accessor} === "boolean"`);
|
|
1450
|
+
break;
|
|
1451
|
+
case "array": {
|
|
1452
|
+
checks.push(`Array.isArray(${accessor})`);
|
|
1453
|
+
if (hasMinItems(schema)) {
|
|
1454
|
+
checks.push(`${accessor}.length >= ${schema.minItems}`);
|
|
1455
|
+
}
|
|
1456
|
+
if (hasMaxItems(schema)) {
|
|
1457
|
+
checks.push(`${accessor}.length <= ${schema.maxItems}`);
|
|
1458
|
+
}
|
|
1459
|
+
if (hasUniqueItems(schema) && schema.uniqueItems === true) {
|
|
1460
|
+
checks.push(`new Set(${accessor}).size === ${accessor}.length`);
|
|
1461
|
+
}
|
|
1462
|
+
break;
|
|
1463
|
+
}
|
|
1464
|
+
case "object": {
|
|
1465
|
+
checks.push(`isObject(${accessor})`);
|
|
1466
|
+
if (hasRequired(schema) && schema.required.length > 0) {
|
|
1467
|
+
for (const requiredKey of schema.required) {
|
|
1468
|
+
checks.push(`"${requiredKey}" in ${accessor}`);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
if (hasMinProperties(schema)) {
|
|
1472
|
+
checks.push(`Object.keys(${accessor}).length >= ${schema.minProperties}`);
|
|
1473
|
+
}
|
|
1474
|
+
if (hasMaxProperties(schema)) {
|
|
1475
|
+
checks.push(`Object.keys(${accessor}).length <= ${schema.maxProperties}`);
|
|
1476
|
+
}
|
|
1477
|
+
if (hasAdditionalProperties(schema) && schema.additionalProperties === false && hasProperties(schema)) {
|
|
1478
|
+
const allowedKeys = Object.keys(schema.properties);
|
|
1479
|
+
const allowedKeysStr = JSON.stringify(allowedKeys);
|
|
1480
|
+
checks.push(`Object.keys(${accessor}).every(k => ${allowedKeysStr}.includes(k))`);
|
|
1481
|
+
}
|
|
1482
|
+
break;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
1487
|
+
checks.push(generateEnumCheck(accessor, schema.enum));
|
|
1488
|
+
}
|
|
1489
|
+
if (checks.length === 0) {
|
|
1490
|
+
return isRequired ? `${accessor} ?? ${defaultValue}` : accessor;
|
|
1491
|
+
}
|
|
1492
|
+
let combinedCheck = checks[0];
|
|
1493
|
+
for (let i = 1;i < checks.length; i++) {
|
|
1494
|
+
combinedCheck += " && " + checks[i];
|
|
1495
|
+
}
|
|
1496
|
+
const typeCoercion = getTypeCoercion(accessor, schema, defaultValue);
|
|
1497
|
+
if (isRequired) {
|
|
1498
|
+
if (typeCoercion) {
|
|
1499
|
+
if (knownNotUndefined) {
|
|
1500
|
+
return `${combinedCheck} ? ${accessor} : ${typeCoercion}`;
|
|
1501
|
+
}
|
|
1502
|
+
return `${combinedCheck} ? ${accessor} : (${accessor} !== undefined ? ${typeCoercion} : ${defaultValue})`;
|
|
1503
|
+
}
|
|
1504
|
+
return `${combinedCheck} ? ${accessor} : ${defaultValue}`;
|
|
1505
|
+
} else {
|
|
1506
|
+
if (typeCoercion) {
|
|
1507
|
+
if (knownNotUndefined) {
|
|
1508
|
+
return `${combinedCheck} ? ${accessor} : ${typeCoercion}`;
|
|
1509
|
+
}
|
|
1510
|
+
return `${combinedCheck} ? ${accessor} : (${accessor} !== undefined ? ${typeCoercion} : undefined)`;
|
|
1511
|
+
}
|
|
1512
|
+
return `${combinedCheck} ? ${accessor} : undefined`;
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
// src/generators/generate-parser-function.ts
|
|
1517
|
+
var generateParserName = (typeName) => {
|
|
1518
|
+
return `parse${typeName}`;
|
|
1519
|
+
};
|
|
1520
|
+
var isPropertyRequired = (key, schema) => {
|
|
1521
|
+
if (!isSchemaObject3(schema)) {
|
|
1522
|
+
return false;
|
|
1523
|
+
}
|
|
1524
|
+
if (!("required" in schema) || !Array.isArray(schema.required)) {
|
|
1525
|
+
return false;
|
|
1526
|
+
}
|
|
1527
|
+
return schema.required.includes(key);
|
|
1528
|
+
};
|
|
1529
|
+
var generateRequiredRefCall = (key, ref) => {
|
|
1530
|
+
const acc = safeAccessor("input", key);
|
|
1531
|
+
const parserName = generateParserName(refToName(ref));
|
|
1532
|
+
return `${parserName}(${acc})`;
|
|
1533
|
+
};
|
|
1534
|
+
var generateOptionalRefCall = (key, ref) => {
|
|
1535
|
+
const acc = safeAccessor("input", key);
|
|
1536
|
+
const parserName = generateParserName(refToName(ref));
|
|
1537
|
+
return `...(${acc} && { ${safeKey2(key)}: ${parserName}(${acc}) })`;
|
|
1538
|
+
};
|
|
1539
|
+
var generateRequiredArrayRefCall = (key, ref) => {
|
|
1540
|
+
const parserName = generateParserName(refToName(ref));
|
|
1541
|
+
return `validateArray(${safeAccessor("input", key)}, ${parserName})`;
|
|
1542
|
+
};
|
|
1543
|
+
var generateOptionalArrayRefCall = (key, ref) => {
|
|
1544
|
+
const parserName = generateParserName(refToName(ref));
|
|
1545
|
+
const acc = safeAccessor("input", key);
|
|
1546
|
+
return `...(${acc} && { ${safeKey2(key)}: validateArray(${acc}, ${parserName}) })`;
|
|
1547
|
+
};
|
|
1548
|
+
var generateRequiredRecordRefCall = (key, ref) => {
|
|
1549
|
+
const acc = safeAccessor("input", key);
|
|
1550
|
+
const parserName = generateParserName(refToName(ref));
|
|
1551
|
+
return `validateRecord(${acc}, ${parserName})`;
|
|
1552
|
+
};
|
|
1553
|
+
var generateOptionalRecordRefCall = (key, ref) => {
|
|
1554
|
+
const acc = safeAccessor("input", key);
|
|
1555
|
+
const parserName = generateParserName(refToName(ref));
|
|
1556
|
+
return `...(${acc} && { ${safeKey2(key)}: validateRecord(${acc}, ${parserName}) })`;
|
|
1557
|
+
};
|
|
1558
|
+
var generateOptionalInlineProperty = (key, valueExpression) => {
|
|
1559
|
+
return `...((value => value === undefined ? {} : { ${safeKey2(key)}: value })(${valueExpression}))`;
|
|
1560
|
+
};
|
|
1561
|
+
var shouldUseRefImport = (propSchema, useRefImports) => {
|
|
1562
|
+
if (!useRefImports || !hasRef(propSchema)) {
|
|
1563
|
+
return false;
|
|
1564
|
+
}
|
|
1565
|
+
const ref = propSchema.$ref;
|
|
1566
|
+
const isUri = ref.startsWith("http://") || ref.startsWith("https://");
|
|
1567
|
+
if (isUri && (ref.includes("#/properties/") || ref.includes("#/definitions/"))) {
|
|
1568
|
+
return false;
|
|
1569
|
+
}
|
|
1570
|
+
return true;
|
|
1571
|
+
};
|
|
1572
|
+
var shouldUseArrayRefImport = (propSchema, useRefImports) => {
|
|
1573
|
+
if (!useRefImports) {
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1576
|
+
if (!isSchemaObject3(propSchema)) {
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
if (!("type" in propSchema) || propSchema.type !== "array") {
|
|
1580
|
+
return false;
|
|
1581
|
+
}
|
|
1582
|
+
return hasItems(propSchema) && hasRef(propSchema.items);
|
|
1583
|
+
};
|
|
1584
|
+
var shouldUseRecordRefImport = (propSchema, useRefImports) => {
|
|
1585
|
+
if (!useRefImports) {
|
|
1586
|
+
return false;
|
|
1587
|
+
}
|
|
1588
|
+
if (!isSchemaObject3(propSchema)) {
|
|
1589
|
+
return false;
|
|
1590
|
+
}
|
|
1591
|
+
if (!("type" in propSchema) || propSchema.type !== "object") {
|
|
1592
|
+
return false;
|
|
1593
|
+
}
|
|
1594
|
+
if (!("additionalProperties" in propSchema)) {
|
|
1595
|
+
return false;
|
|
1596
|
+
}
|
|
1597
|
+
const additionalProps = propSchema.additionalProperties;
|
|
1598
|
+
return isSchemaObject3(additionalProps) && hasRef(additionalProps);
|
|
1599
|
+
};
|
|
1600
|
+
var generatePropertyValue = (key, propSchema, isRequired, useRefImports) => {
|
|
1601
|
+
if (shouldUseRefImport(propSchema, useRefImports)) {
|
|
1602
|
+
const ref = propSchema.$ref;
|
|
1603
|
+
return isRequired ? generateRequiredRefCall(key, ref) : generateOptionalRefCall(key, ref);
|
|
1604
|
+
}
|
|
1605
|
+
if (shouldUseArrayRefImport(propSchema, useRefImports)) {
|
|
1606
|
+
const items = propSchema.items;
|
|
1607
|
+
const ref = items.$ref;
|
|
1608
|
+
return isRequired ? generateRequiredArrayRefCall(key, ref) : generateOptionalArrayRefCall(key, ref);
|
|
1609
|
+
}
|
|
1610
|
+
if (shouldUseRecordRefImport(propSchema, useRefImports)) {
|
|
1611
|
+
const additionalProps = propSchema.additionalProperties;
|
|
1612
|
+
const ref = additionalProps.$ref;
|
|
1613
|
+
return isRequired ? generateRequiredRecordRefCall(key, ref) : generateOptionalRecordRefCall(key, ref);
|
|
1614
|
+
}
|
|
1615
|
+
if (!isSchemaObject3(propSchema)) {
|
|
1616
|
+
return isRequired ? "undefined" : generateOptionalInlineProperty(key, "undefined");
|
|
1617
|
+
}
|
|
1618
|
+
const defaultValue = getDefaultValue(propSchema);
|
|
1619
|
+
const valueExpression = generateValidationExpression(key, propSchema, defaultValue, isRequired);
|
|
1620
|
+
return isRequired ? valueExpression : generateOptionalInlineProperty(key, valueExpression);
|
|
1621
|
+
};
|
|
1622
|
+
var generatePropertyEntries = (schema, useRefImports) => {
|
|
1623
|
+
if (!hasProperties(schema)) {
|
|
1624
|
+
return [];
|
|
1625
|
+
}
|
|
1626
|
+
const entries = [];
|
|
1627
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
1628
|
+
const isRequired = isPropertyRequired(key, schema);
|
|
1629
|
+
const value = generatePropertyValue(key, propSchema, isRequired, useRefImports);
|
|
1630
|
+
const isOptional = value.startsWith("...");
|
|
1631
|
+
entries.push({ key, value, isOptional });
|
|
1632
|
+
}
|
|
1633
|
+
return entries;
|
|
1634
|
+
};
|
|
1635
|
+
var generateFallbackValue = (_, propSchema, useRefImports) => {
|
|
1636
|
+
if (useRefImports && hasRef(propSchema)) {
|
|
1637
|
+
const ref = propSchema.$ref;
|
|
1638
|
+
const parserName = generateParserName(refToName(ref));
|
|
1639
|
+
return `${parserName}(undefined)`;
|
|
1640
|
+
}
|
|
1641
|
+
if (useRefImports && isSchemaObject3(propSchema) && propSchema.type === "array" && hasItems(propSchema) && hasRef(propSchema.items)) {
|
|
1642
|
+
return "[]";
|
|
1643
|
+
}
|
|
1644
|
+
if (useRefImports && isSchemaObject3(propSchema) && propSchema.type === "object" && "additionalProperties" in propSchema) {
|
|
1645
|
+
const additionalProps = propSchema.additionalProperties;
|
|
1646
|
+
if (isSchemaObject3(additionalProps) && hasRef(additionalProps)) {
|
|
1647
|
+
return "{}";
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
if (!isSchemaObject3(propSchema)) {
|
|
1651
|
+
return "undefined";
|
|
1652
|
+
}
|
|
1653
|
+
if (hasDefault(propSchema)) {
|
|
1654
|
+
return JSON.stringify(propSchema.default);
|
|
1655
|
+
}
|
|
1656
|
+
if (hasEnum(propSchema) && propSchema.enum.length > 0) {
|
|
1657
|
+
return JSON.stringify(propSchema.enum[0]);
|
|
1658
|
+
}
|
|
1659
|
+
if (hasExamples(propSchema) && propSchema.examples.length > 0) {
|
|
1660
|
+
return JSON.stringify(propSchema.examples[0]);
|
|
1661
|
+
}
|
|
1662
|
+
if (!hasType(propSchema)) {
|
|
1663
|
+
return "undefined";
|
|
1664
|
+
}
|
|
1665
|
+
switch (propSchema.type) {
|
|
1666
|
+
case "string":
|
|
1667
|
+
return '""';
|
|
1668
|
+
case "number":
|
|
1669
|
+
case "integer":
|
|
1670
|
+
return "0";
|
|
1671
|
+
case "boolean":
|
|
1672
|
+
return "false";
|
|
1673
|
+
case "array":
|
|
1674
|
+
return "[]";
|
|
1675
|
+
case "object":
|
|
1676
|
+
return "{}";
|
|
1677
|
+
default:
|
|
1678
|
+
return "undefined";
|
|
1679
|
+
}
|
|
1680
|
+
};
|
|
1681
|
+
var generateFallbackObject = (schema, useRefImports, typeName) => {
|
|
1682
|
+
if (!hasProperties(schema)) {
|
|
1683
|
+
return `{} as ${typeName}`;
|
|
1684
|
+
}
|
|
1685
|
+
if (isSchemaObject3(schema) && (("if" in schema) || ("then" in schema) || ("else" in schema))) {
|
|
1686
|
+
return `{} as ${typeName}`;
|
|
1687
|
+
}
|
|
1688
|
+
const requiredProps = [];
|
|
1689
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
1690
|
+
const isRequired = isPropertyRequired(key, schema);
|
|
1691
|
+
if (isRequired) {
|
|
1692
|
+
const fallbackValue = generateFallbackValue(key, propSchema, useRefImports);
|
|
1693
|
+
if (fallbackValue === "undefined") {
|
|
1694
|
+
return `{} as ${typeName}`;
|
|
1695
|
+
}
|
|
1696
|
+
requiredProps.push(` ${safeKey2(key)}: ${fallbackValue},`);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
if (requiredProps.length === 0) {
|
|
1700
|
+
return `{} as ${typeName}`;
|
|
1701
|
+
}
|
|
1702
|
+
let result = `{
|
|
1703
|
+
`;
|
|
1704
|
+
for (let i = 0;i < requiredProps.length; i++) {
|
|
1705
|
+
result += requiredProps[i];
|
|
1706
|
+
if (i < requiredProps.length - 1) {
|
|
1707
|
+
result += `
|
|
1708
|
+
`;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
result += `
|
|
1712
|
+
}`;
|
|
1713
|
+
return result;
|
|
1714
|
+
};
|
|
1715
|
+
var generateNonObjectParser = (typeName, schema) => {
|
|
1716
|
+
const functionName = generateParserName(typeName);
|
|
1717
|
+
if (!isSchemaObject3(schema) || !hasType(schema)) {
|
|
1718
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
|
|
1719
|
+
}
|
|
1720
|
+
switch (schema.type) {
|
|
1721
|
+
case "string":
|
|
1722
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => typeof input === "string" ? input as ${typeName} : "" as ${typeName};`;
|
|
1723
|
+
case "number":
|
|
1724
|
+
case "integer":
|
|
1725
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => typeof input === "number" ? input as ${typeName} : 0 as ${typeName};`;
|
|
1726
|
+
case "boolean":
|
|
1727
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => typeof input === "boolean" ? input as ${typeName} : false as ${typeName};`;
|
|
1728
|
+
case "array":
|
|
1729
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => Array.isArray(input) ? [...input] as ${typeName} : [] as ${typeName};`;
|
|
1730
|
+
default:
|
|
1731
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
|
|
1732
|
+
}
|
|
1733
|
+
};
|
|
1734
|
+
var generateEmptyObjectParser = (typeName) => {
|
|
1735
|
+
const functionName = generateParserName(typeName);
|
|
1736
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? { ...input } as ${typeName} : {} as ${typeName};`;
|
|
1737
|
+
};
|
|
1738
|
+
var toVarName = (key) => {
|
|
1739
|
+
const safe = key.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1740
|
+
return `_${safe}`;
|
|
1741
|
+
};
|
|
1742
|
+
var shapeValidatorName = (typeName) => `validate${typeName}Shape`;
|
|
1743
|
+
var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
|
|
1744
|
+
if (!isSchemaObject3(schema))
|
|
1745
|
+
return null;
|
|
1746
|
+
if (useRefImports && hasRef(schema)) {
|
|
1747
|
+
const refName = refToName(schema.$ref);
|
|
1748
|
+
return `${shapeValidatorName(refName)}(${varName})`;
|
|
1749
|
+
}
|
|
1750
|
+
if (hasEnum(schema) || hasOneOf(schema) || hasAnyOf(schema) || hasAllOf(schema) || hasRef(schema) || "not" in schema) {
|
|
1751
|
+
return null;
|
|
1752
|
+
}
|
|
1753
|
+
if (!hasType(schema))
|
|
1754
|
+
return null;
|
|
1755
|
+
if (useRefImports && schema.type === "array" && hasItems(schema) && isSchemaObject3(schema.items) && hasRef(schema.items)) {
|
|
1756
|
+
const refName = refToName(schema.items.$ref);
|
|
1757
|
+
return `Array.isArray(${varName}) && ${varName}.every(${shapeValidatorName(refName)})`;
|
|
1758
|
+
}
|
|
1759
|
+
const checks = [];
|
|
1760
|
+
switch (schema.type) {
|
|
1761
|
+
case "string": {
|
|
1762
|
+
checks.push(`typeof ${varName} === "string"`);
|
|
1763
|
+
if (hasPattern(schema))
|
|
1764
|
+
checks.push(`/${escapeRegexPattern(schema.pattern)}/.test(${varName})`);
|
|
1765
|
+
if (hasMinLength(schema))
|
|
1766
|
+
checks.push(`${varName}.length >= ${schema.minLength}`);
|
|
1767
|
+
if (hasMaxLength(schema))
|
|
1768
|
+
checks.push(`${varName}.length <= ${schema.maxLength}`);
|
|
1769
|
+
break;
|
|
1770
|
+
}
|
|
1771
|
+
case "number":
|
|
1772
|
+
case "integer": {
|
|
1773
|
+
checks.push(`typeof ${varName} === "number"`);
|
|
1774
|
+
if (hasMinimum(schema))
|
|
1775
|
+
checks.push(`${varName} >= ${schema.minimum}`);
|
|
1776
|
+
if (hasMaximum(schema))
|
|
1777
|
+
checks.push(`${varName} <= ${schema.maximum}`);
|
|
1778
|
+
if (hasExclusiveMinimum(schema))
|
|
1779
|
+
checks.push(`${varName} > ${schema.exclusiveMinimum}`);
|
|
1780
|
+
if (hasExclusiveMaximum(schema))
|
|
1781
|
+
checks.push(`${varName} < ${schema.exclusiveMaximum}`);
|
|
1782
|
+
if (hasMultipleOf(schema))
|
|
1783
|
+
checks.push(`${varName} % ${schema.multipleOf} === 0`);
|
|
1784
|
+
break;
|
|
1785
|
+
}
|
|
1786
|
+
case "boolean":
|
|
1787
|
+
checks.push(`typeof ${varName} === "boolean"`);
|
|
1788
|
+
break;
|
|
1789
|
+
case "array": {
|
|
1790
|
+
checks.push(`Array.isArray(${varName})`);
|
|
1791
|
+
if (hasMinItems(schema))
|
|
1792
|
+
checks.push(`${varName}.length >= ${schema.minItems}`);
|
|
1793
|
+
if (hasMaxItems(schema))
|
|
1794
|
+
checks.push(`${varName}.length <= ${schema.maxItems}`);
|
|
1795
|
+
if (hasUniqueItems(schema) && schema.uniqueItems === true) {
|
|
1796
|
+
checks.push(`new Set(${varName}).size === ${varName}.length`);
|
|
1797
|
+
}
|
|
1798
|
+
break;
|
|
1799
|
+
}
|
|
1800
|
+
case "object":
|
|
1801
|
+
checks.push(`isObject(${varName})`);
|
|
1802
|
+
break;
|
|
1803
|
+
default:
|
|
1804
|
+
return null;
|
|
1805
|
+
}
|
|
1806
|
+
if (checks.length === 0)
|
|
1807
|
+
return null;
|
|
1808
|
+
let result = checks[0];
|
|
1809
|
+
for (let i = 1;i < checks.length; i++) {
|
|
1810
|
+
result += " && " + checks[i];
|
|
1811
|
+
}
|
|
1812
|
+
return result;
|
|
1813
|
+
};
|
|
1814
|
+
var shouldCacheVariable = (propSchema, _canFastPath, _useRefImports) => {
|
|
1815
|
+
return isSchemaObject3(propSchema);
|
|
1816
|
+
};
|
|
1817
|
+
var generateObjectParser = (schema, typeName, useRefImports, logWarnings) => {
|
|
1818
|
+
const functionName = generateParserName(typeName);
|
|
1819
|
+
if (!hasProperties(schema)) {
|
|
1820
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? input as ${typeName} : {} as ${typeName};`;
|
|
1821
|
+
}
|
|
1822
|
+
const fallbackObject = generateFallbackObject(schema, useRefImports, typeName);
|
|
1823
|
+
const properties = Object.entries(schema.properties);
|
|
1824
|
+
const lines = [];
|
|
1825
|
+
lines.push(`export const ${functionName} = (input: unknown): ${typeName} => {`);
|
|
1826
|
+
lines.push(` if (!isObject(input)) return ${fallbackObject};`);
|
|
1827
|
+
const propInfo = [];
|
|
1828
|
+
const hasAllOfRefParsers = useRefImports && isSchemaObject3(schema) && hasAllOf(schema) && schema.allOf.some((entry) => isSchemaObject3(entry) && hasRef(entry));
|
|
1829
|
+
let canFastPath = !hasAllOfRefParsers;
|
|
1830
|
+
const fastPathChecks = [];
|
|
1831
|
+
for (const [key, propSchema] of properties) {
|
|
1832
|
+
const isRequired = isPropertyRequired(key, schema);
|
|
1833
|
+
const varName = toVarName(key);
|
|
1834
|
+
propInfo.push({ key, varName, isRequired, propSchema });
|
|
1835
|
+
if (canFastPath) {
|
|
1836
|
+
if (shouldUseRecordRefImport(propSchema, useRefImports)) {
|
|
1837
|
+
canFastPath = false;
|
|
1838
|
+
} else {
|
|
1839
|
+
const check = generatePropertyTypeCheck(varName, propSchema, useRefImports);
|
|
1840
|
+
if (check === null) {
|
|
1841
|
+
canFastPath = false;
|
|
1842
|
+
} else {
|
|
1843
|
+
if (isRequired) {
|
|
1844
|
+
fastPathChecks.push(check);
|
|
1845
|
+
} else {
|
|
1846
|
+
fastPathChecks.push(`(${varName} === undefined || ${check})`);
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
for (const { key, varName, propSchema } of propInfo) {
|
|
1853
|
+
if (shouldCacheVariable(propSchema, canFastPath, useRefImports)) {
|
|
1854
|
+
lines.push(` const ${varName} = ${safeAccessor("input", key)};`);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
if (logWarnings && propInfo.length > 0) {
|
|
1858
|
+
const keysList = propInfo.map(({ key }) => JSON.stringify(key)).join(", ");
|
|
1859
|
+
lines.push(` const _knownKeys = new Set([${keysList}]);`);
|
|
1860
|
+
lines.push(` for (const _k in input) {`);
|
|
1861
|
+
lines.push(` if (!_knownKeys.has(_k)) {`);
|
|
1862
|
+
lines.push(` console.warn(\`[${typeName}] Unknown property "\${_k}"\`);`);
|
|
1863
|
+
lines.push(` }`);
|
|
1864
|
+
lines.push(` }`);
|
|
1865
|
+
}
|
|
1866
|
+
if (canFastPath && fastPathChecks.length > 0) {
|
|
1867
|
+
let fastPathExpr = fastPathChecks[0];
|
|
1868
|
+
for (let i = 1;i < fastPathChecks.length; i++) {
|
|
1869
|
+
fastPathExpr += " && " + fastPathChecks[i];
|
|
1870
|
+
}
|
|
1871
|
+
lines.push(` if (${fastPathExpr}) return { ...input } as ${typeName};`);
|
|
1872
|
+
}
|
|
1873
|
+
const objectLines = [];
|
|
1874
|
+
objectLines.push(" ...input,");
|
|
1875
|
+
if (useRefImports && isSchemaObject3(schema) && hasAllOf(schema)) {
|
|
1876
|
+
for (const entry of schema.allOf) {
|
|
1877
|
+
if (isSchemaObject3(entry) && hasRef(entry)) {
|
|
1878
|
+
const parserName = generateParserName(refToName(entry.$ref));
|
|
1879
|
+
objectLines.push(` ...(${parserName}(input) as Record<string, unknown>),`);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
for (const { key, varName, isRequired, propSchema } of propInfo) {
|
|
1884
|
+
const shouldCache = shouldCacheVariable(propSchema, canFastPath, useRefImports);
|
|
1885
|
+
const accessor = shouldCache ? varName : safeAccessor("input", key);
|
|
1886
|
+
if (shouldUseRefImport(propSchema, useRefImports)) {
|
|
1887
|
+
const ref = propSchema.$ref;
|
|
1888
|
+
const parserName = generateParserName(refToName(ref));
|
|
1889
|
+
if (isRequired) {
|
|
1890
|
+
objectLines.push(` ${safeKey2(key)}: ${parserName}(${accessor}),`);
|
|
1891
|
+
} else {
|
|
1892
|
+
objectLines.push(` ...(${accessor} !== undefined && { ${safeKey2(key)}: ${parserName}(${accessor}) }),`);
|
|
1893
|
+
}
|
|
1894
|
+
continue;
|
|
1895
|
+
}
|
|
1896
|
+
if (shouldUseArrayRefImport(propSchema, useRefImports)) {
|
|
1897
|
+
const items = propSchema.items;
|
|
1898
|
+
const ref = items.$ref;
|
|
1899
|
+
const parserName = generateParserName(refToName(ref));
|
|
1900
|
+
if (isRequired) {
|
|
1901
|
+
objectLines.push(` ${safeKey2(key)}: validateArray(${accessor}, ${parserName}),`);
|
|
1902
|
+
} else {
|
|
1903
|
+
objectLines.push(` ...(${accessor} !== undefined && { ${safeKey2(key)}: validateArray(${accessor}, ${parserName}) }),`);
|
|
1904
|
+
}
|
|
1905
|
+
continue;
|
|
1906
|
+
}
|
|
1907
|
+
if (shouldUseRecordRefImport(propSchema, useRefImports)) {
|
|
1908
|
+
const additionalProps = propSchema.additionalProperties;
|
|
1909
|
+
const ref = additionalProps.$ref;
|
|
1910
|
+
const parserName = generateParserName(refToName(ref));
|
|
1911
|
+
if (isRequired) {
|
|
1912
|
+
objectLines.push(` ${safeKey2(key)}: validateRecord(${accessor}, ${parserName}),`);
|
|
1913
|
+
} else {
|
|
1914
|
+
objectLines.push(` ...(${accessor} !== undefined && { ${safeKey2(key)}: validateRecord(${accessor}, ${parserName}) }),`);
|
|
1915
|
+
}
|
|
1916
|
+
continue;
|
|
1917
|
+
}
|
|
1918
|
+
if (!isSchemaObject3(propSchema)) {
|
|
1919
|
+
if (isRequired) {
|
|
1920
|
+
objectLines.push(` ${safeKey2(key)}: undefined,`);
|
|
1921
|
+
}
|
|
1922
|
+
continue;
|
|
1923
|
+
}
|
|
1924
|
+
const defaultValue = getDefaultValue(propSchema);
|
|
1925
|
+
const knownNotUndefined = !isRequired;
|
|
1926
|
+
const valueExpr = generateValidationExpression(key, propSchema, defaultValue, true, undefined, undefined, shouldCache ? varName : undefined, knownNotUndefined);
|
|
1927
|
+
if (isRequired) {
|
|
1928
|
+
objectLines.push(` ${safeKey2(key)}: ${valueExpr},`);
|
|
1929
|
+
} else {
|
|
1930
|
+
objectLines.push(` ...(${accessor} !== undefined && { ${safeKey2(key)}: ${valueExpr} }),`);
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
lines.push(` return {`);
|
|
1934
|
+
let objectBody = objectLines[0];
|
|
1935
|
+
for (let i = 1;i < objectLines.length; i++) {
|
|
1936
|
+
objectBody += `
|
|
1937
|
+
` + objectLines[i];
|
|
1938
|
+
}
|
|
1939
|
+
lines.push(objectBody);
|
|
1940
|
+
lines.push(` } as unknown as ${typeName};`);
|
|
1941
|
+
lines.push(`}`);
|
|
1942
|
+
let result = lines[0];
|
|
1943
|
+
for (let i = 1;i < lines.length; i++) {
|
|
1944
|
+
result += `
|
|
1945
|
+
` + lines[i];
|
|
1946
|
+
}
|
|
1947
|
+
return result;
|
|
1948
|
+
};
|
|
1949
|
+
var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings) => {
|
|
1950
|
+
const functionName = generateParserName(typeName);
|
|
1951
|
+
const entries = generatePropertyEntries(schema, useRefImports);
|
|
1952
|
+
const propertyLines = entries.map((entry) => {
|
|
1953
|
+
if (entry.isOptional) {
|
|
1954
|
+
return ` ${entry.value},`;
|
|
1955
|
+
}
|
|
1956
|
+
return ` ${safeKey2(entry.key)}: ${entry.value},`;
|
|
1957
|
+
});
|
|
1958
|
+
if (!isSchemaObject3(schema) || !("patternProperties" in schema)) {
|
|
1959
|
+
return generateObjectParser(schema, typeName, useRefImports, logWarnings);
|
|
1960
|
+
}
|
|
1961
|
+
const patternProps = schema.patternProperties;
|
|
1962
|
+
const patterns = Object.entries(patternProps);
|
|
1963
|
+
const refPattern = patterns.find(([, ps]) => isSchemaObject3(ps) && hasRef(ps));
|
|
1964
|
+
if (!refPattern || !useRefImports) {
|
|
1965
|
+
return generateObjectParser(schema, typeName, useRefImports, logWarnings);
|
|
1966
|
+
}
|
|
1967
|
+
const [pattern, patternSchema] = refPattern;
|
|
1968
|
+
const ref = patternSchema.$ref;
|
|
1969
|
+
const parserName = generateParserName(refToName(ref));
|
|
1970
|
+
const assignmentCode = `(result as Record<string, unknown>)[key] = ${parserName}(value);`;
|
|
1971
|
+
const escapedPattern = escapeRegexPattern(pattern);
|
|
1972
|
+
const inputSpread = " ...input,";
|
|
1973
|
+
let objectProperties = inputSpread;
|
|
1974
|
+
if (propertyLines.length > 0) {
|
|
1975
|
+
for (const line of propertyLines) {
|
|
1976
|
+
objectProperties += `
|
|
1977
|
+
` + line;
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => {
|
|
1981
|
+
if (!isObject(input)) {
|
|
1982
|
+
return {} as unknown as ${typeName};
|
|
1983
|
+
}
|
|
1984
|
+
const result = {
|
|
1985
|
+
${objectProperties}
|
|
1986
|
+
} as unknown as ${typeName};
|
|
1987
|
+
for (const key in input) {
|
|
1988
|
+
if (/${escapedPattern}/.test(key)) {
|
|
1989
|
+
const value = input[key];
|
|
1990
|
+
${assignmentCode}
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
return result;
|
|
1994
|
+
};`;
|
|
1995
|
+
};
|
|
1996
|
+
var generateAdditionalPropertiesParser = (schema, typeName, useRefImports) => {
|
|
1997
|
+
const functionName = generateParserName(typeName);
|
|
1998
|
+
const additionalProps = schema.additionalProperties;
|
|
1999
|
+
if (!additionalProps) {
|
|
2000
|
+
return generateEmptyObjectParser(typeName);
|
|
2001
|
+
}
|
|
2002
|
+
if (useRefImports && isSchemaObject3(additionalProps) && hasRef(additionalProps)) {
|
|
2003
|
+
const ref = additionalProps.$ref;
|
|
2004
|
+
const parserName = generateParserName(refToName(ref));
|
|
2005
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => validateRecord(input, ${parserName}) as ${typeName};`;
|
|
2006
|
+
}
|
|
2007
|
+
if (isSchemaObject3(additionalProps) && hasType(additionalProps)) {
|
|
2008
|
+
const inlineParser = generateInlineValueParser(additionalProps);
|
|
2009
|
+
if (inlineParser) {
|
|
2010
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => validateRecord(input, ${inlineParser}) as ${typeName};`;
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? { ...input } as ${typeName} : {};`;
|
|
2014
|
+
};
|
|
2015
|
+
var generateInlineValueParser = (schema) => {
|
|
2016
|
+
if (!isSchemaObject3(schema) || !hasType(schema)) {
|
|
2017
|
+
return null;
|
|
2018
|
+
}
|
|
2019
|
+
switch (schema.type) {
|
|
2020
|
+
case "string":
|
|
2021
|
+
return '(value: unknown) => typeof value === "string" ? value : ""';
|
|
2022
|
+
case "number":
|
|
2023
|
+
case "integer":
|
|
2024
|
+
return '(value: unknown) => typeof value === "number" ? value : 0';
|
|
2025
|
+
case "boolean":
|
|
2026
|
+
return '(value: unknown) => typeof value === "boolean" ? value : false';
|
|
2027
|
+
case "array":
|
|
2028
|
+
return "(value: unknown) => Array.isArray(value) ? value : []";
|
|
2029
|
+
default:
|
|
2030
|
+
return null;
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
2033
|
+
var escapeRegexPattern = (pattern) => {
|
|
2034
|
+
return pattern.replace(/\\/g, "\\\\").replace(/\//g, "\\/");
|
|
2035
|
+
};
|
|
2036
|
+
var generatePatternPropertiesParser = (schema, typeName, useRefImports) => {
|
|
2037
|
+
const functionName = generateParserName(typeName);
|
|
2038
|
+
if (!("patternProperties" in schema) || typeof schema.patternProperties !== "object") {
|
|
2039
|
+
return generateEmptyObjectParser(typeName);
|
|
2040
|
+
}
|
|
2041
|
+
const patternProps = schema.patternProperties;
|
|
2042
|
+
const patterns = Object.entries(patternProps);
|
|
2043
|
+
if (patterns.length === 0) {
|
|
2044
|
+
return generateEmptyObjectParser(typeName);
|
|
2045
|
+
}
|
|
2046
|
+
const [pattern, patternSchema] = patterns[0];
|
|
2047
|
+
let patternAssignment = "(result as Record<string, unknown>)[key] = value;";
|
|
2048
|
+
if (useRefImports && isSchemaObject3(patternSchema) && hasRef(patternSchema)) {
|
|
2049
|
+
const ref = patternSchema.$ref;
|
|
2050
|
+
const parserName = generateParserName(refToName(ref));
|
|
2051
|
+
patternAssignment = `(result as Record<string, unknown>)[key] = ${parserName}(value);`;
|
|
2052
|
+
} else if (patternSchema === false) {
|
|
2053
|
+
patternAssignment = "";
|
|
2054
|
+
}
|
|
2055
|
+
const escapedPattern = escapeRegexPattern(pattern);
|
|
2056
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => {
|
|
2057
|
+
if (!isObject(input)) {
|
|
2058
|
+
return {} as unknown as ${typeName};
|
|
2059
|
+
}
|
|
2060
|
+
const result = {
|
|
2061
|
+
...input,
|
|
2062
|
+
} as unknown as ${typeName};
|
|
2063
|
+
for (const key in input) {
|
|
2064
|
+
if (/${escapedPattern}/.test(key)) {
|
|
2065
|
+
const value = input[key];
|
|
2066
|
+
${patternAssignment}
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
return result;
|
|
2070
|
+
};`;
|
|
2071
|
+
};
|
|
2072
|
+
var generateConditionalParser = (schema, typeName) => {
|
|
2073
|
+
const functionName = generateParserName(typeName);
|
|
2074
|
+
const ifSchema = schema.if;
|
|
2075
|
+
const thenSchema = schema.then;
|
|
2076
|
+
const elseSchema = schema.else;
|
|
2077
|
+
const thenHasRef = thenSchema && isSchemaObject3(thenSchema) && hasRef(thenSchema);
|
|
2078
|
+
const elseHasRef = elseSchema && isSchemaObject3(elseSchema) && hasRef(elseSchema);
|
|
2079
|
+
if (!thenHasRef || !elseHasRef) {
|
|
2080
|
+
const mergedSchema = getConditionalObjectSchema2(schema);
|
|
2081
|
+
if (mergedSchema) {
|
|
2082
|
+
return generateObjectParser(mergedSchema, typeName, false);
|
|
2083
|
+
}
|
|
2084
|
+
return generateEmptyObjectParser(typeName);
|
|
2085
|
+
}
|
|
2086
|
+
const isRefCondition = ifSchema && isSchemaObject3(ifSchema) && "required" in ifSchema && Array.isArray(ifSchema.required) && ifSchema.required.includes("$ref");
|
|
2087
|
+
if (!isRefCondition) {
|
|
2088
|
+
const mergedSchema = getConditionalObjectSchema2(schema);
|
|
2089
|
+
if (mergedSchema) {
|
|
2090
|
+
return generateObjectParser(mergedSchema, typeName, false);
|
|
2091
|
+
}
|
|
2092
|
+
return generateEmptyObjectParser(typeName);
|
|
2093
|
+
}
|
|
2094
|
+
const thenRef = thenSchema.$ref;
|
|
2095
|
+
const elseRef = elseSchema.$ref;
|
|
2096
|
+
const thenParserName = generateParserName(refToName(thenRef));
|
|
2097
|
+
const elseParserName = generateParserName(refToName(elseRef));
|
|
2098
|
+
const thenTypeName = refToName(thenRef);
|
|
2099
|
+
return `export const ${functionName} = (input: unknown): ${typeName} | ${thenTypeName} =>
|
|
2100
|
+
hasRef(input) ? ${thenParserName}(input) : ${elseParserName}(input)
|
|
2101
|
+
`;
|
|
2102
|
+
};
|
|
2103
|
+
var getConditionalObjectSchema2 = (schema) => {
|
|
2104
|
+
if (!isSchemaObject3(schema)) {
|
|
2105
|
+
return null;
|
|
2106
|
+
}
|
|
2107
|
+
if (!("if" in schema) || !("then" in schema)) {
|
|
2108
|
+
return null;
|
|
2109
|
+
}
|
|
2110
|
+
const ifSchema = schema.if;
|
|
2111
|
+
const thenSchema = schema.then;
|
|
2112
|
+
const elseSchema = "else" in schema ? schema.else : undefined;
|
|
2113
|
+
if (!isSchemaObject3(ifSchema) || !isSchemaObject3(thenSchema)) {
|
|
2114
|
+
return null;
|
|
2115
|
+
}
|
|
2116
|
+
const ifProperties = ifSchema.properties;
|
|
2117
|
+
const thenProperties = thenSchema.properties;
|
|
2118
|
+
const elseProperties = elseSchema && isSchemaObject3(elseSchema) ? elseSchema.properties : undefined;
|
|
2119
|
+
const hasIfProperties = ifProperties && typeof ifProperties === "object";
|
|
2120
|
+
const hasThenProperties = thenProperties && typeof thenProperties === "object";
|
|
2121
|
+
const hasElseProperties = elseProperties && typeof elseProperties === "object";
|
|
2122
|
+
if (!hasIfProperties && !hasThenProperties && !hasElseProperties) {
|
|
2123
|
+
return null;
|
|
2124
|
+
}
|
|
2125
|
+
const required = new Set;
|
|
2126
|
+
if (Array.isArray(ifSchema.required)) {
|
|
2127
|
+
for (const key of ifSchema.required) {
|
|
2128
|
+
required.add(key);
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
if (hasIfProperties && ifProperties && typeof ifProperties === "object") {
|
|
2132
|
+
for (const [key, propSchema] of Object.entries(ifProperties)) {
|
|
2133
|
+
if (isSchemaObject3(propSchema) && hasConst(propSchema)) {
|
|
2134
|
+
required.add(key);
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
if (Array.isArray(thenSchema.required)) {
|
|
2139
|
+
for (const key of thenSchema.required) {
|
|
2140
|
+
required.add(key);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
return {
|
|
2144
|
+
type: "object",
|
|
2145
|
+
properties: {
|
|
2146
|
+
...hasElseProperties ? elseProperties : {},
|
|
2147
|
+
...hasIfProperties ? ifProperties : {},
|
|
2148
|
+
...hasThenProperties ? thenProperties : {}
|
|
2149
|
+
},
|
|
2150
|
+
...required.size > 0 ? { required: Array.from(required) } : {}
|
|
2151
|
+
};
|
|
2152
|
+
};
|
|
2153
|
+
var generateSchemaObjectParser = (typeName) => {
|
|
2154
|
+
const functionName = generateParserName(typeName);
|
|
2155
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => {
|
|
2156
|
+
if (typeof input === 'boolean') {
|
|
2157
|
+
return input as ${typeName};
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
if (!isObject(input)) {
|
|
2161
|
+
return {} as ${typeName};
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
return input as ${typeName};
|
|
2165
|
+
};`;
|
|
2166
|
+
};
|
|
2167
|
+
var selectParserStrategy = (schema, typeName, options) => {
|
|
2168
|
+
const useRefImports = options?.useRefImports ?? false;
|
|
2169
|
+
const logWarnings = options?.logWarnings ?? false;
|
|
2170
|
+
if (typeName === "SchemaObject") {
|
|
2171
|
+
return generateSchemaObjectParser(typeName);
|
|
2172
|
+
}
|
|
2173
|
+
const isObjectLikeSchema2 = isObjectSchema2(schema) || isSchemaObject3(schema) && (("patternProperties" in schema) || ("additionalProperties" in schema));
|
|
2174
|
+
if (!isObjectLikeSchema2 && !isSchemaObject3(schema)) {
|
|
2175
|
+
return generateNonObjectParser(typeName, schema);
|
|
2176
|
+
}
|
|
2177
|
+
if (hasProperties(schema) && isSchemaObject3(schema) && "patternProperties" in schema) {
|
|
2178
|
+
return generateCombinedObjectParser(schema, typeName, useRefImports, logWarnings);
|
|
2179
|
+
}
|
|
2180
|
+
if (hasProperties(schema)) {
|
|
2181
|
+
return generateObjectParser(schema, typeName, useRefImports, logWarnings);
|
|
2182
|
+
}
|
|
2183
|
+
if (isSchemaObject3(schema) && "if" in schema && "then" in schema && "else" in schema) {
|
|
2184
|
+
return generateConditionalParser(schema, typeName);
|
|
2185
|
+
}
|
|
2186
|
+
const conditionalObjectSchema = getConditionalObjectSchema2(schema);
|
|
2187
|
+
if (conditionalObjectSchema) {
|
|
2188
|
+
return generateObjectParser(conditionalObjectSchema, typeName, useRefImports, logWarnings);
|
|
2189
|
+
}
|
|
2190
|
+
if (!isObjectLikeSchema2) {
|
|
2191
|
+
return generateNonObjectParser(typeName, schema);
|
|
2192
|
+
}
|
|
2193
|
+
if ("patternProperties" in schema) {
|
|
2194
|
+
return generatePatternPropertiesParser(schema, typeName, useRefImports);
|
|
2195
|
+
}
|
|
2196
|
+
if ("additionalProperties" in schema && !hasProperties(schema)) {
|
|
2197
|
+
const additionalProps = schema.additionalProperties;
|
|
2198
|
+
if (additionalProps === true || additionalProps === false) {
|
|
2199
|
+
return generateEmptyObjectParser(typeName);
|
|
2200
|
+
}
|
|
2201
|
+
return generateAdditionalPropertiesParser(schema, typeName, useRefImports);
|
|
2202
|
+
}
|
|
2203
|
+
if ("type" in schema && schema.type === "object" && !hasProperties(schema)) {
|
|
2204
|
+
return generateEmptyObjectParser(typeName);
|
|
2205
|
+
}
|
|
2206
|
+
return generateEmptyObjectParser(typeName);
|
|
2207
|
+
};
|
|
2208
|
+
var generateParserFunction = (schema, typeName, options) => {
|
|
2209
|
+
return selectParserStrategy(schema, typeName, options);
|
|
2210
|
+
};
|
|
2211
|
+
var generateShapeValidator = (schema, typeName, useRefImports) => {
|
|
2212
|
+
const fnName = shapeValidatorName(typeName);
|
|
2213
|
+
const stub = `export const ${fnName} = (_input: unknown): boolean => false;`;
|
|
2214
|
+
if (!isSchemaObject3(schema))
|
|
2215
|
+
return stub;
|
|
2216
|
+
if (!hasProperties(schema))
|
|
2217
|
+
return stub;
|
|
2218
|
+
if (hasOneOf(schema) || hasAnyOf(schema) || hasAllOf(schema) || "not" in schema || "patternProperties" in schema || "if" in schema || "then" in schema || "else" in schema) {
|
|
2219
|
+
return stub;
|
|
2220
|
+
}
|
|
2221
|
+
const properties = Object.entries(schema.properties);
|
|
2222
|
+
const checks = [];
|
|
2223
|
+
for (const [key, propSchema] of properties) {
|
|
2224
|
+
if (shouldUseRecordRefImport(propSchema, useRefImports)) {
|
|
2225
|
+
return stub;
|
|
2226
|
+
}
|
|
2227
|
+
const accessor = safeAccessor("input", key);
|
|
2228
|
+
const isRequired = isPropertyRequired(key, schema);
|
|
2229
|
+
const check = generatePropertyTypeCheck(accessor, propSchema, useRefImports);
|
|
2230
|
+
if (check === null) {
|
|
2231
|
+
return stub;
|
|
2232
|
+
}
|
|
2233
|
+
if (isRequired) {
|
|
2234
|
+
checks.push(check);
|
|
2235
|
+
} else {
|
|
2236
|
+
checks.push(`(${accessor} === undefined || ${check})`);
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
if (checks.length === 0) {
|
|
2240
|
+
return `export const ${fnName} = (input: unknown): boolean => isObject(input);`;
|
|
2241
|
+
}
|
|
2242
|
+
let body = checks[0];
|
|
2243
|
+
for (let i = 1;i < checks.length; i++) {
|
|
2244
|
+
body += `
|
|
2245
|
+
&& ` + checks[i];
|
|
2246
|
+
}
|
|
2247
|
+
return `export const ${fnName} = (input: unknown): boolean => {
|
|
2248
|
+
if (!isObject(input)) return false;
|
|
2249
|
+
return ${body};
|
|
2250
|
+
};`;
|
|
2251
|
+
};
|
|
2252
|
+
|
|
2253
|
+
// src/generators/generate-files.ts
|
|
2254
|
+
var generateFile = (schema, typeName, options) => {
|
|
2255
|
+
const typesOnly = options?.typesOnly === true;
|
|
2256
|
+
const selfRef = options?.selfRef;
|
|
2257
|
+
const rootSchema = options?.rootSchema;
|
|
2258
|
+
const typeDefinition = generateTypeDefinition(schema, typeName);
|
|
2259
|
+
if (typesOnly) {
|
|
2260
|
+
const imports2 = collectImports(schema, { typesOnly: true, selfRef, rootSchema });
|
|
2261
|
+
let result2 = "";
|
|
2262
|
+
if (imports2.length > 0) {
|
|
2263
|
+
result2 += imports2[0];
|
|
2264
|
+
for (let i = 1;i < imports2.length; i++) {
|
|
2265
|
+
result2 += `
|
|
2266
|
+
` + imports2[i];
|
|
2267
|
+
}
|
|
2268
|
+
result2 += `
|
|
2269
|
+
|
|
2270
|
+
`;
|
|
2271
|
+
}
|
|
2272
|
+
return result2 + typeDefinition;
|
|
2273
|
+
}
|
|
2274
|
+
const parserFunction = generateParserFunction(schema, typeName, {
|
|
2275
|
+
useRefImports: true,
|
|
2276
|
+
...options?.logWarnings !== undefined ? { logWarnings: options.logWarnings } : {}
|
|
2277
|
+
});
|
|
2278
|
+
const shapeValidator = generateShapeValidator(schema, typeName, true);
|
|
2279
|
+
const combinedFunctions = `${shapeValidator}
|
|
2280
|
+
|
|
2281
|
+
${parserFunction}`;
|
|
2282
|
+
const imports = [...collectImports(schema, { selfRef, rootSchema }), ...collectHelpers(combinedFunctions)];
|
|
2283
|
+
let result = "";
|
|
2284
|
+
if (imports.length > 0) {
|
|
2285
|
+
result += imports[0];
|
|
2286
|
+
for (let i = 1;i < imports.length; i++) {
|
|
2287
|
+
result += `
|
|
2288
|
+
` + imports[i];
|
|
2289
|
+
}
|
|
2290
|
+
result += `
|
|
2291
|
+
|
|
2292
|
+
`;
|
|
2293
|
+
}
|
|
2294
|
+
return result + typeDefinition + `
|
|
2295
|
+
|
|
2296
|
+
` + combinedFunctions;
|
|
2297
|
+
};
|
|
2298
|
+
|
|
2299
|
+
// src/generators/build-schema.ts
|
|
2300
|
+
var extractDynamicAnchorDefs = (schema) => {
|
|
2301
|
+
const refs = [];
|
|
2302
|
+
if (typeof schema !== "object" || schema === null) {
|
|
2303
|
+
return refs;
|
|
2304
|
+
}
|
|
2305
|
+
if (!("$defs" in schema) || typeof schema["$defs"] !== "object" || schema["$defs"] === null) {
|
|
2306
|
+
return refs;
|
|
2307
|
+
}
|
|
2308
|
+
const defs = schema["$defs"];
|
|
2309
|
+
for (const [key, value] of Object.entries(defs)) {
|
|
2310
|
+
if (typeof value === "object" && value !== null) {
|
|
2311
|
+
const defSchema = value;
|
|
2312
|
+
if ("$dynamicAnchor" in defSchema) {
|
|
2313
|
+
refs.push(`#/$defs/${key}`);
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
return refs;
|
|
2318
|
+
};
|
|
2319
|
+
var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings) => {
|
|
2320
|
+
rootSchema = upgradeDraft07Schema(rootSchema);
|
|
2321
|
+
const files = [];
|
|
2322
|
+
const processedRefs = new Set;
|
|
2323
|
+
const processedFilenames = new Set;
|
|
2324
|
+
const refsToProcess = [];
|
|
2325
|
+
const dynamicRefMap = buildDynamicRefMap(rootSchema);
|
|
2326
|
+
const processedRootSchema = resolveDynamicRefs(rootSchema, dynamicRefMap);
|
|
2327
|
+
const extendedRootSchema = extensions ? applySchemaExtensions(processedRootSchema, rootTypeName.toLowerCase(), extensions) : processedRootSchema;
|
|
2328
|
+
const rootContent = generateFile(extendedRootSchema, rootTypeName, {
|
|
2329
|
+
typesOnly: typesOnly ?? false,
|
|
2330
|
+
rootSchema,
|
|
2331
|
+
...logWarnings !== undefined ? { logWarnings } : {}
|
|
2332
|
+
});
|
|
2333
|
+
const rootFilename = rootTypeName.toLowerCase();
|
|
2334
|
+
processedFilenames.add(rootFilename);
|
|
2335
|
+
files.push({
|
|
2336
|
+
filename: `${rootFilename}.ts`,
|
|
2337
|
+
content: rootContent
|
|
2338
|
+
});
|
|
2339
|
+
const rootRefs = extractRefs(rootSchema);
|
|
2340
|
+
refsToProcess.push(...rootRefs);
|
|
2341
|
+
const dynamicAnchorRefs = extractDynamicAnchorDefs(rootSchema);
|
|
2342
|
+
refsToProcess.push(...dynamicAnchorRefs);
|
|
2343
|
+
while (refsToProcess.length > 0) {
|
|
2344
|
+
const ref = refsToProcess.shift();
|
|
2345
|
+
if (!ref || processedRefs.has(ref)) {
|
|
2346
|
+
continue;
|
|
2347
|
+
}
|
|
2348
|
+
processedRefs.add(ref);
|
|
2349
|
+
const resolvedSchema = resolveRef(ref, rootSchema);
|
|
2350
|
+
if (!resolvedSchema) {
|
|
2351
|
+
console.warn(`Warning: Could not resolve ref: ${ref}`);
|
|
2352
|
+
continue;
|
|
2353
|
+
}
|
|
2354
|
+
const typeName = refToName(ref);
|
|
2355
|
+
const filename = refToFilename(ref);
|
|
2356
|
+
const processedSchema = resolveDynamicRefs(resolvedSchema, dynamicRefMap);
|
|
2357
|
+
const extendedSchema = extensions ? applySchemaExtensions(processedSchema, filename, extensions) : processedSchema;
|
|
2358
|
+
const content = generateFile(extendedSchema, typeName, {
|
|
2359
|
+
typesOnly: typesOnly ?? false,
|
|
2360
|
+
selfRef: ref,
|
|
2361
|
+
rootSchema,
|
|
2362
|
+
...logWarnings !== undefined ? { logWarnings } : {}
|
|
2363
|
+
});
|
|
2364
|
+
if (!processedFilenames.has(filename)) {
|
|
2365
|
+
processedFilenames.add(filename);
|
|
2366
|
+
files.push({
|
|
2367
|
+
filename: `${filename}.ts`,
|
|
2368
|
+
content
|
|
2369
|
+
});
|
|
2370
|
+
}
|
|
2371
|
+
const nestedRefs = extractRefs(resolvedSchema);
|
|
2372
|
+
for (const nestedRef of nestedRefs) {
|
|
2373
|
+
if (!processedRefs.has(nestedRef)) {
|
|
2374
|
+
refsToProcess.push(nestedRef);
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
const TYPE_EXPORT_RE = /^export type (\w+)/gm;
|
|
2379
|
+
const CONST_EXPORT_RE = /^export const (\w+)/gm;
|
|
2380
|
+
const sortedFiles = [...files].sort((a, b) => a.filename.localeCompare(b.filename));
|
|
2381
|
+
let indexContent = "";
|
|
2382
|
+
for (const file of sortedFiles) {
|
|
2383
|
+
const moduleName = file.filename.replace(/\.ts$/, "");
|
|
2384
|
+
const typeNames = [];
|
|
2385
|
+
const constNames = [];
|
|
2386
|
+
for (const match of file.content.matchAll(TYPE_EXPORT_RE)) {
|
|
2387
|
+
typeNames.push(match[1]);
|
|
2388
|
+
}
|
|
2389
|
+
for (const match of file.content.matchAll(CONST_EXPORT_RE)) {
|
|
2390
|
+
constNames.push(match[1]);
|
|
2391
|
+
}
|
|
2392
|
+
if (typeNames.length === 0 && constNames.length === 0)
|
|
2393
|
+
continue;
|
|
2394
|
+
if (typesOnly) {
|
|
2395
|
+
indexContent += `export type { ${typeNames.join(", ")} } from './${moduleName}';
|
|
2396
|
+
`;
|
|
2397
|
+
} else {
|
|
2398
|
+
const typeExports = typeNames.map((n) => `type ${n}`);
|
|
2399
|
+
const allExports = [...typeExports, ...constNames];
|
|
2400
|
+
indexContent += `export { ${allExports.join(", ")} } from './${moduleName}';
|
|
2401
|
+
`;
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
files.push({
|
|
2405
|
+
filename: "index.ts",
|
|
2406
|
+
content: indexContent
|
|
2407
|
+
});
|
|
2408
|
+
return files;
|
|
2409
|
+
};
|
|
2410
|
+
export {
|
|
2411
|
+
buildSchema
|
|
2412
|
+
};
|