@cerios/openapi-to-zod 1.4.0 → 1.5.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/LICENSE +8 -0
- package/README.md +546 -395
- package/dist/cli.js +806 -1293
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +839 -1343
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +468 -59
- package/dist/index.d.ts +468 -59
- package/dist/index.js +644 -881
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +650 -856
- package/dist/index.mjs.map +1 -1
- package/package.json +89 -104
- package/dist/internal.d.mts +0 -470
- package/dist/internal.d.ts +0 -470
- package/dist/internal.js +0 -2025
- package/dist/internal.js.map +0 -1
- package/dist/internal.mjs +0 -1972
- package/dist/internal.mjs.map +0 -1
- package/dist/types-DZ4Bw-D5.d.mts +0 -505
- package/dist/types-DZ4Bw-D5.d.ts +0 -505
package/dist/internal.js
DELETED
|
@@ -1,2025 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/internal.ts
|
|
31
|
-
var internal_exports = {};
|
|
32
|
-
__export(internal_exports, {
|
|
33
|
-
LRUCache: () => LRUCache,
|
|
34
|
-
OperationFiltersSchema: () => OperationFiltersSchema,
|
|
35
|
-
PropertyGenerator: () => PropertyGenerator,
|
|
36
|
-
RequestResponseOptionsSchema: () => RequestResponseOptionsSchema,
|
|
37
|
-
buildDateTimeValidation: () => buildDateTimeValidation,
|
|
38
|
-
createFilterStatistics: () => createFilterStatistics,
|
|
39
|
-
createTypeScriptLoader: () => createTypeScriptLoader,
|
|
40
|
-
escapeJSDoc: () => escapeJSDoc,
|
|
41
|
-
executeBatch: () => executeBatch,
|
|
42
|
-
formatConfigValidationError: () => formatConfigValidationError,
|
|
43
|
-
formatFilterStatistics: () => formatFilterStatistics,
|
|
44
|
-
getBatchExitCode: () => getBatchExitCode,
|
|
45
|
-
getResponseParseMethod: () => getResponseParseMethod,
|
|
46
|
-
mergeParameters: () => mergeParameters,
|
|
47
|
-
resolveParameterRef: () => resolveParameterRef,
|
|
48
|
-
resolveRef: () => resolveRef2,
|
|
49
|
-
resolveRequestBodyRef: () => resolveRequestBodyRef,
|
|
50
|
-
resolveResponseRef: () => resolveResponseRef,
|
|
51
|
-
shouldIncludeOperation: () => shouldIncludeOperation,
|
|
52
|
-
stripPathPrefix: () => stripPathPrefix,
|
|
53
|
-
stripPrefix: () => stripPrefix,
|
|
54
|
-
toCamelCase: () => toCamelCase,
|
|
55
|
-
toPascalCase: () => toPascalCase,
|
|
56
|
-
validateFilters: () => validateFilters
|
|
57
|
-
});
|
|
58
|
-
module.exports = __toCommonJS(internal_exports);
|
|
59
|
-
|
|
60
|
-
// src/errors.ts
|
|
61
|
-
var GeneratorError = class extends Error {
|
|
62
|
-
constructor(message, code, context) {
|
|
63
|
-
var _a;
|
|
64
|
-
super(message);
|
|
65
|
-
this.code = code;
|
|
66
|
-
this.context = context;
|
|
67
|
-
this.name = "GeneratorError";
|
|
68
|
-
(_a = Error.captureStackTrace) == null ? void 0 : _a.call(Error, this, this.constructor);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
var ConfigurationError = class extends GeneratorError {
|
|
72
|
-
constructor(message, context) {
|
|
73
|
-
super(message, "CONFIGURATION_ERROR", context);
|
|
74
|
-
this.name = "ConfigurationError";
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
// src/batch-executor.ts
|
|
79
|
-
async function processSpec(spec, index, total, createGenerator) {
|
|
80
|
-
const specInput = spec.input || "spec";
|
|
81
|
-
const specOutput = spec.output || "output";
|
|
82
|
-
console.log(`Processing [${index + 1}/${total}] ${specInput}...`);
|
|
83
|
-
try {
|
|
84
|
-
const generator = createGenerator(spec);
|
|
85
|
-
generator.generate();
|
|
86
|
-
return {
|
|
87
|
-
spec,
|
|
88
|
-
success: true
|
|
89
|
-
};
|
|
90
|
-
} catch (error) {
|
|
91
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
92
|
-
console.error(`\u2717 Failed to generate ${specOutput}: ${errorMessage}`);
|
|
93
|
-
return {
|
|
94
|
-
spec,
|
|
95
|
-
success: false,
|
|
96
|
-
error: errorMessage
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
async function executeParallel(specs, createGenerator, batchSize) {
|
|
101
|
-
console.log(`
|
|
102
|
-
Executing ${specs.length} specification(s) in parallel (batch size: ${batchSize})...
|
|
103
|
-
`);
|
|
104
|
-
const results = [];
|
|
105
|
-
for (let i = 0; i < specs.length; i += batchSize) {
|
|
106
|
-
const batch = specs.slice(i, Math.min(i + batchSize, specs.length));
|
|
107
|
-
const batchPromises = batch.map(
|
|
108
|
-
(spec, batchIndex) => processSpec(spec, i + batchIndex, specs.length, createGenerator)
|
|
109
|
-
);
|
|
110
|
-
const batchResults = await Promise.allSettled(batchPromises);
|
|
111
|
-
for (let j = 0; j < batchResults.length; j++) {
|
|
112
|
-
const result = batchResults[j];
|
|
113
|
-
if (result.status === "fulfilled") {
|
|
114
|
-
results.push(result.value);
|
|
115
|
-
} else {
|
|
116
|
-
results.push({
|
|
117
|
-
spec: batch[j],
|
|
118
|
-
success: false,
|
|
119
|
-
error: result.reason instanceof Error ? result.reason.message : String(result.reason)
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return results;
|
|
125
|
-
}
|
|
126
|
-
async function executeSequential(specs, createGenerator) {
|
|
127
|
-
console.log(`
|
|
128
|
-
Executing ${specs.length} spec(s) sequentially...
|
|
129
|
-
`);
|
|
130
|
-
const results = [];
|
|
131
|
-
for (let i = 0; i < specs.length; i++) {
|
|
132
|
-
const result = await processSpec(specs[i], i, specs.length, createGenerator);
|
|
133
|
-
results.push(result);
|
|
134
|
-
}
|
|
135
|
-
return results;
|
|
136
|
-
}
|
|
137
|
-
function printSummary(summary) {
|
|
138
|
-
console.log(`
|
|
139
|
-
${"=".repeat(50)}`);
|
|
140
|
-
console.log("Batch Execution Summary");
|
|
141
|
-
console.log("=".repeat(50));
|
|
142
|
-
console.log(`Total specs: ${summary.total}`);
|
|
143
|
-
console.log(`Successful: ${summary.successful}`);
|
|
144
|
-
console.log(`Failed: ${summary.failed}`);
|
|
145
|
-
if (summary.failed > 0) {
|
|
146
|
-
console.log("\nFailed specs:");
|
|
147
|
-
for (const result of summary.results) {
|
|
148
|
-
if (!result.success) {
|
|
149
|
-
const specInput = result.spec.input || "spec";
|
|
150
|
-
console.error(` \u2717 ${specInput}`);
|
|
151
|
-
console.error(` Error: ${result.error}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
console.log(`${"=".repeat(50)}
|
|
156
|
-
`);
|
|
157
|
-
}
|
|
158
|
-
async function executeBatch(specs, executionMode = "parallel", createGenerator, batchSize) {
|
|
159
|
-
if (specs.length === 0) {
|
|
160
|
-
throw new ConfigurationError("No specs provided for batch execution", { specsCount: 0, executionMode });
|
|
161
|
-
}
|
|
162
|
-
let results = [];
|
|
163
|
-
try {
|
|
164
|
-
results = executionMode === "parallel" ? await executeParallel(specs, createGenerator, batchSize) : await executeSequential(specs, createGenerator);
|
|
165
|
-
const summary = {
|
|
166
|
-
total: results.length,
|
|
167
|
-
successful: results.filter((r) => r.success).length,
|
|
168
|
-
failed: results.filter((r) => !r.success).length,
|
|
169
|
-
results
|
|
170
|
-
};
|
|
171
|
-
printSummary(summary);
|
|
172
|
-
return summary;
|
|
173
|
-
} finally {
|
|
174
|
-
if (results.length > batchSize) {
|
|
175
|
-
for (const result of results) {
|
|
176
|
-
if (result.spec) {
|
|
177
|
-
result.spec = null;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
if (global.gc) {
|
|
181
|
-
global.gc();
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function getBatchExitCode(summary) {
|
|
187
|
-
return summary.failed > 0 ? 1 : 0;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// src/utils/lru-cache.ts
|
|
191
|
-
var LRUCache = class {
|
|
192
|
-
constructor(maxSize) {
|
|
193
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
194
|
-
this.maxSize = maxSize;
|
|
195
|
-
}
|
|
196
|
-
get capacity() {
|
|
197
|
-
return this.maxSize;
|
|
198
|
-
}
|
|
199
|
-
get(key) {
|
|
200
|
-
if (!this.cache.has(key)) return void 0;
|
|
201
|
-
const value = this.cache.get(key);
|
|
202
|
-
if (value === void 0) return void 0;
|
|
203
|
-
this.cache.delete(key);
|
|
204
|
-
this.cache.set(key, value);
|
|
205
|
-
return value;
|
|
206
|
-
}
|
|
207
|
-
set(key, value) {
|
|
208
|
-
if (this.cache.has(key)) {
|
|
209
|
-
this.cache.delete(key);
|
|
210
|
-
} else if (this.cache.size >= this.maxSize) {
|
|
211
|
-
const firstKey = this.cache.keys().next().value;
|
|
212
|
-
if (firstKey !== void 0) {
|
|
213
|
-
this.cache.delete(firstKey);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
this.cache.set(key, value);
|
|
217
|
-
}
|
|
218
|
-
has(key) {
|
|
219
|
-
return this.cache.has(key);
|
|
220
|
-
}
|
|
221
|
-
clear() {
|
|
222
|
-
this.cache.clear();
|
|
223
|
-
}
|
|
224
|
-
size() {
|
|
225
|
-
return this.cache.size;
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
// src/utils/name-utils.ts
|
|
230
|
-
function sanitizeIdentifier(str) {
|
|
231
|
-
return str.replace(/[^a-zA-Z0-9._\-\s]+/g, "_");
|
|
232
|
-
}
|
|
233
|
-
function toCamelCase(str, options) {
|
|
234
|
-
const sanitized = sanitizeIdentifier(str);
|
|
235
|
-
const words = sanitized.split(/[.\-_\s]+/).filter((word) => word.length > 0);
|
|
236
|
-
let name;
|
|
237
|
-
if (words.length === 0) {
|
|
238
|
-
name = str.charAt(0).toLowerCase() + str.slice(1);
|
|
239
|
-
} else if (words.length === 1) {
|
|
240
|
-
name = words[0].charAt(0).toLowerCase() + words[0].slice(1);
|
|
241
|
-
} else {
|
|
242
|
-
name = words[0].charAt(0).toLowerCase() + words[0].slice(1) + words.slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
243
|
-
}
|
|
244
|
-
if (options == null ? void 0 : options.prefix) {
|
|
245
|
-
const prefix = options.prefix.charAt(0).toLowerCase() + options.prefix.slice(1);
|
|
246
|
-
name = prefix + name.charAt(0).toUpperCase() + name.slice(1);
|
|
247
|
-
}
|
|
248
|
-
if (options == null ? void 0 : options.suffix) {
|
|
249
|
-
const suffix = options.suffix.charAt(0).toUpperCase() + options.suffix.slice(1);
|
|
250
|
-
name = name + suffix;
|
|
251
|
-
}
|
|
252
|
-
return name;
|
|
253
|
-
}
|
|
254
|
-
function toPascalCase(str) {
|
|
255
|
-
const stringValue = String(str);
|
|
256
|
-
const isAlreadyValidCase = /^[a-zA-Z][a-zA-Z0-9]*$/.test(stringValue);
|
|
257
|
-
if (isAlreadyValidCase) {
|
|
258
|
-
return stringValue.charAt(0).toUpperCase() + stringValue.slice(1);
|
|
259
|
-
}
|
|
260
|
-
const sanitized = sanitizeIdentifier(stringValue);
|
|
261
|
-
const words = sanitized.split(/[.\-_\s]+/).filter((word) => word.length > 0);
|
|
262
|
-
let result;
|
|
263
|
-
if (words.length === 0) {
|
|
264
|
-
result = "Value";
|
|
265
|
-
} else {
|
|
266
|
-
result = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
267
|
-
}
|
|
268
|
-
if (/^\d/.test(result)) {
|
|
269
|
-
result = `N${result}`;
|
|
270
|
-
}
|
|
271
|
-
if (!result || /^_+$/.test(result)) {
|
|
272
|
-
return "Value";
|
|
273
|
-
}
|
|
274
|
-
return result;
|
|
275
|
-
}
|
|
276
|
-
function resolveRef(ref) {
|
|
277
|
-
const parts = ref.split("/");
|
|
278
|
-
return parts[parts.length - 1];
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// src/utils/pattern-utils.ts
|
|
282
|
-
var import_minimatch = require("minimatch");
|
|
283
|
-
function isValidGlobPattern(pattern) {
|
|
284
|
-
try {
|
|
285
|
-
new import_minimatch.minimatch.Minimatch(pattern);
|
|
286
|
-
return true;
|
|
287
|
-
} catch {
|
|
288
|
-
return false;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
function isGlobPattern(pattern) {
|
|
292
|
-
return /[*?[\]{}!]/.test(pattern);
|
|
293
|
-
}
|
|
294
|
-
function stripPrefix(input, pattern, ensureLeadingChar) {
|
|
295
|
-
if (!pattern) {
|
|
296
|
-
return input;
|
|
297
|
-
}
|
|
298
|
-
if (isGlobPattern(pattern) && !isValidGlobPattern(pattern)) {
|
|
299
|
-
console.warn(`\u26A0\uFE0F Invalid glob pattern "${pattern}": Pattern is malformed`);
|
|
300
|
-
return input;
|
|
301
|
-
}
|
|
302
|
-
if (isGlobPattern(pattern)) {
|
|
303
|
-
let longestMatch = -1;
|
|
304
|
-
for (let i = 1; i <= input.length; i++) {
|
|
305
|
-
const testPrefix = input.substring(0, i);
|
|
306
|
-
if ((0, import_minimatch.minimatch)(testPrefix, pattern)) {
|
|
307
|
-
longestMatch = i;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
if (longestMatch > 0) {
|
|
311
|
-
const stripped = input.substring(longestMatch);
|
|
312
|
-
if (ensureLeadingChar) {
|
|
313
|
-
if (stripped === "") {
|
|
314
|
-
return ensureLeadingChar;
|
|
315
|
-
}
|
|
316
|
-
if (!stripped.startsWith(ensureLeadingChar)) {
|
|
317
|
-
return `${ensureLeadingChar}${stripped}`;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
return stripped === "" && !ensureLeadingChar ? input : stripped;
|
|
321
|
-
}
|
|
322
|
-
return input;
|
|
323
|
-
}
|
|
324
|
-
if (input.startsWith(pattern)) {
|
|
325
|
-
const stripped = input.substring(pattern.length);
|
|
326
|
-
if (ensureLeadingChar) {
|
|
327
|
-
if (stripped === "") {
|
|
328
|
-
return ensureLeadingChar;
|
|
329
|
-
}
|
|
330
|
-
if (!stripped.startsWith(ensureLeadingChar)) {
|
|
331
|
-
return `${ensureLeadingChar}${stripped}`;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
return stripped;
|
|
335
|
-
}
|
|
336
|
-
return input;
|
|
337
|
-
}
|
|
338
|
-
function stripPathPrefix(path, pattern) {
|
|
339
|
-
if (!pattern) {
|
|
340
|
-
return path;
|
|
341
|
-
}
|
|
342
|
-
if (!isGlobPattern(pattern)) {
|
|
343
|
-
let normalizedPattern = pattern.trim();
|
|
344
|
-
if (!normalizedPattern.startsWith("/")) {
|
|
345
|
-
normalizedPattern = `/${normalizedPattern}`;
|
|
346
|
-
}
|
|
347
|
-
if (normalizedPattern.endsWith("/") && normalizedPattern !== "/") {
|
|
348
|
-
normalizedPattern = normalizedPattern.slice(0, -1);
|
|
349
|
-
}
|
|
350
|
-
return stripPrefix(path, normalizedPattern, "/");
|
|
351
|
-
}
|
|
352
|
-
return stripPrefix(path, pattern, "/");
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
// src/utils/string-utils.ts
|
|
356
|
-
function escapeDescription(str) {
|
|
357
|
-
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
358
|
-
}
|
|
359
|
-
function escapePattern(str) {
|
|
360
|
-
return str.replace(/(?<!\\)\//g, "\\/");
|
|
361
|
-
}
|
|
362
|
-
function escapeJSDoc(str) {
|
|
363
|
-
return str.replace(/\*\//g, "*\\/");
|
|
364
|
-
}
|
|
365
|
-
function wrapNullable(validation, isNullable2) {
|
|
366
|
-
return isNullable2 ? `${validation}.nullable()` : validation;
|
|
367
|
-
}
|
|
368
|
-
function isNullable(schema, defaultNullable = false) {
|
|
369
|
-
if (schema.nullable === true) {
|
|
370
|
-
return true;
|
|
371
|
-
}
|
|
372
|
-
if (schema.nullable === false) {
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
if (Array.isArray(schema.type)) {
|
|
376
|
-
return schema.type.includes("null");
|
|
377
|
-
}
|
|
378
|
-
return defaultNullable;
|
|
379
|
-
}
|
|
380
|
-
function getPrimaryType(schema) {
|
|
381
|
-
if (Array.isArray(schema.type)) {
|
|
382
|
-
const nonNullType = schema.type.find((t) => t !== "null");
|
|
383
|
-
return nonNullType;
|
|
384
|
-
}
|
|
385
|
-
return schema.type;
|
|
386
|
-
}
|
|
387
|
-
function hasMultipleTypes(schema) {
|
|
388
|
-
if (Array.isArray(schema.type)) {
|
|
389
|
-
const nonNullTypes = schema.type.filter((t) => t !== "null");
|
|
390
|
-
return nonNullTypes.length > 1;
|
|
391
|
-
}
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
function addDescription(validation, description, useDescribe) {
|
|
395
|
-
if (!description || !useDescribe) return validation;
|
|
396
|
-
const escapedDesc = escapeDescription(description);
|
|
397
|
-
return `${validation}.describe("${escapedDesc}")`;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// src/validators/array-validator.ts
|
|
401
|
-
function generateArrayValidation(schema, context) {
|
|
402
|
-
var _a;
|
|
403
|
-
let validation;
|
|
404
|
-
if (schema.prefixItems && schema.prefixItems.length > 0) {
|
|
405
|
-
const tupleItems = schema.prefixItems.map((item) => context.generatePropertySchema(item, context.currentSchema));
|
|
406
|
-
validation = `z.tuple([${tupleItems.join(", ")}])`;
|
|
407
|
-
if (schema.items) {
|
|
408
|
-
const restSchema = context.generatePropertySchema(schema.items, context.currentSchema);
|
|
409
|
-
validation += `.rest(${restSchema})`;
|
|
410
|
-
} else if (schema.unevaluatedItems && typeof schema.unevaluatedItems === "object") {
|
|
411
|
-
const restSchema = context.generatePropertySchema(schema.unevaluatedItems, context.currentSchema);
|
|
412
|
-
validation += `.rest(${restSchema})`;
|
|
413
|
-
}
|
|
414
|
-
} else if (schema.items) {
|
|
415
|
-
const itemSchema = context.generatePropertySchema(schema.items, context.currentSchema);
|
|
416
|
-
validation = `z.array(${itemSchema})`;
|
|
417
|
-
if (schema.minItems !== void 0) {
|
|
418
|
-
validation += `.min(${schema.minItems})`;
|
|
419
|
-
}
|
|
420
|
-
if (schema.maxItems !== void 0) {
|
|
421
|
-
validation += `.max(${schema.maxItems})`;
|
|
422
|
-
}
|
|
423
|
-
if (schema.uniqueItems === true) {
|
|
424
|
-
validation += `.refine((items) => new Set(items).size === items.length, { message: "Array items must be unique" })`;
|
|
425
|
-
}
|
|
426
|
-
} else {
|
|
427
|
-
validation = "z.array(z.unknown())";
|
|
428
|
-
}
|
|
429
|
-
if (schema.contains) {
|
|
430
|
-
const containsSchema = context.generatePropertySchema(schema.contains, context.currentSchema);
|
|
431
|
-
const minCount = (_a = schema.minContains) != null ? _a : 1;
|
|
432
|
-
const maxCount = schema.maxContains;
|
|
433
|
-
if (maxCount !== void 0) {
|
|
434
|
-
validation += `.refine((arr) => { const matches = arr.filter(item => ${containsSchema}.safeParse(item).success); return matches.length >= ${minCount} && matches.length <= ${maxCount}; }, { message: "Array must contain between ${minCount} and ${maxCount} items matching the schema" })`;
|
|
435
|
-
} else {
|
|
436
|
-
validation += `.refine((arr) => arr.filter(item => ${containsSchema}.safeParse(item).success).length >= ${minCount}, { message: "Array must contain at least ${minCount} item(s) matching the schema" })`;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
if (schema.unevaluatedItems === false && schema.prefixItems && schema.prefixItems.length > 0 && !schema.items) {
|
|
440
|
-
const prefixCount = schema.prefixItems.length;
|
|
441
|
-
validation += `.refine((arr) => arr.length <= ${prefixCount}, { message: "No unevaluated items allowed beyond prefix items" })`;
|
|
442
|
-
}
|
|
443
|
-
return addDescription(validation, schema.description, context.useDescribe);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// src/validators/composition-validator.ts
|
|
447
|
-
function isDiscriminatorRequired(schemas, discriminator, context) {
|
|
448
|
-
const invalidSchemas = [];
|
|
449
|
-
for (const schema of schemas) {
|
|
450
|
-
const resolved = resolveSchema(schema, context);
|
|
451
|
-
const required = resolved.required || [];
|
|
452
|
-
if (!required.includes(discriminator)) {
|
|
453
|
-
const schemaName = schema.$ref ? schema.$ref.split("/").pop() || "inline" : "inline";
|
|
454
|
-
invalidSchemas.push(schemaName);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
return {
|
|
458
|
-
valid: invalidSchemas.length === 0,
|
|
459
|
-
invalidSchemas
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
function generateUnion(schemas, discriminator, isNullable2, context, options, currentSchema) {
|
|
463
|
-
if (schemas.length === 0) {
|
|
464
|
-
console.warn(
|
|
465
|
-
"[openapi-to-zod] Warning: Empty oneOf/anyOf array encountered. This is likely a malformed OpenAPI spec. Generating z.never() as fallback."
|
|
466
|
-
);
|
|
467
|
-
return wrapNullable(
|
|
468
|
-
'z.never().describe("Empty oneOf/anyOf in OpenAPI spec - no valid schema defined")',
|
|
469
|
-
isNullable2
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
if (schemas.length === 1) {
|
|
473
|
-
let singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
|
|
474
|
-
if ((options == null ? void 0 : options.passthrough) && !singleSchema.includes(".catchall(")) {
|
|
475
|
-
singleSchema = `${singleSchema}.catchall(z.unknown())`;
|
|
476
|
-
}
|
|
477
|
-
return wrapNullable(singleSchema, isNullable2);
|
|
478
|
-
}
|
|
479
|
-
if (discriminator) {
|
|
480
|
-
let resolvedSchemas = schemas;
|
|
481
|
-
if ((options == null ? void 0 : options.discriminatorMapping) && context.resolveDiscriminatorMapping) {
|
|
482
|
-
resolvedSchemas = context.resolveDiscriminatorMapping(options.discriminatorMapping, schemas);
|
|
483
|
-
}
|
|
484
|
-
const discriminatorCheck = isDiscriminatorRequired(resolvedSchemas, discriminator, context);
|
|
485
|
-
if (!discriminatorCheck.valid) {
|
|
486
|
-
console.warn(
|
|
487
|
-
`[openapi-to-zod] Warning: Discriminator "${discriminator}" is not required in schemas: ${discriminatorCheck.invalidSchemas.join(", ")}. Falling back to z.union() instead of z.discriminatedUnion().`
|
|
488
|
-
);
|
|
489
|
-
let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
|
|
490
|
-
if (options == null ? void 0 : options.passthrough) {
|
|
491
|
-
schemaStrings3 = schemaStrings3.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
|
|
492
|
-
}
|
|
493
|
-
const fallbackDescription = `Discriminator "${discriminator}" is optional in some schemas (${discriminatorCheck.invalidSchemas.join(", ")}), using z.union() instead of z.discriminatedUnion()`;
|
|
494
|
-
const union3 = `z.union([${schemaStrings3.join(", ")}]).describe("${fallbackDescription}")`;
|
|
495
|
-
return wrapNullable(union3, isNullable2);
|
|
496
|
-
}
|
|
497
|
-
let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
|
|
498
|
-
if (options == null ? void 0 : options.passthrough) {
|
|
499
|
-
schemaStrings2 = schemaStrings2.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
|
|
500
|
-
}
|
|
501
|
-
const union2 = `z.discriminatedUnion("${discriminator}", [${schemaStrings2.join(", ")}])`;
|
|
502
|
-
return wrapNullable(union2, isNullable2);
|
|
503
|
-
}
|
|
504
|
-
let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
|
|
505
|
-
if (options == null ? void 0 : options.passthrough) {
|
|
506
|
-
schemaStrings = schemaStrings.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
|
|
507
|
-
}
|
|
508
|
-
const union = `z.union([${schemaStrings.join(", ")}])`;
|
|
509
|
-
return wrapNullable(union, isNullable2);
|
|
510
|
-
}
|
|
511
|
-
function resolveSchema(schema, context) {
|
|
512
|
-
if (schema.$ref && context.resolveSchemaRef) {
|
|
513
|
-
const resolved = context.resolveSchemaRef(schema.$ref);
|
|
514
|
-
if (resolved) {
|
|
515
|
-
return resolved;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
return schema;
|
|
519
|
-
}
|
|
520
|
-
function collectProperties(schema, context) {
|
|
521
|
-
const resolved = resolveSchema(schema, context);
|
|
522
|
-
const props = /* @__PURE__ */ new Map();
|
|
523
|
-
const sourceName = schema.$ref ? schema.$ref.split("/").pop() || "unknown" : "inline";
|
|
524
|
-
if (resolved.properties) {
|
|
525
|
-
for (const [key, value] of Object.entries(resolved.properties)) {
|
|
526
|
-
props.set(key, { schema: value, source: sourceName });
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
if (resolved.allOf) {
|
|
530
|
-
for (const subSchema of resolved.allOf) {
|
|
531
|
-
const subProps = collectProperties(subSchema, context);
|
|
532
|
-
for (const [key, value] of subProps) {
|
|
533
|
-
if (!props.has(key)) {
|
|
534
|
-
props.set(key, value);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
return props;
|
|
540
|
-
}
|
|
541
|
-
function schemasMatch(a, b) {
|
|
542
|
-
return JSON.stringify(a) === JSON.stringify(b);
|
|
543
|
-
}
|
|
544
|
-
function detectConflictingProperties(schemas, context) {
|
|
545
|
-
const conflicts = [];
|
|
546
|
-
const propertyMap = /* @__PURE__ */ new Map();
|
|
547
|
-
for (const schema of schemas) {
|
|
548
|
-
const schemaProps = collectProperties(schema, context);
|
|
549
|
-
for (const [propName, propInfo] of schemaProps) {
|
|
550
|
-
const existing = propertyMap.get(propName);
|
|
551
|
-
if (existing) {
|
|
552
|
-
if (!schemasMatch(existing.schema, propInfo.schema)) {
|
|
553
|
-
conflicts.push(
|
|
554
|
-
`Property "${propName}" has conflicting definitions in ${existing.source} and ${propInfo.source}`
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
} else {
|
|
558
|
-
propertyMap.set(propName, propInfo);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
return conflicts;
|
|
563
|
-
}
|
|
564
|
-
function generateAllOf(schemas, isNullable2, context, currentSchema) {
|
|
565
|
-
if (schemas.length === 1) {
|
|
566
|
-
const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
|
|
567
|
-
return wrapNullable(singleSchema, isNullable2);
|
|
568
|
-
}
|
|
569
|
-
const conflicts = detectConflictingProperties(schemas, context);
|
|
570
|
-
let conflictDescription = "";
|
|
571
|
-
if (conflicts.length > 0) {
|
|
572
|
-
for (const conflict of conflicts) {
|
|
573
|
-
console.warn(`[openapi-to-zod] Warning: allOf composition conflict - ${conflict}`);
|
|
574
|
-
}
|
|
575
|
-
conflictDescription = `allOf property conflicts detected: ${conflicts.join("; ")}`;
|
|
576
|
-
}
|
|
577
|
-
const allObjects = schemas.every((s) => s.type === "object" || s.properties || s.$ref || s.allOf);
|
|
578
|
-
let result;
|
|
579
|
-
if (allObjects) {
|
|
580
|
-
let merged = context.generatePropertySchema(schemas[0], currentSchema, false, true);
|
|
581
|
-
for (let i = 1; i < schemas.length; i++) {
|
|
582
|
-
const schema = schemas[i];
|
|
583
|
-
if (schema.$ref) {
|
|
584
|
-
const refSchema = context.generatePropertySchema(schema, currentSchema, false, true);
|
|
585
|
-
merged = `${merged}.extend(${refSchema}.shape)`;
|
|
586
|
-
} else if (context.generateInlineObjectShape && (schema.properties || schema.type === "object")) {
|
|
587
|
-
const inlineShape = context.generateInlineObjectShape(schema, currentSchema);
|
|
588
|
-
merged = `${merged}.extend(${inlineShape})`;
|
|
589
|
-
} else {
|
|
590
|
-
const schemaString = context.generatePropertySchema(schema, currentSchema, false, true);
|
|
591
|
-
merged = `${merged}.extend(${schemaString}.shape)`;
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
result = merged;
|
|
595
|
-
} else {
|
|
596
|
-
const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
|
|
597
|
-
let merged = schemaStrings[0];
|
|
598
|
-
for (let i = 1; i < schemaStrings.length; i++) {
|
|
599
|
-
merged = `${merged}.and(${schemaStrings[i]})`;
|
|
600
|
-
}
|
|
601
|
-
result = merged;
|
|
602
|
-
}
|
|
603
|
-
if (conflictDescription) {
|
|
604
|
-
result = `${result}.describe("${conflictDescription}")`;
|
|
605
|
-
}
|
|
606
|
-
return wrapNullable(result, isNullable2);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
// src/validators/number-validator.ts
|
|
610
|
-
function generateNumberValidation(schema, isInt, useDescribe) {
|
|
611
|
-
let validation = isInt ? "z.number().int()" : "z.number()";
|
|
612
|
-
if (schema.minimum !== void 0) {
|
|
613
|
-
const isExclusive = schema.exclusiveMinimum === true;
|
|
614
|
-
validation += isExclusive ? `.gt(${schema.minimum})` : `.gte(${schema.minimum})`;
|
|
615
|
-
} else if (typeof schema.exclusiveMinimum === "number") {
|
|
616
|
-
validation += `.gt(${schema.exclusiveMinimum})`;
|
|
617
|
-
}
|
|
618
|
-
if (schema.maximum !== void 0) {
|
|
619
|
-
const isExclusive = schema.exclusiveMaximum === true;
|
|
620
|
-
validation += isExclusive ? `.lt(${schema.maximum})` : `.lte(${schema.maximum})`;
|
|
621
|
-
} else if (typeof schema.exclusiveMaximum === "number") {
|
|
622
|
-
validation += `.lt(${schema.exclusiveMaximum})`;
|
|
623
|
-
}
|
|
624
|
-
if (schema.multipleOf !== void 0) {
|
|
625
|
-
validation += `.multipleOf(${schema.multipleOf})`;
|
|
626
|
-
}
|
|
627
|
-
return addDescription(validation, schema.description, useDescribe);
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// src/generators/jsdoc-generator.ts
|
|
631
|
-
function generateJSDoc(schema, name, options = { includeDescriptions: true }) {
|
|
632
|
-
if (!schema || typeof schema !== "object") {
|
|
633
|
-
return "";
|
|
634
|
-
}
|
|
635
|
-
if (!options.includeDescriptions) {
|
|
636
|
-
if (schema.deprecated) {
|
|
637
|
-
return "/** @deprecated */\n";
|
|
638
|
-
}
|
|
639
|
-
return "";
|
|
640
|
-
}
|
|
641
|
-
if (!schema.description && !schema.title && !schema.deprecated && !schema.examples && schema.example === void 0) {
|
|
642
|
-
return "";
|
|
643
|
-
}
|
|
644
|
-
const parts = [];
|
|
645
|
-
if (schema.title && typeof schema.title === "string" && (!name || schema.title !== name)) {
|
|
646
|
-
const sanitizedTitle = escapeJSDoc(schema.title).replace(/@/g, "\\@");
|
|
647
|
-
parts.push(sanitizedTitle);
|
|
648
|
-
}
|
|
649
|
-
if (schema.description && typeof schema.description === "string") {
|
|
650
|
-
const sanitizedDesc = escapeJSDoc(schema.description).replace(/@/g, "\\@").replace(/\*\//g, "*\\/");
|
|
651
|
-
parts.push(sanitizedDesc);
|
|
652
|
-
}
|
|
653
|
-
if (schema.examples && Array.isArray(schema.examples) && schema.examples.length > 0) {
|
|
654
|
-
try {
|
|
655
|
-
const examplesStr = schema.examples.map((ex) => JSON.stringify(ex)).join(", ");
|
|
656
|
-
parts.push(`@example ${examplesStr}`);
|
|
657
|
-
} catch (error) {
|
|
658
|
-
console.warn("Warning: Could not serialize schema examples", error);
|
|
659
|
-
}
|
|
660
|
-
} else if (schema.example !== void 0) {
|
|
661
|
-
try {
|
|
662
|
-
parts.push(`@example ${JSON.stringify(schema.example)}`);
|
|
663
|
-
} catch (error) {
|
|
664
|
-
console.warn("Warning: Could not serialize schema example", error);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
if (schema.deprecated) {
|
|
668
|
-
parts.push("@deprecated");
|
|
669
|
-
}
|
|
670
|
-
if (parts.length === 0) {
|
|
671
|
-
return "";
|
|
672
|
-
}
|
|
673
|
-
const fullComment = parts.join(" ");
|
|
674
|
-
return `/** ${fullComment} */
|
|
675
|
-
`;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
// src/validators/conditional-validator.ts
|
|
679
|
-
function generatePropertyAccess(propName) {
|
|
680
|
-
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
681
|
-
return validIdentifier.test(propName) ? `obj.${propName}` : `obj["${propName}"]`;
|
|
682
|
-
}
|
|
683
|
-
function generateDependencies(schema, generatePropertySchema, currentSchema) {
|
|
684
|
-
if (!schema.dependencies) {
|
|
685
|
-
return "";
|
|
686
|
-
}
|
|
687
|
-
let result = "";
|
|
688
|
-
for (const [prop, dependency] of Object.entries(schema.dependencies)) {
|
|
689
|
-
if (Array.isArray(dependency)) {
|
|
690
|
-
if (dependency.length === 0) {
|
|
691
|
-
continue;
|
|
692
|
-
}
|
|
693
|
-
const propAccess = generatePropertyAccess(prop);
|
|
694
|
-
const checkLogic = dependency.map((p) => {
|
|
695
|
-
const pAccess = generatePropertyAccess(p);
|
|
696
|
-
return `if (${pAccess} === undefined) missing.push('${p}');`;
|
|
697
|
-
}).join("\n ");
|
|
698
|
-
result += `.superRefine((obj, ctx) => {
|
|
699
|
-
if (${propAccess} === undefined) return;
|
|
700
|
-
const missing: string[] = [];
|
|
701
|
-
${checkLogic}
|
|
702
|
-
if (missing.length > 0) {
|
|
703
|
-
ctx.addIssue({
|
|
704
|
-
code: "custom",
|
|
705
|
-
message: \`When '${prop}' is present, the following properties are required: \${missing.join(', ')}\`,
|
|
706
|
-
path: []
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
})`;
|
|
710
|
-
} else if (generatePropertySchema) {
|
|
711
|
-
const depSchema = { ...dependency, type: dependency.type || "object" };
|
|
712
|
-
const depSchemaValidation = generatePropertySchema(depSchema, currentSchema);
|
|
713
|
-
const propAccess = generatePropertyAccess(prop);
|
|
714
|
-
result += `.superRefine((obj, ctx) => {
|
|
715
|
-
if (${propAccess} === undefined) return;
|
|
716
|
-
const validation = ${depSchemaValidation}.safeParse(obj);
|
|
717
|
-
if (!validation.success) {
|
|
718
|
-
const errors = validation.error.issues.map(i => \` - \${i.path.join('.')}: \${i.message}\`).join('\\n');
|
|
719
|
-
ctx.addIssue({
|
|
720
|
-
code: "custom",
|
|
721
|
-
message: \`When '${prop}' is present, object must satisfy additional constraints:\\n\${errors}\`,
|
|
722
|
-
path: []
|
|
723
|
-
});
|
|
724
|
-
}
|
|
725
|
-
})`;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
return result;
|
|
729
|
-
}
|
|
730
|
-
function generateConditionalCheck(schema) {
|
|
731
|
-
const conditions = [];
|
|
732
|
-
if (schema.properties) {
|
|
733
|
-
for (const [prop, propSchema] of Object.entries(schema.properties)) {
|
|
734
|
-
const propAccess = generatePropertyAccess(prop);
|
|
735
|
-
if (propSchema.type) {
|
|
736
|
-
conditions.push(`typeof ${propAccess} === "${propSchema.type}"`);
|
|
737
|
-
}
|
|
738
|
-
if (propSchema.const !== void 0) {
|
|
739
|
-
const value = typeof propSchema.const === "string" ? `"${propSchema.const}"` : propSchema.const;
|
|
740
|
-
conditions.push(`${propAccess} === ${value}`);
|
|
741
|
-
}
|
|
742
|
-
if (propSchema.minimum !== void 0) {
|
|
743
|
-
conditions.push(`${propAccess} >= ${propSchema.minimum}`);
|
|
744
|
-
}
|
|
745
|
-
if (propSchema.maximum !== void 0) {
|
|
746
|
-
conditions.push(`${propAccess} <= ${propSchema.maximum}`);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
if (schema.required) {
|
|
751
|
-
for (const prop of schema.required) {
|
|
752
|
-
conditions.push(`${generatePropertyAccess(prop)} !== undefined`);
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
return conditions.length > 0 ? conditions.join(" && ") : "true";
|
|
756
|
-
}
|
|
757
|
-
function generateConditionalValidation(schema) {
|
|
758
|
-
const checks = [];
|
|
759
|
-
if (schema.required) {
|
|
760
|
-
for (const prop of schema.required) {
|
|
761
|
-
checks.push(`${generatePropertyAccess(prop)} !== undefined`);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
if (schema.properties) {
|
|
765
|
-
for (const [prop, propSchema] of Object.entries(schema.properties)) {
|
|
766
|
-
const propAccess = generatePropertyAccess(prop);
|
|
767
|
-
if (propSchema.minimum !== void 0) {
|
|
768
|
-
checks.push(`${propAccess} === undefined || ${propAccess} >= ${propSchema.minimum}`);
|
|
769
|
-
}
|
|
770
|
-
if (propSchema.maximum !== void 0) {
|
|
771
|
-
checks.push(`${propAccess} === undefined || ${propAccess} <= ${propSchema.maximum}`);
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
return checks.length > 0 ? checks.join(" && ") : "true";
|
|
776
|
-
}
|
|
777
|
-
function generateIfThenElse(schema) {
|
|
778
|
-
if (!schema.if || !schema.then && !schema.else) {
|
|
779
|
-
return "";
|
|
780
|
-
}
|
|
781
|
-
const ifCondition = generateConditionalCheck(schema.if);
|
|
782
|
-
if (schema.then && schema.else) {
|
|
783
|
-
const thenValidation = generateConditionalValidation(schema.then);
|
|
784
|
-
const elseValidation2 = generateConditionalValidation(schema.else);
|
|
785
|
-
const thenRequiredProps = schema.then.required || [];
|
|
786
|
-
const elseRequiredProps2 = schema.else.required || [];
|
|
787
|
-
return `.superRefine((obj, ctx) => {
|
|
788
|
-
const ifConditionMet = ${ifCondition};
|
|
789
|
-
if (ifConditionMet) {
|
|
790
|
-
// Then branch
|
|
791
|
-
const thenValid = ${thenValidation};
|
|
792
|
-
if (!thenValid) {
|
|
793
|
-
${thenRequiredProps.length > 0 ? `
|
|
794
|
-
const missingThenProps = ${JSON.stringify(thenRequiredProps)}.filter(p => obj[p] === undefined);
|
|
795
|
-
const message = missingThenProps.length > 0
|
|
796
|
-
? \`When condition is met, required properties are missing: \${missingThenProps.join(', ')}\`
|
|
797
|
-
: "When condition is met, validation constraints failed";
|
|
798
|
-
` : `
|
|
799
|
-
const message = "When condition is met, validation constraints failed";
|
|
800
|
-
`}
|
|
801
|
-
ctx.addIssue({
|
|
802
|
-
code: "custom",
|
|
803
|
-
message: message,
|
|
804
|
-
path: []
|
|
805
|
-
});
|
|
806
|
-
}
|
|
807
|
-
} else {
|
|
808
|
-
// Else branch
|
|
809
|
-
const elseValid = ${elseValidation2};
|
|
810
|
-
if (!elseValid) {
|
|
811
|
-
${elseRequiredProps2.length > 0 ? `
|
|
812
|
-
const missingElseProps = ${JSON.stringify(elseRequiredProps2)}.filter(p => obj[p] === undefined);
|
|
813
|
-
const message = missingElseProps.length > 0
|
|
814
|
-
? \`When condition is not met, required properties are missing: \${missingElseProps.join(', ')}\`
|
|
815
|
-
: "When condition is not met, validation constraints failed";
|
|
816
|
-
` : `
|
|
817
|
-
const message = "When condition is not met, validation constraints failed";
|
|
818
|
-
`}
|
|
819
|
-
ctx.addIssue({
|
|
820
|
-
code: "custom",
|
|
821
|
-
message: message,
|
|
822
|
-
path: []
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
})`;
|
|
827
|
-
}
|
|
828
|
-
if (schema.then) {
|
|
829
|
-
const thenValidation = generateConditionalValidation(schema.then);
|
|
830
|
-
const thenRequiredProps = schema.then.required || [];
|
|
831
|
-
return `.superRefine((obj, ctx) => {
|
|
832
|
-
const ifConditionMet = ${ifCondition};
|
|
833
|
-
if (ifConditionMet) {
|
|
834
|
-
const thenValid = ${thenValidation};
|
|
835
|
-
if (!thenValid) {
|
|
836
|
-
${thenRequiredProps.length > 0 ? `
|
|
837
|
-
const missingProps = ${JSON.stringify(thenRequiredProps)}.filter(p => obj[p] === undefined);
|
|
838
|
-
const message = missingProps.length > 0
|
|
839
|
-
? \`When condition is met, required properties are missing: \${missingProps.join(', ')}\`
|
|
840
|
-
: "When condition is met, validation constraints failed";
|
|
841
|
-
` : `
|
|
842
|
-
const message = "When condition is met, validation constraints failed";
|
|
843
|
-
`}
|
|
844
|
-
ctx.addIssue({
|
|
845
|
-
code: "custom",
|
|
846
|
-
message: message,
|
|
847
|
-
path: []
|
|
848
|
-
});
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
})`;
|
|
852
|
-
}
|
|
853
|
-
if (!schema.else) return "";
|
|
854
|
-
const elseValidation = generateConditionalValidation(schema.else);
|
|
855
|
-
const elseRequiredProps = schema.else.required || [];
|
|
856
|
-
return `.superRefine((obj, ctx) => {
|
|
857
|
-
const ifConditionMet = ${ifCondition};
|
|
858
|
-
if (!ifConditionMet) {
|
|
859
|
-
const elseValid = ${elseValidation};
|
|
860
|
-
if (!elseValid) {
|
|
861
|
-
${elseRequiredProps.length > 0 ? `
|
|
862
|
-
const missingProps = ${JSON.stringify(elseRequiredProps)}.filter(p => obj[p] === undefined);
|
|
863
|
-
const message = missingProps.length > 0
|
|
864
|
-
? \`When condition is not met, required properties are missing: \${missingProps.join(', ')}\`
|
|
865
|
-
: "When condition is not met, validation constraints failed";
|
|
866
|
-
` : `
|
|
867
|
-
const message = "When condition is not met, validation constraints failed";
|
|
868
|
-
`}
|
|
869
|
-
ctx.addIssue({
|
|
870
|
-
code: "custom",
|
|
871
|
-
message: message,
|
|
872
|
-
path: []
|
|
873
|
-
});
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
})`;
|
|
877
|
-
}
|
|
878
|
-
function generateDependentRequired(schema) {
|
|
879
|
-
if (!schema.dependentRequired) {
|
|
880
|
-
return "";
|
|
881
|
-
}
|
|
882
|
-
let result = "";
|
|
883
|
-
for (const [prop, requiredProps] of Object.entries(schema.dependentRequired)) {
|
|
884
|
-
if (requiredProps.length === 0) {
|
|
885
|
-
continue;
|
|
886
|
-
}
|
|
887
|
-
const propAccess = generatePropertyAccess(prop);
|
|
888
|
-
const checkLogic = requiredProps.map((rp) => {
|
|
889
|
-
const rpAccess = generatePropertyAccess(rp);
|
|
890
|
-
return `if (${rpAccess} === undefined) missing.push('${rp}');`;
|
|
891
|
-
}).join("\n ");
|
|
892
|
-
result += `.superRefine((obj, ctx) => {
|
|
893
|
-
if (${propAccess} === undefined) return;
|
|
894
|
-
const missing: string[] = [];
|
|
895
|
-
${checkLogic}
|
|
896
|
-
if (missing.length > 0) {
|
|
897
|
-
ctx.addIssue({
|
|
898
|
-
code: "custom",
|
|
899
|
-
message: \`When '${prop}' is present, the following properties are required: \${missing.join(', ')}\`,
|
|
900
|
-
path: []
|
|
901
|
-
});
|
|
902
|
-
}
|
|
903
|
-
})`;
|
|
904
|
-
}
|
|
905
|
-
return result;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
// src/validators/object-validator.ts
|
|
909
|
-
function needsQuoting(propName) {
|
|
910
|
-
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
911
|
-
return !validIdentifier.test(propName);
|
|
912
|
-
}
|
|
913
|
-
function generatePropertyAccess2(propName) {
|
|
914
|
-
return needsQuoting(propName) ? `obj["${propName}"]` : `obj.${propName}`;
|
|
915
|
-
}
|
|
916
|
-
function generateObjectSchema(schema, context, currentSchema) {
|
|
917
|
-
const required = new Set(schema.required || []);
|
|
918
|
-
const properties = [];
|
|
919
|
-
if (schema.properties) {
|
|
920
|
-
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
921
|
-
if (!context.shouldIncludeProperty(propSchema)) {
|
|
922
|
-
continue;
|
|
923
|
-
}
|
|
924
|
-
const isRequired = required.has(propName);
|
|
925
|
-
const zodSchema = context.generatePropertySchema(propSchema, currentSchema);
|
|
926
|
-
const quotedPropName = needsQuoting(propName) ? `"${propName}"` : propName;
|
|
927
|
-
let propertyDef = ` ${quotedPropName}: ${zodSchema}`;
|
|
928
|
-
if (!isRequired) {
|
|
929
|
-
propertyDef += ".optional()";
|
|
930
|
-
}
|
|
931
|
-
const jsdoc = generateJSDoc(propSchema, propName, { includeDescriptions: context.includeDescriptions });
|
|
932
|
-
if (jsdoc) {
|
|
933
|
-
properties.push(`${jsdoc.trimEnd()}
|
|
934
|
-
${propertyDef}`);
|
|
935
|
-
} else {
|
|
936
|
-
properties.push(propertyDef);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
let objectMethod;
|
|
941
|
-
if (schema.additionalProperties === false) {
|
|
942
|
-
objectMethod = "z.strictObject";
|
|
943
|
-
} else {
|
|
944
|
-
switch (context.mode) {
|
|
945
|
-
case "strict":
|
|
946
|
-
objectMethod = "z.strictObject";
|
|
947
|
-
break;
|
|
948
|
-
case "loose":
|
|
949
|
-
objectMethod = "z.looseObject";
|
|
950
|
-
break;
|
|
951
|
-
default:
|
|
952
|
-
objectMethod = "z.object";
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
let objectDef = `${objectMethod}({
|
|
956
|
-
${properties.join(",\n")}
|
|
957
|
-
})`;
|
|
958
|
-
if (schema.additionalProperties !== void 0) {
|
|
959
|
-
if (typeof schema.additionalProperties === "object") {
|
|
960
|
-
const additionalSchema = context.generatePropertySchema(schema.additionalProperties, currentSchema);
|
|
961
|
-
objectDef += `.catchall(${additionalSchema})`;
|
|
962
|
-
} else if (schema.additionalProperties === true) {
|
|
963
|
-
objectDef += ".catchall(z.unknown())";
|
|
964
|
-
}
|
|
965
|
-
} else if (schema.patternProperties) {
|
|
966
|
-
objectDef += ".catchall(z.unknown())";
|
|
967
|
-
}
|
|
968
|
-
if (schema.minProperties !== void 0 || schema.maxProperties !== void 0) {
|
|
969
|
-
const conditions = [];
|
|
970
|
-
if (schema.minProperties !== void 0) {
|
|
971
|
-
conditions.push(`Object.keys(obj).length >= ${schema.minProperties}`);
|
|
972
|
-
}
|
|
973
|
-
if (schema.maxProperties !== void 0) {
|
|
974
|
-
conditions.push(`Object.keys(obj).length <= ${schema.maxProperties}`);
|
|
975
|
-
}
|
|
976
|
-
const condition = conditions.join(" && ");
|
|
977
|
-
let message = "Object ";
|
|
978
|
-
if (schema.minProperties !== void 0 && schema.maxProperties !== void 0) {
|
|
979
|
-
message += `must have between ${schema.minProperties} and ${schema.maxProperties} properties`;
|
|
980
|
-
} else if (schema.minProperties !== void 0) {
|
|
981
|
-
message += `must have at least ${schema.minProperties} ${schema.minProperties === 1 ? "property" : "properties"}`;
|
|
982
|
-
} else {
|
|
983
|
-
message += `must have at most ${schema.maxProperties} ${schema.maxProperties === 1 ? "property" : "properties"}`;
|
|
984
|
-
}
|
|
985
|
-
objectDef += `.refine((obj) => ${condition}, { message: "${message}" })`;
|
|
986
|
-
}
|
|
987
|
-
const definedProps = new Set(Object.keys(schema.properties || {}));
|
|
988
|
-
const undefinedRequired = (schema.required || []).filter((prop) => !definedProps.has(prop));
|
|
989
|
-
if (undefinedRequired.length > 0) {
|
|
990
|
-
if (!objectDef.includes(".catchall(")) {
|
|
991
|
-
objectDef += ".catchall(z.unknown())";
|
|
992
|
-
}
|
|
993
|
-
const requiredChecks = undefinedRequired.map((prop) => `${generatePropertyAccess2(prop)} !== undefined`).join(" && ");
|
|
994
|
-
const propList = undefinedRequired.join(", ");
|
|
995
|
-
objectDef += `.refine((obj) => ${requiredChecks}, { message: "Missing required fields: ${propList}" })`;
|
|
996
|
-
}
|
|
997
|
-
if (schema.patternProperties) {
|
|
998
|
-
const definedProps2 = Object.keys(schema.properties || {});
|
|
999
|
-
const definedPropsSet = `new Set(${JSON.stringify(definedProps2)})`;
|
|
1000
|
-
const patterns = Object.entries(schema.patternProperties);
|
|
1001
|
-
const patternSchemas = patterns.map(([pattern, patternSchema]) => ({
|
|
1002
|
-
pattern,
|
|
1003
|
-
escapedPattern: pattern.replace(/\\/g, "\\\\").replace(/'/g, "\\'"),
|
|
1004
|
-
zodSchema: context.generatePropertySchema(patternSchema, currentSchema)
|
|
1005
|
-
}));
|
|
1006
|
-
objectDef += `.superRefine((obj, ctx) => {
|
|
1007
|
-
const definedPropsSet = ${definedPropsSet};
|
|
1008
|
-
const patterns = ${JSON.stringify(patternSchemas.map((p) => ({ pattern: p.escapedPattern })))};
|
|
1009
|
-
const schemas = [${patternSchemas.map((p) => p.zodSchema).join(", ")}];
|
|
1010
|
-
const regexps = patterns.map(p => new RegExp(p.pattern));
|
|
1011
|
-
|
|
1012
|
-
// Check all object keys
|
|
1013
|
-
for (const key of Object.keys(obj)) {
|
|
1014
|
-
// Skip properties that are explicitly defined
|
|
1015
|
-
if (definedPropsSet.has(key)) continue;
|
|
1016
|
-
|
|
1017
|
-
// Find first matching pattern (first-match-wins priority)
|
|
1018
|
-
for (let i = 0; i < regexps.length; i++) {
|
|
1019
|
-
if (regexps[i].test(key)) {
|
|
1020
|
-
const validation = schemas[i].safeParse(obj[key]);
|
|
1021
|
-
if (!validation.success) {
|
|
1022
|
-
// Add detailed error messages with property name and pattern
|
|
1023
|
-
for (const issue of validation.error.issues) {
|
|
1024
|
-
ctx.addIssue({
|
|
1025
|
-
...issue,
|
|
1026
|
-
path: [key, ...issue.path],
|
|
1027
|
-
message: \`Property '\${key}' (pattern '\${patterns[i].pattern}'): \${issue.message}\`
|
|
1028
|
-
});
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
break; // First match wins, stop checking other patterns
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
})`;
|
|
1036
|
-
}
|
|
1037
|
-
if (schema.propertyNames) {
|
|
1038
|
-
const hasPattern = schema.propertyNames.pattern !== void 0;
|
|
1039
|
-
const hasMinLength = schema.propertyNames.minLength !== void 0;
|
|
1040
|
-
const hasMaxLength = schema.propertyNames.maxLength !== void 0;
|
|
1041
|
-
if (hasPattern || hasMinLength || hasMaxLength) {
|
|
1042
|
-
const escapedPattern = hasPattern && schema.propertyNames.pattern ? schema.propertyNames.pattern.replace(/\\/g, "\\\\").replace(/'/g, "\\'") : null;
|
|
1043
|
-
const minLen = schema.propertyNames.minLength;
|
|
1044
|
-
const maxLen = schema.propertyNames.maxLength;
|
|
1045
|
-
objectDef += `.superRefine((obj, ctx) => {
|
|
1046
|
-
${escapedPattern ? `const pattern = /${escapedPattern}/;` : ""}
|
|
1047
|
-
|
|
1048
|
-
for (const key of Object.keys(obj)) {
|
|
1049
|
-
const failures: string[] = [];
|
|
1050
|
-
|
|
1051
|
-
${hasPattern ? `
|
|
1052
|
-
if (!pattern.test(key)) {
|
|
1053
|
-
failures.push("must match pattern '${schema.propertyNames.pattern}'");
|
|
1054
|
-
}
|
|
1055
|
-
` : ""}
|
|
1056
|
-
|
|
1057
|
-
${hasMinLength ? `
|
|
1058
|
-
if (key.length < ${minLen}) {
|
|
1059
|
-
failures.push("must be at least ${minLen} characters");
|
|
1060
|
-
}
|
|
1061
|
-
` : ""}
|
|
1062
|
-
|
|
1063
|
-
${hasMaxLength ? `
|
|
1064
|
-
if (key.length > ${maxLen}) {
|
|
1065
|
-
failures.push("must be at most ${maxLen} characters");
|
|
1066
|
-
}
|
|
1067
|
-
` : ""}
|
|
1068
|
-
|
|
1069
|
-
if (failures.length > 0) {
|
|
1070
|
-
ctx.addIssue({
|
|
1071
|
-
code: "custom",
|
|
1072
|
-
message: \`Property name '\${key}' \${failures.join(", ")}\`,
|
|
1073
|
-
path: [key]
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
})`;
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
objectDef += generateDependencies(schema, context.generatePropertySchema, currentSchema);
|
|
1081
|
-
objectDef += generateDependentRequired(schema);
|
|
1082
|
-
objectDef += generateIfThenElse(schema);
|
|
1083
|
-
return objectDef;
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
// src/validators/string-validator.ts
|
|
1087
|
-
var DEFAULT_FORMAT_MAP = {
|
|
1088
|
-
uuid: "z.uuid()",
|
|
1089
|
-
email: "z.email()",
|
|
1090
|
-
uri: "z.url()",
|
|
1091
|
-
url: "z.url()",
|
|
1092
|
-
"uri-reference": 'z.string().refine((val) => !/\\s/.test(val), { message: "Must be a valid URI reference" })',
|
|
1093
|
-
hostname: 'z.string().refine((val) => /^(?=.{1,253}$)(?:(?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)*(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/.test(val), { message: "Must be a valid hostname" })',
|
|
1094
|
-
byte: "z.base64()",
|
|
1095
|
-
binary: "z.string()",
|
|
1096
|
-
date: "z.iso.date()",
|
|
1097
|
-
time: "z.iso.time()",
|
|
1098
|
-
duration: 'z.string().refine((val) => /^P(?:(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?:\\d+H)?(?:\\d+M)?(?:\\d+(?:\\.\\d+)?S)?)?|\\d+W)$/.test(val) && !/^PT?$/.test(val), { message: "Must be a valid ISO 8601 duration" })',
|
|
1099
|
-
ipv4: "z.ipv4()",
|
|
1100
|
-
ipv6: "z.ipv6()",
|
|
1101
|
-
emoji: "z.emoji()",
|
|
1102
|
-
base64: "z.base64()",
|
|
1103
|
-
base64url: "z.base64url()",
|
|
1104
|
-
nanoid: "z.nanoid()",
|
|
1105
|
-
cuid: "z.cuid()",
|
|
1106
|
-
cuid2: "z.cuid2()",
|
|
1107
|
-
ulid: "z.ulid()",
|
|
1108
|
-
cidr: "z.cidrv4()",
|
|
1109
|
-
// Default to v4
|
|
1110
|
-
cidrv4: "z.cidrv4()",
|
|
1111
|
-
cidrv6: "z.cidrv6()",
|
|
1112
|
-
"json-pointer": 'z.string().refine((val) => val === "" || /^(\\/([^~/]|~0|~1)+)+$/.test(val), { message: "Must be a valid JSON Pointer (RFC 6901)" })',
|
|
1113
|
-
"relative-json-pointer": 'z.string().refine((val) => /^(0|[1-9]\\d*)(#|(\\/([^~/]|~0|~1)+)*)$/.test(val), { message: "Must be a valid relative JSON Pointer" })'
|
|
1114
|
-
};
|
|
1115
|
-
function buildDateTimeValidation(pattern) {
|
|
1116
|
-
if (!pattern) {
|
|
1117
|
-
return "z.iso.datetime()";
|
|
1118
|
-
}
|
|
1119
|
-
const patternStr = pattern instanceof RegExp ? pattern.source : pattern;
|
|
1120
|
-
if (patternStr === "") {
|
|
1121
|
-
return "z.iso.datetime()";
|
|
1122
|
-
}
|
|
1123
|
-
try {
|
|
1124
|
-
new RegExp(patternStr);
|
|
1125
|
-
} catch (error) {
|
|
1126
|
-
throw new Error(
|
|
1127
|
-
`Invalid regular expression pattern for customDateTimeFormatRegex: ${patternStr}. ${error instanceof Error ? error.message : "Pattern is malformed"}`
|
|
1128
|
-
);
|
|
1129
|
-
}
|
|
1130
|
-
const escapedPattern = escapePattern(patternStr);
|
|
1131
|
-
return `z.string().regex(/${escapedPattern}/)`;
|
|
1132
|
-
}
|
|
1133
|
-
function generateStringValidation(schema, useDescribe, context) {
|
|
1134
|
-
let validation;
|
|
1135
|
-
const format = schema.format || "";
|
|
1136
|
-
if (format === "date-time") {
|
|
1137
|
-
validation = context.dateTimeValidation;
|
|
1138
|
-
} else {
|
|
1139
|
-
validation = DEFAULT_FORMAT_MAP[format] || "z.string()";
|
|
1140
|
-
}
|
|
1141
|
-
if (schema.minLength !== void 0) {
|
|
1142
|
-
validation += `.min(${schema.minLength})`;
|
|
1143
|
-
}
|
|
1144
|
-
if (schema.maxLength !== void 0) {
|
|
1145
|
-
validation += `.max(${schema.maxLength})`;
|
|
1146
|
-
}
|
|
1147
|
-
if (schema.pattern) {
|
|
1148
|
-
let escapedPattern = context.patternCache.get(schema.pattern);
|
|
1149
|
-
if (escapedPattern === void 0) {
|
|
1150
|
-
escapedPattern = escapePattern(schema.pattern);
|
|
1151
|
-
context.patternCache.set(schema.pattern, escapedPattern);
|
|
1152
|
-
}
|
|
1153
|
-
validation += `.regex(/${escapedPattern}/)`;
|
|
1154
|
-
}
|
|
1155
|
-
if (schema.contentEncoding && !schema.format) {
|
|
1156
|
-
switch (schema.contentEncoding) {
|
|
1157
|
-
case "base64":
|
|
1158
|
-
validation = "z.base64()";
|
|
1159
|
-
break;
|
|
1160
|
-
case "base64url":
|
|
1161
|
-
validation = "z.base64url()";
|
|
1162
|
-
break;
|
|
1163
|
-
case "quoted-printable":
|
|
1164
|
-
validation = 'z.string().refine((val) => /^[\\x20-\\x7E\\r\\n=]*$/.test(val), { message: "Must be valid quoted-printable encoding" })';
|
|
1165
|
-
break;
|
|
1166
|
-
case "7bit":
|
|
1167
|
-
case "8bit":
|
|
1168
|
-
case "binary":
|
|
1169
|
-
validation = "z.string()";
|
|
1170
|
-
break;
|
|
1171
|
-
default:
|
|
1172
|
-
validation = `z.string().describe("Content encoding: ${schema.contentEncoding}")`;
|
|
1173
|
-
}
|
|
1174
|
-
if (schema.minLength !== void 0) {
|
|
1175
|
-
validation += `.min(${schema.minLength})`;
|
|
1176
|
-
}
|
|
1177
|
-
if (schema.maxLength !== void 0) {
|
|
1178
|
-
validation += `.max(${schema.maxLength})`;
|
|
1179
|
-
}
|
|
1180
|
-
if (schema.pattern) {
|
|
1181
|
-
let escapedPattern = context.patternCache.get(schema.pattern);
|
|
1182
|
-
if (escapedPattern === void 0) {
|
|
1183
|
-
escapedPattern = escapePattern(schema.pattern);
|
|
1184
|
-
context.patternCache.set(schema.pattern, escapedPattern);
|
|
1185
|
-
}
|
|
1186
|
-
validation += `.regex(/${escapedPattern}/)`;
|
|
1187
|
-
}
|
|
1188
|
-
} else if (schema.contentMediaType) {
|
|
1189
|
-
const mediaType = schema.contentMediaType;
|
|
1190
|
-
if (mediaType === "application/json") {
|
|
1191
|
-
validation += `.refine((val) => { try { JSON.parse(val); return true; } catch { return false; } }, { message: "Must be valid JSON" })`;
|
|
1192
|
-
} else if (mediaType === "application/xml" || mediaType === "text/xml") {
|
|
1193
|
-
validation += `.refine((val) => { try { if (typeof DOMParser !== "undefined") { const parser = new DOMParser(); const doc = parser.parseFromString(val, "text/xml"); return !doc.querySelector("parsererror"); } return /^\\s*<[^>]+>/.test(val); } catch { return false; } }, { message: "Must be valid XML" })`;
|
|
1194
|
-
} else if (mediaType === "application/yaml" || mediaType === "application/x-yaml" || mediaType === "text/yaml") {
|
|
1195
|
-
validation += `.refine((val) => { try { return val.trim().length > 0 && !/^[[{]/.test(val.trim()); } catch { return false; } }, { message: "Must be valid YAML" })`;
|
|
1196
|
-
} else if (mediaType === "text/html") {
|
|
1197
|
-
validation += `.refine((val) => /<[^>]+>/.test(val), { message: "Must contain HTML tags" })`;
|
|
1198
|
-
} else if (mediaType === "text/plain") {
|
|
1199
|
-
validation += `.refine(() => true, { message: "Plain text content" })`;
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
return addDescription(validation, schema.description, useDescribe);
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
// src/generators/property-generator.ts
|
|
1206
|
-
var _PropertyGenerator = class _PropertyGenerator {
|
|
1207
|
-
constructor(context) {
|
|
1208
|
-
// Performance optimization: Memoize filtered property results
|
|
1209
|
-
this.filteredPropsCache = /* @__PURE__ */ new Map();
|
|
1210
|
-
// Performance optimization: LRU cache for generated schemas
|
|
1211
|
-
this.schemaCache = new LRUCache(500);
|
|
1212
|
-
this.context = context;
|
|
1213
|
-
}
|
|
1214
|
-
/**
|
|
1215
|
-
* Check if a property should be included based on schemaType and readOnly/writeOnly flags
|
|
1216
|
-
*/
|
|
1217
|
-
shouldIncludeProperty(schema) {
|
|
1218
|
-
const rule = _PropertyGenerator.INCLUSION_RULES[this.context.schemaType];
|
|
1219
|
-
return rule(schema);
|
|
1220
|
-
}
|
|
1221
|
-
/**
|
|
1222
|
-
* Recursively filter any schema type (helper for composition schemas)
|
|
1223
|
-
*/
|
|
1224
|
-
filterSchemaRecursive(schema) {
|
|
1225
|
-
if (schema.$ref) {
|
|
1226
|
-
return schema;
|
|
1227
|
-
}
|
|
1228
|
-
if (schema.properties) {
|
|
1229
|
-
return this.filterNestedProperties(schema);
|
|
1230
|
-
}
|
|
1231
|
-
if (schema.type === "array" && schema.items && typeof schema.items === "object" && schema.items.properties) {
|
|
1232
|
-
return {
|
|
1233
|
-
...schema,
|
|
1234
|
-
items: this.filterNestedProperties(schema.items)
|
|
1235
|
-
};
|
|
1236
|
-
}
|
|
1237
|
-
return schema;
|
|
1238
|
-
}
|
|
1239
|
-
/**
|
|
1240
|
-
* Recursively filter properties in nested objects based on readOnly/writeOnly
|
|
1241
|
-
* Performance optimized with memoization
|
|
1242
|
-
*/
|
|
1243
|
-
filterNestedProperties(schema) {
|
|
1244
|
-
var _a, _b;
|
|
1245
|
-
const propKeys = schema.properties ? Object.keys(schema.properties).sort().join(",") : "";
|
|
1246
|
-
const cacheKey = `${this.context.schemaType}:${schema.type || "unknown"}:${propKeys}:${((_a = schema.required) == null ? void 0 : _a.join(",")) || ""}`;
|
|
1247
|
-
const cached = this.filteredPropsCache.get(cacheKey);
|
|
1248
|
-
if (cached) {
|
|
1249
|
-
return cached;
|
|
1250
|
-
}
|
|
1251
|
-
if (!schema.properties) {
|
|
1252
|
-
return schema;
|
|
1253
|
-
}
|
|
1254
|
-
const filteredProperties = {};
|
|
1255
|
-
const filteredRequired = [];
|
|
1256
|
-
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
1257
|
-
if (!this.shouldIncludeProperty(propSchema)) {
|
|
1258
|
-
continue;
|
|
1259
|
-
}
|
|
1260
|
-
let filteredPropSchema = propSchema;
|
|
1261
|
-
if (propSchema.type === "object" && propSchema.properties) {
|
|
1262
|
-
filteredPropSchema = this.filterNestedProperties(propSchema);
|
|
1263
|
-
} else if (propSchema.type === "array" && propSchema.items && typeof propSchema.items === "object" && propSchema.items.properties) {
|
|
1264
|
-
filteredPropSchema = {
|
|
1265
|
-
...propSchema,
|
|
1266
|
-
items: this.filterNestedProperties(propSchema.items)
|
|
1267
|
-
};
|
|
1268
|
-
} else if (propSchema.allOf || propSchema.oneOf || propSchema.anyOf) {
|
|
1269
|
-
if (propSchema.allOf) {
|
|
1270
|
-
filteredPropSchema = {
|
|
1271
|
-
...propSchema,
|
|
1272
|
-
allOf: propSchema.allOf.map((s) => this.filterSchemaRecursive(s))
|
|
1273
|
-
};
|
|
1274
|
-
} else if (propSchema.oneOf) {
|
|
1275
|
-
filteredPropSchema = {
|
|
1276
|
-
...propSchema,
|
|
1277
|
-
oneOf: propSchema.oneOf.map((s) => this.filterSchemaRecursive(s))
|
|
1278
|
-
};
|
|
1279
|
-
} else if (propSchema.anyOf) {
|
|
1280
|
-
filteredPropSchema = {
|
|
1281
|
-
...propSchema,
|
|
1282
|
-
anyOf: propSchema.anyOf.map((s) => this.filterSchemaRecursive(s))
|
|
1283
|
-
};
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
filteredProperties[propName] = filteredPropSchema;
|
|
1287
|
-
if ((_b = schema.required) == null ? void 0 : _b.includes(propName)) {
|
|
1288
|
-
filteredRequired.push(propName);
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
const result = {
|
|
1292
|
-
...schema,
|
|
1293
|
-
properties: filteredProperties,
|
|
1294
|
-
required: filteredRequired.length > 0 ? filteredRequired : void 0
|
|
1295
|
-
};
|
|
1296
|
-
this.filteredPropsCache.set(cacheKey, result);
|
|
1297
|
-
return result;
|
|
1298
|
-
}
|
|
1299
|
-
/**
|
|
1300
|
-
* Resolve discriminator mapping to actual schema references
|
|
1301
|
-
*/
|
|
1302
|
-
resolveDiscriminatorMapping(mapping, schemas) {
|
|
1303
|
-
const mappedSchemas = [];
|
|
1304
|
-
for (const [_, schemaRef] of Object.entries(mapping)) {
|
|
1305
|
-
const matchingSchema = schemas.find((s) => {
|
|
1306
|
-
if (s.$ref) {
|
|
1307
|
-
return s.$ref === schemaRef || s.$ref.endsWith(schemaRef);
|
|
1308
|
-
}
|
|
1309
|
-
return false;
|
|
1310
|
-
});
|
|
1311
|
-
if (matchingSchema) {
|
|
1312
|
-
mappedSchemas.push(matchingSchema);
|
|
1313
|
-
} else {
|
|
1314
|
-
mappedSchemas.push({ $ref: schemaRef });
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
for (const schema of schemas) {
|
|
1318
|
-
if (!mappedSchemas.includes(schema)) {
|
|
1319
|
-
mappedSchemas.push(schema);
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
return mappedSchemas;
|
|
1323
|
-
}
|
|
1324
|
-
/**
|
|
1325
|
-
* Resolve a $ref string to the actual schema
|
|
1326
|
-
*/
|
|
1327
|
-
resolveSchemaRef(ref) {
|
|
1328
|
-
var _a, _b;
|
|
1329
|
-
const schemaName = ref.split("/").pop();
|
|
1330
|
-
if (!schemaName) return void 0;
|
|
1331
|
-
return (_b = (_a = this.context.spec.components) == null ? void 0 : _a.schemas) == null ? void 0 : _b[schemaName];
|
|
1332
|
-
}
|
|
1333
|
-
/**
|
|
1334
|
-
* Resolve a schema name through any aliases to get the actual schema name
|
|
1335
|
-
* If the schema is an alias (allOf with single $ref), return the target name
|
|
1336
|
-
*/
|
|
1337
|
-
resolveSchemaAlias(schemaName) {
|
|
1338
|
-
var _a, _b;
|
|
1339
|
-
const schema = (_b = (_a = this.context.spec.components) == null ? void 0 : _a.schemas) == null ? void 0 : _b[schemaName];
|
|
1340
|
-
if (!schema) return schemaName;
|
|
1341
|
-
if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref && !schema.properties && !schema.oneOf && !schema.anyOf) {
|
|
1342
|
-
const targetName = resolveRef(schema.allOf[0].$ref);
|
|
1343
|
-
return this.resolveSchemaAlias(targetName);
|
|
1344
|
-
}
|
|
1345
|
-
return schemaName;
|
|
1346
|
-
}
|
|
1347
|
-
/**
|
|
1348
|
-
* Check if this is a circular dependency through aliases
|
|
1349
|
-
*/
|
|
1350
|
-
isCircularThroughAlias(fromSchema, toSchema) {
|
|
1351
|
-
var _a, _b;
|
|
1352
|
-
const toSchemaSpec = (_b = (_a = this.context.spec.components) == null ? void 0 : _a.schemas) == null ? void 0 : _b[toSchema];
|
|
1353
|
-
if (!toSchemaSpec) return false;
|
|
1354
|
-
if (toSchemaSpec.allOf && toSchemaSpec.allOf.length === 1 && toSchemaSpec.allOf[0].$ref) {
|
|
1355
|
-
const aliasTarget = resolveRef(toSchemaSpec.allOf[0].$ref);
|
|
1356
|
-
return aliasTarget === fromSchema;
|
|
1357
|
-
}
|
|
1358
|
-
return false;
|
|
1359
|
-
}
|
|
1360
|
-
/**
|
|
1361
|
-
* Generate union for multiple types (OpenAPI 3.1)
|
|
1362
|
-
*/
|
|
1363
|
-
generateMultiTypeUnion(schema, currentSchema) {
|
|
1364
|
-
if (!Array.isArray(schema.type)) {
|
|
1365
|
-
return "z.unknown()";
|
|
1366
|
-
}
|
|
1367
|
-
const nonNullTypes = schema.type.filter((t) => t !== "null");
|
|
1368
|
-
const schemas = nonNullTypes.map((type) => {
|
|
1369
|
-
const typeSchema = { ...schema, type };
|
|
1370
|
-
return this.generatePropertySchema(typeSchema, currentSchema);
|
|
1371
|
-
});
|
|
1372
|
-
return `z.union([${schemas.join(", ")}])`;
|
|
1373
|
-
}
|
|
1374
|
-
/**
|
|
1375
|
-
* Apply unevaluatedProperties validation to a schema
|
|
1376
|
-
*/
|
|
1377
|
-
applyUnevaluatedProperties(baseSchema, schema) {
|
|
1378
|
-
const evaluatedProps = /* @__PURE__ */ new Set();
|
|
1379
|
-
if (schema.properties) {
|
|
1380
|
-
for (const propName of Object.keys(schema.properties)) {
|
|
1381
|
-
evaluatedProps.add(propName);
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
const collectPropsFromComposition = (schemas) => {
|
|
1385
|
-
var _a, _b;
|
|
1386
|
-
if (!schemas) return;
|
|
1387
|
-
for (const subSchema of schemas) {
|
|
1388
|
-
if (subSchema.properties) {
|
|
1389
|
-
for (const propName of Object.keys(subSchema.properties)) {
|
|
1390
|
-
evaluatedProps.add(propName);
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
if (subSchema.$ref) {
|
|
1394
|
-
const refSchema = (_b = (_a = this.context.spec.components) == null ? void 0 : _a.schemas) == null ? void 0 : _b[subSchema.$ref.split("/").pop() || ""];
|
|
1395
|
-
if (refSchema == null ? void 0 : refSchema.properties) {
|
|
1396
|
-
for (const propName of Object.keys(refSchema.properties)) {
|
|
1397
|
-
evaluatedProps.add(propName);
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
};
|
|
1403
|
-
collectPropsFromComposition(schema.allOf);
|
|
1404
|
-
collectPropsFromComposition(schema.oneOf);
|
|
1405
|
-
collectPropsFromComposition(schema.anyOf);
|
|
1406
|
-
const evaluatedPropsSet = `new Set(${JSON.stringify([...evaluatedProps])})`;
|
|
1407
|
-
let schemaWithCatchall = baseSchema;
|
|
1408
|
-
if (baseSchema.includes(".union([") || baseSchema.includes(".discriminatedUnion(")) {
|
|
1409
|
-
schemaWithCatchall = baseSchema;
|
|
1410
|
-
} else if (baseSchema.includes(".extend(")) {
|
|
1411
|
-
schemaWithCatchall = `${baseSchema}.catchall(z.unknown())`;
|
|
1412
|
-
}
|
|
1413
|
-
if (schema.unevaluatedProperties === false) {
|
|
1414
|
-
return `${schemaWithCatchall}.refine((obj) => Object.keys(obj).every(key => ${evaluatedPropsSet}.has(key)), { message: "No unevaluated properties allowed" })`;
|
|
1415
|
-
} else if (typeof schema.unevaluatedProperties === "object") {
|
|
1416
|
-
const unevalSchema = this.generatePropertySchema(schema.unevaluatedProperties);
|
|
1417
|
-
return `${schemaWithCatchall}.refine((obj) => Object.keys(obj).filter(key => !${evaluatedPropsSet}.has(key)).every(key => ${unevalSchema}.safeParse(obj[key]).success), { message: "Unevaluated properties must match the schema" })`;
|
|
1418
|
-
}
|
|
1419
|
-
return baseSchema;
|
|
1420
|
-
}
|
|
1421
|
-
/**
|
|
1422
|
-
* Generate Zod schema for a property
|
|
1423
|
-
* @param schema - The OpenAPI schema to generate
|
|
1424
|
-
* @param currentSchema - The name of the current schema being processed (for circular ref detection)
|
|
1425
|
-
* @param isTopLevel - Whether this is a top-level schema definition
|
|
1426
|
-
* @param suppressDefaultNullable - When true, don't apply defaultNullable (used when outer schema has explicit nullable: false)
|
|
1427
|
-
*/
|
|
1428
|
-
generatePropertySchema(schema, currentSchema, isTopLevel = false, suppressDefaultNullable = false) {
|
|
1429
|
-
var _a, _b, _c, _d, _e;
|
|
1430
|
-
const isCacheable = !schema.$ref && !schema.allOf && !schema.oneOf && !schema.anyOf && !currentSchema;
|
|
1431
|
-
if (isCacheable) {
|
|
1432
|
-
const cacheKey = JSON.stringify({
|
|
1433
|
-
schema,
|
|
1434
|
-
type: this.context.schemaType,
|
|
1435
|
-
mode: this.context.mode,
|
|
1436
|
-
suppressDefaultNullable
|
|
1437
|
-
});
|
|
1438
|
-
const cached = this.schemaCache.get(cacheKey);
|
|
1439
|
-
if (cached) {
|
|
1440
|
-
return cached;
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
if ((this.context.schemaType === "request" || this.context.schemaType === "response") && schema.properties) {
|
|
1444
|
-
schema = this.filterNestedProperties(schema);
|
|
1445
|
-
}
|
|
1446
|
-
const isEnum = !!schema.enum;
|
|
1447
|
-
const isConst = schema.const !== void 0;
|
|
1448
|
-
const shouldApplyDefaultNullable = !isTopLevel && !isEnum && !isConst && !suppressDefaultNullable;
|
|
1449
|
-
const effectiveDefaultNullable = shouldApplyDefaultNullable ? this.context.defaultNullable : false;
|
|
1450
|
-
const nullable = isNullable(schema, effectiveDefaultNullable);
|
|
1451
|
-
if (hasMultipleTypes(schema)) {
|
|
1452
|
-
const union = this.generateMultiTypeUnion(schema, currentSchema);
|
|
1453
|
-
return wrapNullable(union, nullable);
|
|
1454
|
-
}
|
|
1455
|
-
if (schema.$ref) {
|
|
1456
|
-
const refName = resolveRef(schema.$ref);
|
|
1457
|
-
const resolvedRefName = this.resolveSchemaAlias(refName);
|
|
1458
|
-
if (currentSchema && refName !== currentSchema && !isTopLevel) {
|
|
1459
|
-
if (!this.context.schemaDependencies.has(currentSchema)) {
|
|
1460
|
-
this.context.schemaDependencies.set(currentSchema, /* @__PURE__ */ new Set());
|
|
1461
|
-
}
|
|
1462
|
-
(_a = this.context.schemaDependencies.get(currentSchema)) == null ? void 0 : _a.add(refName);
|
|
1463
|
-
}
|
|
1464
|
-
const strippedRefName = stripPrefix(resolvedRefName, this.context.stripSchemaPrefix);
|
|
1465
|
-
const schemaName = `${toCamelCase(strippedRefName, this.context.namingOptions)}Schema`;
|
|
1466
|
-
if (currentSchema && (refName === currentSchema || this.isCircularThroughAlias(currentSchema, refName))) {
|
|
1467
|
-
const lazySchema = `z.lazy((): z.ZodTypeAny => ${schemaName})`;
|
|
1468
|
-
return wrapNullable(lazySchema, nullable);
|
|
1469
|
-
}
|
|
1470
|
-
return wrapNullable(schemaName, nullable);
|
|
1471
|
-
}
|
|
1472
|
-
if (schema.const !== void 0) {
|
|
1473
|
-
const literalValue = typeof schema.const === "string" ? `"${schema.const}"` : schema.const;
|
|
1474
|
-
const zodLiteral = `z.literal(${literalValue})`;
|
|
1475
|
-
return wrapNullable(zodLiteral, nullable);
|
|
1476
|
-
}
|
|
1477
|
-
if (schema.enum) {
|
|
1478
|
-
const allBooleans = schema.enum.every((v) => typeof v === "boolean");
|
|
1479
|
-
if (allBooleans) {
|
|
1480
|
-
const zodBoolean = "z.boolean()";
|
|
1481
|
-
return wrapNullable(zodBoolean, nullable);
|
|
1482
|
-
}
|
|
1483
|
-
const allStrings = schema.enum.every((v) => typeof v === "string");
|
|
1484
|
-
if (allStrings) {
|
|
1485
|
-
const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
|
|
1486
|
-
const zodEnum = `z.enum([${enumValues}])`;
|
|
1487
|
-
return wrapNullable(zodEnum, nullable);
|
|
1488
|
-
}
|
|
1489
|
-
const literalValues = schema.enum.map((v) => {
|
|
1490
|
-
if (typeof v === "string") {
|
|
1491
|
-
return `z.literal("${v}")`;
|
|
1492
|
-
}
|
|
1493
|
-
return `z.literal(${v})`;
|
|
1494
|
-
}).join(", ");
|
|
1495
|
-
const zodUnion = `z.union([${literalValues}])`;
|
|
1496
|
-
return wrapNullable(zodUnion, nullable);
|
|
1497
|
-
}
|
|
1498
|
-
if (schema.allOf) {
|
|
1499
|
-
const compositionNullable = isNullable(schema, false);
|
|
1500
|
-
let composition = generateAllOf(
|
|
1501
|
-
schema.allOf,
|
|
1502
|
-
compositionNullable,
|
|
1503
|
-
{
|
|
1504
|
-
generatePropertySchema: this.generatePropertySchema.bind(this),
|
|
1505
|
-
generateInlineObjectShape: this.generateInlineObjectShape.bind(this),
|
|
1506
|
-
resolveSchemaRef: this.resolveSchemaRef.bind(this)
|
|
1507
|
-
},
|
|
1508
|
-
currentSchema
|
|
1509
|
-
);
|
|
1510
|
-
if (schema.unevaluatedProperties !== void 0) {
|
|
1511
|
-
composition = this.applyUnevaluatedProperties(composition, schema);
|
|
1512
|
-
}
|
|
1513
|
-
return composition;
|
|
1514
|
-
}
|
|
1515
|
-
if (schema.oneOf) {
|
|
1516
|
-
const compositionNullable = isNullable(schema, false);
|
|
1517
|
-
const needsPassthrough = schema.unevaluatedProperties !== void 0;
|
|
1518
|
-
let composition = generateUnion(
|
|
1519
|
-
schema.oneOf,
|
|
1520
|
-
(_b = schema.discriminator) == null ? void 0 : _b.propertyName,
|
|
1521
|
-
compositionNullable,
|
|
1522
|
-
{
|
|
1523
|
-
generatePropertySchema: this.generatePropertySchema.bind(this),
|
|
1524
|
-
resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
|
|
1525
|
-
resolveSchemaRef: this.resolveSchemaRef.bind(this)
|
|
1526
|
-
},
|
|
1527
|
-
{
|
|
1528
|
-
passthrough: needsPassthrough,
|
|
1529
|
-
discriminatorMapping: (_c = schema.discriminator) == null ? void 0 : _c.mapping
|
|
1530
|
-
},
|
|
1531
|
-
currentSchema
|
|
1532
|
-
);
|
|
1533
|
-
if (schema.unevaluatedProperties !== void 0) {
|
|
1534
|
-
composition = this.applyUnevaluatedProperties(composition, schema);
|
|
1535
|
-
}
|
|
1536
|
-
return composition;
|
|
1537
|
-
}
|
|
1538
|
-
if (schema.anyOf) {
|
|
1539
|
-
const compositionNullable = isNullable(schema, false);
|
|
1540
|
-
const needsPassthrough = schema.unevaluatedProperties !== void 0;
|
|
1541
|
-
let composition = generateUnion(
|
|
1542
|
-
schema.anyOf,
|
|
1543
|
-
(_d = schema.discriminator) == null ? void 0 : _d.propertyName,
|
|
1544
|
-
compositionNullable,
|
|
1545
|
-
{
|
|
1546
|
-
generatePropertySchema: this.generatePropertySchema.bind(this),
|
|
1547
|
-
resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
|
|
1548
|
-
resolveSchemaRef: this.resolveSchemaRef.bind(this)
|
|
1549
|
-
},
|
|
1550
|
-
{
|
|
1551
|
-
passthrough: needsPassthrough,
|
|
1552
|
-
discriminatorMapping: (_e = schema.discriminator) == null ? void 0 : _e.mapping
|
|
1553
|
-
},
|
|
1554
|
-
currentSchema
|
|
1555
|
-
);
|
|
1556
|
-
if (schema.unevaluatedProperties !== void 0) {
|
|
1557
|
-
composition = this.applyUnevaluatedProperties(composition, schema);
|
|
1558
|
-
}
|
|
1559
|
-
return composition;
|
|
1560
|
-
}
|
|
1561
|
-
if (schema.not) {
|
|
1562
|
-
const notSchema = this.generatePropertySchema(schema.not, currentSchema);
|
|
1563
|
-
let baseValidation;
|
|
1564
|
-
if (schema.type || schema.properties || schema.items) {
|
|
1565
|
-
const { not: _, ...baseSchema } = schema;
|
|
1566
|
-
baseValidation = this.generatePropertySchema(baseSchema, currentSchema);
|
|
1567
|
-
} else {
|
|
1568
|
-
baseValidation = "z.unknown()";
|
|
1569
|
-
}
|
|
1570
|
-
const refined = `${baseValidation}.refine((val) => !${notSchema}.safeParse(val).success, { message: "Value must not match the excluded schema" })`;
|
|
1571
|
-
return wrapNullable(refined, nullable);
|
|
1572
|
-
}
|
|
1573
|
-
let validation = "";
|
|
1574
|
-
const primaryType = getPrimaryType(schema);
|
|
1575
|
-
switch (primaryType) {
|
|
1576
|
-
case "string":
|
|
1577
|
-
validation = generateStringValidation(schema, this.context.useDescribe, {
|
|
1578
|
-
dateTimeValidation: this.context.dateTimeValidation,
|
|
1579
|
-
patternCache: this.context.patternCache
|
|
1580
|
-
});
|
|
1581
|
-
break;
|
|
1582
|
-
case "number":
|
|
1583
|
-
validation = generateNumberValidation(schema, false, this.context.useDescribe);
|
|
1584
|
-
break;
|
|
1585
|
-
case "integer":
|
|
1586
|
-
validation = generateNumberValidation(schema, true, this.context.useDescribe);
|
|
1587
|
-
break;
|
|
1588
|
-
case "boolean":
|
|
1589
|
-
validation = "z.boolean()";
|
|
1590
|
-
validation = addDescription(validation, schema.description, this.context.useDescribe);
|
|
1591
|
-
break;
|
|
1592
|
-
case "array":
|
|
1593
|
-
validation = generateArrayValidation(schema, {
|
|
1594
|
-
generatePropertySchema: this.generatePropertySchema.bind(this),
|
|
1595
|
-
useDescribe: this.context.useDescribe,
|
|
1596
|
-
currentSchema
|
|
1597
|
-
});
|
|
1598
|
-
break;
|
|
1599
|
-
case "object":
|
|
1600
|
-
if (schema.properties || schema.required || schema.minProperties !== void 0 || schema.maxProperties !== void 0 || schema.patternProperties || schema.propertyNames) {
|
|
1601
|
-
validation = generateObjectSchema(
|
|
1602
|
-
schema,
|
|
1603
|
-
{
|
|
1604
|
-
generatePropertySchema: this.generatePropertySchema.bind(this),
|
|
1605
|
-
shouldIncludeProperty: this.shouldIncludeProperty.bind(this),
|
|
1606
|
-
mode: this.context.mode,
|
|
1607
|
-
includeDescriptions: this.context.includeDescriptions,
|
|
1608
|
-
useDescribe: this.context.useDescribe
|
|
1609
|
-
},
|
|
1610
|
-
currentSchema
|
|
1611
|
-
);
|
|
1612
|
-
validation = addDescription(validation, schema.description, this.context.useDescribe);
|
|
1613
|
-
} else {
|
|
1614
|
-
switch (this.context.emptyObjectBehavior) {
|
|
1615
|
-
case "strict":
|
|
1616
|
-
validation = "z.strictObject({})";
|
|
1617
|
-
break;
|
|
1618
|
-
case "loose":
|
|
1619
|
-
validation = "z.looseObject({})";
|
|
1620
|
-
break;
|
|
1621
|
-
default:
|
|
1622
|
-
validation = "z.record(z.string(), z.unknown())";
|
|
1623
|
-
break;
|
|
1624
|
-
}
|
|
1625
|
-
validation = addDescription(validation, schema.description, this.context.useDescribe);
|
|
1626
|
-
}
|
|
1627
|
-
break;
|
|
1628
|
-
default:
|
|
1629
|
-
validation = "z.unknown()";
|
|
1630
|
-
validation = addDescription(validation, schema.description, this.context.useDescribe);
|
|
1631
|
-
}
|
|
1632
|
-
const result = wrapNullable(validation, nullable);
|
|
1633
|
-
if (isCacheable) {
|
|
1634
|
-
const cacheKey = JSON.stringify({ schema, type: this.context.schemaType, mode: this.context.mode });
|
|
1635
|
-
this.schemaCache.set(cacheKey, result);
|
|
1636
|
-
}
|
|
1637
|
-
return result;
|
|
1638
|
-
}
|
|
1639
|
-
/**
|
|
1640
|
-
* Generate inline object shape for use with .extend()
|
|
1641
|
-
* Returns just the shape object literal: { prop1: z.string(), prop2: z.number() }
|
|
1642
|
-
*
|
|
1643
|
-
* This method is specifically for allOf compositions where we need to pass
|
|
1644
|
-
* the shape directly to .extend() instead of using z.object({...}).shape.
|
|
1645
|
-
* This avoids the .nullable().shape bug when inline objects have nullable: true.
|
|
1646
|
-
*
|
|
1647
|
-
* According to Zod docs (https://zod.dev/api?id=extend):
|
|
1648
|
-
* - .extend() accepts an object of shape definitions
|
|
1649
|
-
* - e.g., baseSchema.extend({ prop: z.string() })
|
|
1650
|
-
*/
|
|
1651
|
-
generateInlineObjectShape(schema, currentSchema) {
|
|
1652
|
-
const required = new Set(schema.required || []);
|
|
1653
|
-
const properties = [];
|
|
1654
|
-
if (schema.properties) {
|
|
1655
|
-
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
1656
|
-
if (!this.shouldIncludeProperty(propSchema)) {
|
|
1657
|
-
continue;
|
|
1658
|
-
}
|
|
1659
|
-
const isRequired = required.has(propName);
|
|
1660
|
-
const zodSchema = this.generatePropertySchema(propSchema, currentSchema);
|
|
1661
|
-
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
1662
|
-
const quotedPropName = validIdentifier.test(propName) ? propName : `"${propName}"`;
|
|
1663
|
-
let propertyDef = `${quotedPropName}: ${zodSchema}`;
|
|
1664
|
-
if (!isRequired) {
|
|
1665
|
-
propertyDef += ".optional()";
|
|
1666
|
-
}
|
|
1667
|
-
properties.push(propertyDef);
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
if (properties.length === 0) {
|
|
1671
|
-
return "{}";
|
|
1672
|
-
}
|
|
1673
|
-
return `{
|
|
1674
|
-
${properties.map((p) => ` ${p}`).join(",\n")}
|
|
1675
|
-
}`;
|
|
1676
|
-
}
|
|
1677
|
-
};
|
|
1678
|
-
// Performance optimization: Lookup table for faster inclusion checks
|
|
1679
|
-
_PropertyGenerator.INCLUSION_RULES = {
|
|
1680
|
-
request: (schema) => !schema.readOnly,
|
|
1681
|
-
response: (schema) => !schema.writeOnly,
|
|
1682
|
-
all: () => true
|
|
1683
|
-
};
|
|
1684
|
-
var PropertyGenerator = _PropertyGenerator;
|
|
1685
|
-
|
|
1686
|
-
// src/utils/config-schemas.ts
|
|
1687
|
-
var import_zod = require("zod");
|
|
1688
|
-
var RequestResponseOptionsSchema = import_zod.z.strictObject({
|
|
1689
|
-
mode: import_zod.z.enum(["strict", "normal", "loose"]).optional(),
|
|
1690
|
-
useDescribe: import_zod.z.boolean().optional(),
|
|
1691
|
-
includeDescriptions: import_zod.z.boolean().optional(),
|
|
1692
|
-
defaultNullable: import_zod.z.boolean().optional(),
|
|
1693
|
-
emptyObjectBehavior: import_zod.z.enum(["strict", "loose", "record"]).optional()
|
|
1694
|
-
});
|
|
1695
|
-
var OperationFiltersSchema = import_zod.z.strictObject({
|
|
1696
|
-
includeTags: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1697
|
-
excludeTags: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1698
|
-
includePaths: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1699
|
-
excludePaths: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1700
|
-
includeMethods: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1701
|
-
excludeMethods: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1702
|
-
includeOperationIds: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1703
|
-
excludeOperationIds: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1704
|
-
excludeDeprecated: import_zod.z.boolean().optional()
|
|
1705
|
-
});
|
|
1706
|
-
|
|
1707
|
-
// src/utils/config-validation.ts
|
|
1708
|
-
function formatConfigValidationError(error, filepath, configPath, additionalNotes) {
|
|
1709
|
-
var _a;
|
|
1710
|
-
const formattedErrors = ((_a = error.issues) == null ? void 0 : _a.map((err) => {
|
|
1711
|
-
const path = err.path.length > 0 ? err.path.join(".") : "root";
|
|
1712
|
-
return ` - ${path}: ${err.message}`;
|
|
1713
|
-
}).join("\n")) || "Unknown validation error";
|
|
1714
|
-
const configSource = filepath || configPath || "config file";
|
|
1715
|
-
const lines = [
|
|
1716
|
-
`Invalid configuration file at: ${configSource}`,
|
|
1717
|
-
"",
|
|
1718
|
-
"Validation errors:",
|
|
1719
|
-
formattedErrors,
|
|
1720
|
-
"",
|
|
1721
|
-
"Please check your configuration file and ensure:",
|
|
1722
|
-
" - All required fields are present (specs array with input/output)",
|
|
1723
|
-
" - Field names are spelled correctly (no typos)",
|
|
1724
|
-
" - Values match the expected types (e.g., mode: 'strict' | 'normal' | 'loose')",
|
|
1725
|
-
" - No unknown/extra properties are included"
|
|
1726
|
-
];
|
|
1727
|
-
if (additionalNotes && additionalNotes.length > 0) {
|
|
1728
|
-
lines.push(...additionalNotes.map((note) => ` - ${note}`));
|
|
1729
|
-
}
|
|
1730
|
-
return lines.join("\n");
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
// src/utils/content-type-utils.ts
|
|
1734
|
-
function getResponseParseMethod(contentType, fallback = "text") {
|
|
1735
|
-
if (!contentType) {
|
|
1736
|
-
return { method: fallback, isUnknown: true };
|
|
1737
|
-
}
|
|
1738
|
-
const normalized = contentType.toLowerCase().split(";")[0].trim();
|
|
1739
|
-
if (!normalized) {
|
|
1740
|
-
return { method: fallback, isUnknown: true };
|
|
1741
|
-
}
|
|
1742
|
-
if (normalized === "application/json" || normalized === "text/json" || normalized.endsWith("+json")) {
|
|
1743
|
-
return { method: "json", isUnknown: false };
|
|
1744
|
-
}
|
|
1745
|
-
if (normalized.startsWith("text/")) {
|
|
1746
|
-
return { method: "text", isUnknown: false };
|
|
1747
|
-
}
|
|
1748
|
-
if (normalized === "application/xml" || normalized.endsWith("+xml")) {
|
|
1749
|
-
return { method: "text", isUnknown: false };
|
|
1750
|
-
}
|
|
1751
|
-
if (normalized === "application/javascript" || normalized === "application/x-javascript" || normalized === "application/ecmascript") {
|
|
1752
|
-
return { method: "text", isUnknown: false };
|
|
1753
|
-
}
|
|
1754
|
-
if (normalized.startsWith("image/")) {
|
|
1755
|
-
return { method: "body", isUnknown: false };
|
|
1756
|
-
}
|
|
1757
|
-
if (normalized.startsWith("audio/")) {
|
|
1758
|
-
return { method: "body", isUnknown: false };
|
|
1759
|
-
}
|
|
1760
|
-
if (normalized.startsWith("video/")) {
|
|
1761
|
-
return { method: "body", isUnknown: false };
|
|
1762
|
-
}
|
|
1763
|
-
if (normalized.startsWith("font/")) {
|
|
1764
|
-
return { method: "body", isUnknown: false };
|
|
1765
|
-
}
|
|
1766
|
-
if (normalized === "application/octet-stream" || normalized === "application/pdf" || normalized === "application/zip" || normalized === "application/gzip" || normalized === "application/x-tar" || normalized === "application/x-7z-compressed" || normalized === "application/x-rar-compressed" || normalized === "application/wasm" || normalized === "application/x-protobuf") {
|
|
1767
|
-
return { method: "body", isUnknown: false };
|
|
1768
|
-
}
|
|
1769
|
-
return { method: fallback, isUnknown: true };
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
// src/utils/operation-filters.ts
|
|
1773
|
-
var import_minimatch2 = require("minimatch");
|
|
1774
|
-
function createFilterStatistics() {
|
|
1775
|
-
return {
|
|
1776
|
-
totalOperations: 0,
|
|
1777
|
-
includedOperations: 0,
|
|
1778
|
-
filteredByTags: 0,
|
|
1779
|
-
filteredByPaths: 0,
|
|
1780
|
-
filteredByMethods: 0,
|
|
1781
|
-
filteredByOperationIds: 0,
|
|
1782
|
-
filteredByDeprecated: 0
|
|
1783
|
-
};
|
|
1784
|
-
}
|
|
1785
|
-
function matchesAnyPattern(value, patterns) {
|
|
1786
|
-
if (!patterns || patterns.length === 0) {
|
|
1787
|
-
return false;
|
|
1788
|
-
}
|
|
1789
|
-
if (!value) {
|
|
1790
|
-
return false;
|
|
1791
|
-
}
|
|
1792
|
-
return patterns.some((pattern) => (0, import_minimatch2.minimatch)(value, pattern));
|
|
1793
|
-
}
|
|
1794
|
-
function containsAny(arr, values) {
|
|
1795
|
-
if (!values || values.length === 0) {
|
|
1796
|
-
return false;
|
|
1797
|
-
}
|
|
1798
|
-
if (!arr || arr.length === 0) {
|
|
1799
|
-
return false;
|
|
1800
|
-
}
|
|
1801
|
-
return values.some((value) => arr.includes(value));
|
|
1802
|
-
}
|
|
1803
|
-
function shouldIncludeOperation(operation, path, method, filters, stats) {
|
|
1804
|
-
if (!filters) {
|
|
1805
|
-
return true;
|
|
1806
|
-
}
|
|
1807
|
-
const methodLower = method.toLowerCase();
|
|
1808
|
-
const operationId = operation == null ? void 0 : operation.operationId;
|
|
1809
|
-
const tags = (operation == null ? void 0 : operation.tags) || [];
|
|
1810
|
-
const deprecated = (operation == null ? void 0 : operation.deprecated) === true;
|
|
1811
|
-
if (filters.includeTags && filters.includeTags.length > 0) {
|
|
1812
|
-
if (!containsAny(tags, filters.includeTags)) {
|
|
1813
|
-
if (stats) stats.filteredByTags++;
|
|
1814
|
-
return false;
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
if (filters.includePaths && filters.includePaths.length > 0) {
|
|
1818
|
-
if (!matchesAnyPattern(path, filters.includePaths)) {
|
|
1819
|
-
if (stats) stats.filteredByPaths++;
|
|
1820
|
-
return false;
|
|
1821
|
-
}
|
|
1822
|
-
}
|
|
1823
|
-
if (filters.includeMethods && filters.includeMethods.length > 0) {
|
|
1824
|
-
const methodsLower = filters.includeMethods.map((m) => m.toLowerCase());
|
|
1825
|
-
if (!methodsLower.includes(methodLower)) {
|
|
1826
|
-
if (stats) stats.filteredByMethods++;
|
|
1827
|
-
return false;
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
if (filters.includeOperationIds && filters.includeOperationIds.length > 0) {
|
|
1831
|
-
if (!matchesAnyPattern(operationId, filters.includeOperationIds)) {
|
|
1832
|
-
if (stats) stats.filteredByOperationIds++;
|
|
1833
|
-
return false;
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
if (filters.excludeDeprecated === true && deprecated) {
|
|
1837
|
-
if (stats) stats.filteredByDeprecated++;
|
|
1838
|
-
return false;
|
|
1839
|
-
}
|
|
1840
|
-
if (filters.excludeTags && filters.excludeTags.length > 0) {
|
|
1841
|
-
if (containsAny(tags, filters.excludeTags)) {
|
|
1842
|
-
if (stats) stats.filteredByTags++;
|
|
1843
|
-
return false;
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
if (filters.excludePaths && filters.excludePaths.length > 0) {
|
|
1847
|
-
if (matchesAnyPattern(path, filters.excludePaths)) {
|
|
1848
|
-
if (stats) stats.filteredByPaths++;
|
|
1849
|
-
return false;
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
if (filters.excludeMethods && filters.excludeMethods.length > 0) {
|
|
1853
|
-
const methodsLower = filters.excludeMethods.map((m) => m.toLowerCase());
|
|
1854
|
-
if (methodsLower.includes(methodLower)) {
|
|
1855
|
-
if (stats) stats.filteredByMethods++;
|
|
1856
|
-
return false;
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
if (filters.excludeOperationIds && filters.excludeOperationIds.length > 0) {
|
|
1860
|
-
if (matchesAnyPattern(operationId, filters.excludeOperationIds)) {
|
|
1861
|
-
if (stats) stats.filteredByOperationIds++;
|
|
1862
|
-
return false;
|
|
1863
|
-
}
|
|
1864
|
-
}
|
|
1865
|
-
return true;
|
|
1866
|
-
}
|
|
1867
|
-
function validateFilters(stats, filters) {
|
|
1868
|
-
if (!filters || stats.totalOperations === 0) {
|
|
1869
|
-
return;
|
|
1870
|
-
}
|
|
1871
|
-
if (stats.includedOperations === 0) {
|
|
1872
|
-
console.warn(
|
|
1873
|
-
`\u26A0\uFE0F Warning: All ${stats.totalOperations} operations were filtered out. Check your operationFilters configuration.`
|
|
1874
|
-
);
|
|
1875
|
-
const filterBreakdown = [];
|
|
1876
|
-
if (stats.filteredByTags > 0) filterBreakdown.push(`${stats.filteredByTags} by tags`);
|
|
1877
|
-
if (stats.filteredByPaths > 0) filterBreakdown.push(`${stats.filteredByPaths} by paths`);
|
|
1878
|
-
if (stats.filteredByMethods > 0) filterBreakdown.push(`${stats.filteredByMethods} by methods`);
|
|
1879
|
-
if (stats.filteredByOperationIds > 0) filterBreakdown.push(`${stats.filteredByOperationIds} by operationIds`);
|
|
1880
|
-
if (stats.filteredByDeprecated > 0) filterBreakdown.push(`${stats.filteredByDeprecated} by deprecated flag`);
|
|
1881
|
-
if (filterBreakdown.length > 0) {
|
|
1882
|
-
console.warn(` Filtered: ${filterBreakdown.join(", ")}`);
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
function formatFilterStatistics(stats) {
|
|
1887
|
-
if (stats.totalOperations === 0) {
|
|
1888
|
-
return "";
|
|
1889
|
-
}
|
|
1890
|
-
const lines = [];
|
|
1891
|
-
lines.push("Operation Filtering:");
|
|
1892
|
-
lines.push(` Total operations: ${stats.totalOperations}`);
|
|
1893
|
-
lines.push(` Included operations: ${stats.includedOperations}`);
|
|
1894
|
-
const filteredCount = stats.filteredByTags + stats.filteredByPaths + stats.filteredByMethods + stats.filteredByOperationIds + stats.filteredByDeprecated;
|
|
1895
|
-
if (filteredCount > 0) {
|
|
1896
|
-
lines.push(` Filtered operations: ${filteredCount}`);
|
|
1897
|
-
if (stats.filteredByTags > 0) lines.push(` - By tags: ${stats.filteredByTags}`);
|
|
1898
|
-
if (stats.filteredByPaths > 0) lines.push(` - By paths: ${stats.filteredByPaths}`);
|
|
1899
|
-
if (stats.filteredByMethods > 0) lines.push(` - By methods: ${stats.filteredByMethods}`);
|
|
1900
|
-
if (stats.filteredByOperationIds > 0) lines.push(` - By operationIds: ${stats.filteredByOperationIds}`);
|
|
1901
|
-
if (stats.filteredByDeprecated > 0) lines.push(` - By deprecated: ${stats.filteredByDeprecated}`);
|
|
1902
|
-
}
|
|
1903
|
-
return lines.join("\n");
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
|
-
// src/utils/ref-resolver.ts
|
|
1907
|
-
function resolveRef2(obj, spec, maxDepth = 10) {
|
|
1908
|
-
var _a, _b, _c, _d;
|
|
1909
|
-
if (!obj || typeof obj !== "object" || maxDepth <= 0) return obj;
|
|
1910
|
-
if (!obj.$ref) return obj;
|
|
1911
|
-
const ref = obj.$ref;
|
|
1912
|
-
let resolved = null;
|
|
1913
|
-
const paramMatch = ref.match(/^#\/components\/parameters\/(.+)$/);
|
|
1914
|
-
const requestBodyMatch = ref.match(/^#\/components\/requestBodies\/(.+)$/);
|
|
1915
|
-
const responseMatch = ref.match(/^#\/components\/responses\/(.+)$/);
|
|
1916
|
-
const schemaMatch = ref.match(/^#\/components\/schemas\/(.+)$/);
|
|
1917
|
-
if (paramMatch && ((_a = spec.components) == null ? void 0 : _a.parameters)) {
|
|
1918
|
-
const name = paramMatch[1];
|
|
1919
|
-
resolved = spec.components.parameters[name];
|
|
1920
|
-
} else if (requestBodyMatch && ((_b = spec.components) == null ? void 0 : _b.requestBodies)) {
|
|
1921
|
-
const name = requestBodyMatch[1];
|
|
1922
|
-
resolved = spec.components.requestBodies[name];
|
|
1923
|
-
} else if (responseMatch && ((_c = spec.components) == null ? void 0 : _c.responses)) {
|
|
1924
|
-
const name = responseMatch[1];
|
|
1925
|
-
resolved = spec.components.responses[name];
|
|
1926
|
-
} else if (schemaMatch && ((_d = spec.components) == null ? void 0 : _d.schemas)) {
|
|
1927
|
-
const name = schemaMatch[1];
|
|
1928
|
-
resolved = spec.components.schemas[name];
|
|
1929
|
-
}
|
|
1930
|
-
if (resolved) {
|
|
1931
|
-
if (resolved.$ref) {
|
|
1932
|
-
return resolveRef2(resolved, spec, maxDepth - 1);
|
|
1933
|
-
}
|
|
1934
|
-
return resolved;
|
|
1935
|
-
}
|
|
1936
|
-
return obj;
|
|
1937
|
-
}
|
|
1938
|
-
function resolveParameterRef(param, spec) {
|
|
1939
|
-
return resolveRef2(param, spec);
|
|
1940
|
-
}
|
|
1941
|
-
function resolveRequestBodyRef(requestBody, spec) {
|
|
1942
|
-
return resolveRef2(requestBody, spec);
|
|
1943
|
-
}
|
|
1944
|
-
function resolveResponseRef(response, spec) {
|
|
1945
|
-
return resolveRef2(response, spec);
|
|
1946
|
-
}
|
|
1947
|
-
function mergeParameters(pathParams, operationParams, spec) {
|
|
1948
|
-
const resolvedPathParams = (pathParams || []).map((p) => resolveParameterRef(p, spec));
|
|
1949
|
-
const resolvedOperationParams = (operationParams || []).map((p) => resolveParameterRef(p, spec));
|
|
1950
|
-
const merged = [...resolvedPathParams];
|
|
1951
|
-
for (const opParam of resolvedOperationParams) {
|
|
1952
|
-
if (!opParam || typeof opParam !== "object") continue;
|
|
1953
|
-
const existingIndex = merged.findIndex(
|
|
1954
|
-
(p) => p && typeof p === "object" && p.name === opParam.name && p.in === opParam.in
|
|
1955
|
-
);
|
|
1956
|
-
if (existingIndex >= 0) {
|
|
1957
|
-
merged[existingIndex] = opParam;
|
|
1958
|
-
} else {
|
|
1959
|
-
merged.push(opParam);
|
|
1960
|
-
}
|
|
1961
|
-
}
|
|
1962
|
-
return merged;
|
|
1963
|
-
}
|
|
1964
|
-
|
|
1965
|
-
// src/utils/typescript-loader.ts
|
|
1966
|
-
function createTypeScriptLoader() {
|
|
1967
|
-
return async (filepath) => {
|
|
1968
|
-
try {
|
|
1969
|
-
const esbuild = await import("esbuild");
|
|
1970
|
-
const fs = await import("fs");
|
|
1971
|
-
const path = await import("path");
|
|
1972
|
-
const tsCode = fs.readFileSync(filepath, "utf-8");
|
|
1973
|
-
const result = await esbuild.build({
|
|
1974
|
-
stdin: {
|
|
1975
|
-
contents: tsCode,
|
|
1976
|
-
loader: "ts",
|
|
1977
|
-
resolveDir: path.dirname(filepath),
|
|
1978
|
-
sourcefile: filepath
|
|
1979
|
-
},
|
|
1980
|
-
format: "cjs",
|
|
1981
|
-
platform: "node",
|
|
1982
|
-
target: "node18",
|
|
1983
|
-
bundle: false,
|
|
1984
|
-
write: false
|
|
1985
|
-
});
|
|
1986
|
-
const jsCode = result.outputFiles[0].text;
|
|
1987
|
-
const module2 = { exports: {} };
|
|
1988
|
-
const func = new Function("exports", "module", "require", "__filename", "__dirname", jsCode);
|
|
1989
|
-
func(module2.exports, module2, require, filepath, path.dirname(filepath));
|
|
1990
|
-
return module2.exports.default || module2.exports;
|
|
1991
|
-
} catch (error) {
|
|
1992
|
-
throw new Error(
|
|
1993
|
-
`Failed to load TypeScript config from ${filepath}: ${error instanceof Error ? error.message : String(error)}`
|
|
1994
|
-
);
|
|
1995
|
-
}
|
|
1996
|
-
};
|
|
1997
|
-
}
|
|
1998
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1999
|
-
0 && (module.exports = {
|
|
2000
|
-
LRUCache,
|
|
2001
|
-
OperationFiltersSchema,
|
|
2002
|
-
PropertyGenerator,
|
|
2003
|
-
RequestResponseOptionsSchema,
|
|
2004
|
-
buildDateTimeValidation,
|
|
2005
|
-
createFilterStatistics,
|
|
2006
|
-
createTypeScriptLoader,
|
|
2007
|
-
escapeJSDoc,
|
|
2008
|
-
executeBatch,
|
|
2009
|
-
formatConfigValidationError,
|
|
2010
|
-
formatFilterStatistics,
|
|
2011
|
-
getBatchExitCode,
|
|
2012
|
-
getResponseParseMethod,
|
|
2013
|
-
mergeParameters,
|
|
2014
|
-
resolveParameterRef,
|
|
2015
|
-
resolveRef,
|
|
2016
|
-
resolveRequestBodyRef,
|
|
2017
|
-
resolveResponseRef,
|
|
2018
|
-
shouldIncludeOperation,
|
|
2019
|
-
stripPathPrefix,
|
|
2020
|
-
stripPrefix,
|
|
2021
|
-
toCamelCase,
|
|
2022
|
-
toPascalCase,
|
|
2023
|
-
validateFilters
|
|
2024
|
-
});
|
|
2025
|
-
//# sourceMappingURL=internal.js.map
|