@cerios/openapi-to-zod 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +209 -28
- package/dist/cli.js +245 -80
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +246 -81
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +209 -77
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +209 -77
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +34 -19
- package/dist/internal.d.ts +34 -19
- package/dist/internal.js +106 -50
- package/dist/internal.js.map +1 -1
- package/dist/internal.mjs +104 -50
- package/dist/internal.mjs.map +1 -1
- package/dist/{types-B7ePTDjr.d.mts → types--r0d47sd.d.mts} +86 -8
- package/dist/{types-B7ePTDjr.d.ts → types--r0d47sd.d.ts} +86 -8
- package/package.json +105 -102
package/dist/cli.mjs
CHANGED
|
@@ -5197,8 +5197,26 @@ var init_name_utils = __esm({
|
|
|
5197
5197
|
function generateEnum(name, values, options) {
|
|
5198
5198
|
const schemaName = `${toCamelCase(name, options)}Schema`;
|
|
5199
5199
|
const typeName = toPascalCase(name);
|
|
5200
|
-
const
|
|
5201
|
-
|
|
5200
|
+
const allBooleans = values.every((v) => typeof v === "boolean");
|
|
5201
|
+
if (allBooleans) {
|
|
5202
|
+
const schemaCode2 = `export const ${schemaName} = z.boolean();`;
|
|
5203
|
+
const typeCode2 = `export type ${typeName} = z.infer<typeof ${schemaName}>;`;
|
|
5204
|
+
return { schemaCode: schemaCode2, typeCode: typeCode2 };
|
|
5205
|
+
}
|
|
5206
|
+
const allStrings = values.every((v) => typeof v === "string");
|
|
5207
|
+
if (allStrings) {
|
|
5208
|
+
const enumValues = values.map((v) => `"${v}"`).join(", ");
|
|
5209
|
+
const schemaCode2 = `export const ${schemaName} = z.enum([${enumValues}]);`;
|
|
5210
|
+
const typeCode2 = `export type ${typeName} = z.infer<typeof ${schemaName}>;`;
|
|
5211
|
+
return { schemaCode: schemaCode2, typeCode: typeCode2 };
|
|
5212
|
+
}
|
|
5213
|
+
const literalValues = values.map((v) => {
|
|
5214
|
+
if (typeof v === "string") {
|
|
5215
|
+
return `z.literal("${v}")`;
|
|
5216
|
+
}
|
|
5217
|
+
return `z.literal(${v})`;
|
|
5218
|
+
}).join(", ");
|
|
5219
|
+
const schemaCode = `export const ${schemaName} = z.union([${literalValues}]);`;
|
|
5202
5220
|
const typeCode = `export type ${typeName} = z.infer<typeof ${schemaName}>;`;
|
|
5203
5221
|
return { schemaCode, typeCode };
|
|
5204
5222
|
}
|
|
@@ -5215,7 +5233,7 @@ function escapeDescription(str) {
|
|
|
5215
5233
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
5216
5234
|
}
|
|
5217
5235
|
function escapePattern(str) {
|
|
5218
|
-
return str.replace(
|
|
5236
|
+
return str.replace(/\//g, "\\/");
|
|
5219
5237
|
}
|
|
5220
5238
|
function escapeJSDoc(str) {
|
|
5221
5239
|
return str.replace(/\*\//g, "*\\/");
|
|
@@ -5223,14 +5241,17 @@ function escapeJSDoc(str) {
|
|
|
5223
5241
|
function wrapNullable(validation, isNullable2) {
|
|
5224
5242
|
return isNullable2 ? `${validation}.nullable()` : validation;
|
|
5225
5243
|
}
|
|
5226
|
-
function isNullable(schema) {
|
|
5244
|
+
function isNullable(schema, defaultNullable = false) {
|
|
5227
5245
|
if (schema.nullable === true) {
|
|
5228
5246
|
return true;
|
|
5229
5247
|
}
|
|
5248
|
+
if (schema.nullable === false) {
|
|
5249
|
+
return false;
|
|
5250
|
+
}
|
|
5230
5251
|
if (Array.isArray(schema.type)) {
|
|
5231
5252
|
return schema.type.includes("null");
|
|
5232
5253
|
}
|
|
5233
|
-
return
|
|
5254
|
+
return defaultNullable;
|
|
5234
5255
|
}
|
|
5235
5256
|
function getPrimaryType(schema) {
|
|
5236
5257
|
if (Array.isArray(schema.type)) {
|
|
@@ -5360,61 +5381,36 @@ var init_lru_cache = __esm({
|
|
|
5360
5381
|
});
|
|
5361
5382
|
|
|
5362
5383
|
// src/utils/pattern-utils.ts
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
if (/\\[dDwWsS]/.test(pattern)) {
|
|
5368
|
-
return true;
|
|
5369
|
-
}
|
|
5370
|
-
if (/\.\*|\.\+/.test(pattern)) {
|
|
5371
|
-
return true;
|
|
5372
|
-
}
|
|
5373
|
-
if (/[[\]()]/.test(pattern)) {
|
|
5374
|
-
return true;
|
|
5375
|
-
}
|
|
5376
|
-
if (/[^/][+?*]\{/.test(pattern)) {
|
|
5384
|
+
import { minimatch } from "minimatch";
|
|
5385
|
+
function isValidGlobPattern(pattern) {
|
|
5386
|
+
try {
|
|
5387
|
+
new minimatch.Minimatch(pattern);
|
|
5377
5388
|
return true;
|
|
5389
|
+
} catch {
|
|
5390
|
+
return false;
|
|
5378
5391
|
}
|
|
5379
|
-
return false;
|
|
5380
5392
|
}
|
|
5381
|
-
function
|
|
5382
|
-
|
|
5383
|
-
return pattern;
|
|
5384
|
-
}
|
|
5385
|
-
if (isRegexPattern(pattern)) {
|
|
5386
|
-
try {
|
|
5387
|
-
return new RegExp(pattern);
|
|
5388
|
-
} catch (error) {
|
|
5389
|
-
console.warn(`\u26A0\uFE0F Invalid regex pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`);
|
|
5390
|
-
return null;
|
|
5391
|
-
}
|
|
5392
|
-
}
|
|
5393
|
-
return null;
|
|
5393
|
+
function isGlobPattern(pattern) {
|
|
5394
|
+
return /[*?[\]{}!]/.test(pattern);
|
|
5394
5395
|
}
|
|
5395
5396
|
function stripPrefix(input, pattern, ensureLeadingChar) {
|
|
5396
5397
|
if (!pattern) {
|
|
5397
5398
|
return input;
|
|
5398
5399
|
}
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
return `${ensureLeadingChar}${stripped}`;
|
|
5410
|
-
}
|
|
5400
|
+
if (isGlobPattern(pattern) && !isValidGlobPattern(pattern)) {
|
|
5401
|
+
console.warn(`\u26A0\uFE0F Invalid glob pattern "${pattern}": Pattern is malformed`);
|
|
5402
|
+
return input;
|
|
5403
|
+
}
|
|
5404
|
+
if (isGlobPattern(pattern)) {
|
|
5405
|
+
let longestMatch = -1;
|
|
5406
|
+
for (let i = 1; i <= input.length; i++) {
|
|
5407
|
+
const testPrefix = input.substring(0, i);
|
|
5408
|
+
if (minimatch(testPrefix, pattern)) {
|
|
5409
|
+
longestMatch = i;
|
|
5411
5410
|
}
|
|
5412
|
-
return stripped;
|
|
5413
5411
|
}
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
if (input.startsWith(stringPattern)) {
|
|
5417
|
-
const stripped = input.substring(stringPattern.length);
|
|
5412
|
+
if (longestMatch > 0) {
|
|
5413
|
+
const stripped = input.substring(longestMatch);
|
|
5418
5414
|
if (ensureLeadingChar) {
|
|
5419
5415
|
if (stripped === "") {
|
|
5420
5416
|
return ensureLeadingChar;
|
|
@@ -5423,11 +5419,40 @@ function stripPrefix(input, pattern, ensureLeadingChar) {
|
|
|
5423
5419
|
return `${ensureLeadingChar}${stripped}`;
|
|
5424
5420
|
}
|
|
5425
5421
|
}
|
|
5426
|
-
return stripped;
|
|
5422
|
+
return stripped === "" && !ensureLeadingChar ? input : stripped;
|
|
5427
5423
|
}
|
|
5424
|
+
return input;
|
|
5425
|
+
}
|
|
5426
|
+
if (input.startsWith(pattern)) {
|
|
5427
|
+
const stripped = input.substring(pattern.length);
|
|
5428
|
+
if (ensureLeadingChar) {
|
|
5429
|
+
if (stripped === "") {
|
|
5430
|
+
return ensureLeadingChar;
|
|
5431
|
+
}
|
|
5432
|
+
if (!stripped.startsWith(ensureLeadingChar)) {
|
|
5433
|
+
return `${ensureLeadingChar}${stripped}`;
|
|
5434
|
+
}
|
|
5435
|
+
}
|
|
5436
|
+
return stripped;
|
|
5428
5437
|
}
|
|
5429
5438
|
return input;
|
|
5430
5439
|
}
|
|
5440
|
+
function stripPathPrefix(path2, pattern) {
|
|
5441
|
+
if (!pattern) {
|
|
5442
|
+
return path2;
|
|
5443
|
+
}
|
|
5444
|
+
if (!isGlobPattern(pattern)) {
|
|
5445
|
+
let normalizedPattern = pattern.trim();
|
|
5446
|
+
if (!normalizedPattern.startsWith("/")) {
|
|
5447
|
+
normalizedPattern = `/${normalizedPattern}`;
|
|
5448
|
+
}
|
|
5449
|
+
if (normalizedPattern.endsWith("/") && normalizedPattern !== "/") {
|
|
5450
|
+
normalizedPattern = normalizedPattern.slice(0, -1);
|
|
5451
|
+
}
|
|
5452
|
+
return stripPrefix(path2, normalizedPattern, "/");
|
|
5453
|
+
}
|
|
5454
|
+
return stripPrefix(path2, pattern, "/");
|
|
5455
|
+
}
|
|
5431
5456
|
var init_pattern_utils = __esm({
|
|
5432
5457
|
"src/utils/pattern-utils.ts"() {
|
|
5433
5458
|
"use strict";
|
|
@@ -5993,6 +6018,26 @@ function configurePatternCache(size) {
|
|
|
5993
6018
|
PATTERN_CACHE = new LRUCache(size);
|
|
5994
6019
|
}
|
|
5995
6020
|
}
|
|
6021
|
+
function configureDateTimeFormat(pattern) {
|
|
6022
|
+
if (!pattern) {
|
|
6023
|
+
FORMAT_MAP["date-time"] = "z.iso.datetime()";
|
|
6024
|
+
return;
|
|
6025
|
+
}
|
|
6026
|
+
const patternStr = pattern instanceof RegExp ? pattern.source : pattern;
|
|
6027
|
+
if (patternStr === "") {
|
|
6028
|
+
FORMAT_MAP["date-time"] = "z.iso.datetime()";
|
|
6029
|
+
return;
|
|
6030
|
+
}
|
|
6031
|
+
try {
|
|
6032
|
+
new RegExp(patternStr);
|
|
6033
|
+
} catch (error) {
|
|
6034
|
+
throw new Error(
|
|
6035
|
+
`Invalid regular expression pattern for customDateTimeFormatRegex: ${patternStr}. ${error instanceof Error ? error.message : "Pattern is malformed"}`
|
|
6036
|
+
);
|
|
6037
|
+
}
|
|
6038
|
+
const escapedPattern = escapePattern(patternStr);
|
|
6039
|
+
FORMAT_MAP["date-time"] = `z.string().regex(/${escapedPattern}/)`;
|
|
6040
|
+
}
|
|
5996
6041
|
function generateStringValidation(schema, useDescribe) {
|
|
5997
6042
|
let validation = FORMAT_MAP[schema.format || ""] || "z.string()";
|
|
5998
6043
|
if (schema.minLength !== void 0) {
|
|
@@ -6058,7 +6103,7 @@ function generateStringValidation(schema, useDescribe) {
|
|
|
6058
6103
|
}
|
|
6059
6104
|
return addDescription(validation, schema.description, useDescribe);
|
|
6060
6105
|
}
|
|
6061
|
-
var PATTERN_CACHE, FORMAT_MAP;
|
|
6106
|
+
var PATTERN_CACHE, DEFAULT_FORMAT_MAP, FORMAT_MAP;
|
|
6062
6107
|
var init_string_validator = __esm({
|
|
6063
6108
|
"src/validators/string-validator.ts"() {
|
|
6064
6109
|
"use strict";
|
|
@@ -6066,7 +6111,7 @@ var init_string_validator = __esm({
|
|
|
6066
6111
|
init_lru_cache();
|
|
6067
6112
|
init_string_utils();
|
|
6068
6113
|
PATTERN_CACHE = new LRUCache(1e3);
|
|
6069
|
-
|
|
6114
|
+
DEFAULT_FORMAT_MAP = {
|
|
6070
6115
|
uuid: "z.uuid()",
|
|
6071
6116
|
email: "z.email()",
|
|
6072
6117
|
uri: "z.url()",
|
|
@@ -6076,7 +6121,6 @@ var init_string_validator = __esm({
|
|
|
6076
6121
|
byte: "z.base64()",
|
|
6077
6122
|
binary: "z.string()",
|
|
6078
6123
|
date: "z.iso.date()",
|
|
6079
|
-
"date-time": "z.iso.datetime()",
|
|
6080
6124
|
time: "z.iso.time()",
|
|
6081
6125
|
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" })',
|
|
6082
6126
|
ipv4: "z.ipv4()",
|
|
@@ -6095,6 +6139,10 @@ var init_string_validator = __esm({
|
|
|
6095
6139
|
"json-pointer": 'z.string().refine((val) => val === "" || /^(\\/([^~/]|~0|~1)+)+$/.test(val), { message: "Must be a valid JSON Pointer (RFC 6901)" })',
|
|
6096
6140
|
"relative-json-pointer": 'z.string().refine((val) => /^(0|[1-9]\\d*)(#|(\\/([^~/]|~0|~1)+)*)$/.test(val), { message: "Must be a valid relative JSON Pointer" })'
|
|
6097
6141
|
};
|
|
6142
|
+
FORMAT_MAP = {
|
|
6143
|
+
...DEFAULT_FORMAT_MAP,
|
|
6144
|
+
"date-time": "z.iso.datetime()"
|
|
6145
|
+
};
|
|
6098
6146
|
}
|
|
6099
6147
|
});
|
|
6100
6148
|
|
|
@@ -6335,7 +6383,8 @@ var init_property_generator = __esm({
|
|
|
6335
6383
|
if ((this.context.schemaType === "request" || this.context.schemaType === "response") && schema.properties) {
|
|
6336
6384
|
schema = this.filterNestedProperties(schema);
|
|
6337
6385
|
}
|
|
6338
|
-
const
|
|
6386
|
+
const effectiveDefaultNullable = isTopLevel ? false : this.context.defaultNullable;
|
|
6387
|
+
const nullable = isNullable(schema, effectiveDefaultNullable);
|
|
6339
6388
|
if (hasMultipleTypes(schema)) {
|
|
6340
6389
|
const union = this.generateMultiTypeUnion(schema, currentSchema);
|
|
6341
6390
|
return wrapNullable(union, nullable);
|
|
@@ -6363,9 +6412,25 @@ var init_property_generator = __esm({
|
|
|
6363
6412
|
return wrapNullable(zodLiteral, nullable);
|
|
6364
6413
|
}
|
|
6365
6414
|
if (schema.enum) {
|
|
6366
|
-
const
|
|
6367
|
-
|
|
6368
|
-
|
|
6415
|
+
const allBooleans = schema.enum.every((v) => typeof v === "boolean");
|
|
6416
|
+
if (allBooleans) {
|
|
6417
|
+
const zodBoolean = "z.boolean()";
|
|
6418
|
+
return wrapNullable(zodBoolean, nullable);
|
|
6419
|
+
}
|
|
6420
|
+
const allStrings = schema.enum.every((v) => typeof v === "string");
|
|
6421
|
+
if (allStrings) {
|
|
6422
|
+
const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
|
|
6423
|
+
const zodEnum = `z.enum([${enumValues}])`;
|
|
6424
|
+
return wrapNullable(zodEnum, nullable);
|
|
6425
|
+
}
|
|
6426
|
+
const literalValues = schema.enum.map((v) => {
|
|
6427
|
+
if (typeof v === "string") {
|
|
6428
|
+
return `z.literal("${v}")`;
|
|
6429
|
+
}
|
|
6430
|
+
return `z.literal(${v})`;
|
|
6431
|
+
}).join(", ");
|
|
6432
|
+
const zodUnion = `z.union([${literalValues}])`;
|
|
6433
|
+
return wrapNullable(zodUnion, nullable);
|
|
6369
6434
|
}
|
|
6370
6435
|
if (schema.allOf) {
|
|
6371
6436
|
let composition = generateAllOf(
|
|
@@ -6498,7 +6563,7 @@ var init_property_generator = __esm({
|
|
|
6498
6563
|
});
|
|
6499
6564
|
|
|
6500
6565
|
// src/utils/operation-filters.ts
|
|
6501
|
-
import { minimatch } from "minimatch";
|
|
6566
|
+
import { minimatch as minimatch2 } from "minimatch";
|
|
6502
6567
|
function createFilterStatistics() {
|
|
6503
6568
|
return {
|
|
6504
6569
|
totalOperations: 0,
|
|
@@ -6517,7 +6582,7 @@ function matchesAnyPattern(value, patterns) {
|
|
|
6517
6582
|
if (!value) {
|
|
6518
6583
|
return false;
|
|
6519
6584
|
}
|
|
6520
|
-
return patterns.some((pattern) =>
|
|
6585
|
+
return patterns.some((pattern) => minimatch2(value, pattern));
|
|
6521
6586
|
}
|
|
6522
6587
|
function containsAny(arr, values) {
|
|
6523
6588
|
if (!values || values.length === 0) {
|
|
@@ -6640,7 +6705,7 @@ var init_operation_filters = __esm({
|
|
|
6640
6705
|
// src/openapi-generator.ts
|
|
6641
6706
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
6642
6707
|
import { dirname, normalize } from "path";
|
|
6643
|
-
import { minimatch as
|
|
6708
|
+
import { minimatch as minimatch3 } from "minimatch";
|
|
6644
6709
|
import { parse } from "yaml";
|
|
6645
6710
|
var OpenApiGenerator;
|
|
6646
6711
|
var init_openapi_generator = __esm({
|
|
@@ -6663,7 +6728,7 @@ var init_openapi_generator = __esm({
|
|
|
6663
6728
|
this.schemaUsageMap = /* @__PURE__ */ new Map();
|
|
6664
6729
|
this.needsZodImport = true;
|
|
6665
6730
|
this.filterStats = createFilterStatistics();
|
|
6666
|
-
var _a, _b, _c, _d, _e;
|
|
6731
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
6667
6732
|
if (!options.input) {
|
|
6668
6733
|
throw new ConfigurationError("Input path is required", { providedOptions: options });
|
|
6669
6734
|
}
|
|
@@ -6673,21 +6738,27 @@ var init_openapi_generator = __esm({
|
|
|
6673
6738
|
output: options.output,
|
|
6674
6739
|
includeDescriptions: (_a = options.includeDescriptions) != null ? _a : true,
|
|
6675
6740
|
useDescribe: (_b = options.useDescribe) != null ? _b : false,
|
|
6741
|
+
defaultNullable: (_c = options.defaultNullable) != null ? _c : false,
|
|
6676
6742
|
schemaType: options.schemaType || "all",
|
|
6677
6743
|
prefix: options.prefix,
|
|
6678
6744
|
suffix: options.suffix,
|
|
6679
6745
|
stripSchemaPrefix: options.stripSchemaPrefix,
|
|
6680
|
-
|
|
6746
|
+
stripPathPrefix: options.stripPathPrefix,
|
|
6747
|
+
showStats: (_d = options.showStats) != null ? _d : true,
|
|
6681
6748
|
request: options.request,
|
|
6682
6749
|
response: options.response,
|
|
6683
6750
|
operationFilters: options.operationFilters,
|
|
6684
6751
|
ignoreHeaders: options.ignoreHeaders,
|
|
6685
|
-
cacheSize: (
|
|
6686
|
-
batchSize: (
|
|
6752
|
+
cacheSize: (_e = options.cacheSize) != null ? _e : 1e3,
|
|
6753
|
+
batchSize: (_f = options.batchSize) != null ? _f : 10,
|
|
6754
|
+
customDateTimeFormatRegex: options.customDateTimeFormatRegex
|
|
6687
6755
|
};
|
|
6688
6756
|
if (this.options.cacheSize) {
|
|
6689
6757
|
configurePatternCache(this.options.cacheSize);
|
|
6690
6758
|
}
|
|
6759
|
+
if (this.options.customDateTimeFormatRegex) {
|
|
6760
|
+
configureDateTimeFormat(this.options.customDateTimeFormatRegex);
|
|
6761
|
+
}
|
|
6691
6762
|
try {
|
|
6692
6763
|
const fs = __require("fs");
|
|
6693
6764
|
if (!fs.existsSync(this.options.input)) {
|
|
@@ -6750,6 +6821,7 @@ var init_openapi_generator = __esm({
|
|
|
6750
6821
|
mode: this.requestOptions.mode,
|
|
6751
6822
|
includeDescriptions: this.requestOptions.includeDescriptions,
|
|
6752
6823
|
useDescribe: this.requestOptions.useDescribe,
|
|
6824
|
+
defaultNullable: (_g = this.options.defaultNullable) != null ? _g : false,
|
|
6753
6825
|
namingOptions: {
|
|
6754
6826
|
prefix: this.options.prefix,
|
|
6755
6827
|
suffix: this.options.suffix
|
|
@@ -6767,6 +6839,9 @@ var init_openapi_generator = __esm({
|
|
|
6767
6839
|
throw new SpecValidationError("No schemas found in OpenAPI spec", { filePath: this.options.input });
|
|
6768
6840
|
}
|
|
6769
6841
|
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
6842
|
+
if (this.options.operationFilters && this.schemaUsageMap.size > 0 && !this.schemaUsageMap.has(name)) {
|
|
6843
|
+
continue;
|
|
6844
|
+
}
|
|
6770
6845
|
this.generateComponentSchema(name, schema);
|
|
6771
6846
|
}
|
|
6772
6847
|
this.generateQueryParameterSchemas();
|
|
@@ -7100,7 +7175,7 @@ var init_openapi_generator = __esm({
|
|
|
7100
7175
|
* Generate schema for a component
|
|
7101
7176
|
*/
|
|
7102
7177
|
generateComponentSchema(name, schema) {
|
|
7103
|
-
var _a, _b;
|
|
7178
|
+
var _a, _b, _c;
|
|
7104
7179
|
if (!this.schemaDependencies.has(name)) {
|
|
7105
7180
|
this.schemaDependencies.set(name, /* @__PURE__ */ new Set());
|
|
7106
7181
|
}
|
|
@@ -7132,14 +7207,14 @@ ${typeCode}`;
|
|
|
7132
7207
|
mode: resolvedOptions.mode,
|
|
7133
7208
|
includeDescriptions: resolvedOptions.includeDescriptions,
|
|
7134
7209
|
useDescribe: resolvedOptions.useDescribe,
|
|
7210
|
+
defaultNullable: (_b = this.options.defaultNullable) != null ? _b : false,
|
|
7135
7211
|
namingOptions: {
|
|
7136
7212
|
prefix: this.options.prefix,
|
|
7137
7213
|
suffix: this.options.suffix
|
|
7138
7214
|
},
|
|
7139
7215
|
stripSchemaPrefix: this.options.stripSchemaPrefix
|
|
7140
7216
|
});
|
|
7141
|
-
const
|
|
7142
|
-
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
7217
|
+
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, true);
|
|
7143
7218
|
const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
|
|
7144
7219
|
if (zodSchema.includes("z.discriminatedUnion(")) {
|
|
7145
7220
|
const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
|
|
@@ -7149,7 +7224,7 @@ ${typeCode}`;
|
|
|
7149
7224
|
const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
|
|
7150
7225
|
if (depMatch) {
|
|
7151
7226
|
const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
|
|
7152
|
-
(
|
|
7227
|
+
(_c = this.schemaDependencies.get(name)) == null ? void 0 : _c.add(depName);
|
|
7153
7228
|
}
|
|
7154
7229
|
}
|
|
7155
7230
|
}
|
|
@@ -7173,7 +7248,7 @@ ${typeCode}`;
|
|
|
7173
7248
|
if (!shouldIncludeOperation(operation, path2, method, this.options.operationFilters)) {
|
|
7174
7249
|
continue;
|
|
7175
7250
|
}
|
|
7176
|
-
if (!operation.
|
|
7251
|
+
if (!operation.parameters || !Array.isArray(operation.parameters)) {
|
|
7177
7252
|
continue;
|
|
7178
7253
|
}
|
|
7179
7254
|
const queryParams = operation.parameters.filter(
|
|
@@ -7182,7 +7257,13 @@ ${typeCode}`;
|
|
|
7182
7257
|
if (queryParams.length === 0) {
|
|
7183
7258
|
continue;
|
|
7184
7259
|
}
|
|
7185
|
-
|
|
7260
|
+
let pascalOperationId;
|
|
7261
|
+
if (operation.operationId) {
|
|
7262
|
+
pascalOperationId = operation.operationId.includes("-") ? toPascalCase(operation.operationId) : operation.operationId.charAt(0).toUpperCase() + operation.operationId.slice(1);
|
|
7263
|
+
} else {
|
|
7264
|
+
const strippedPath = stripPathPrefix(path2, this.options.stripPathPrefix);
|
|
7265
|
+
pascalOperationId = this.generateMethodNameFromPath(method, strippedPath);
|
|
7266
|
+
}
|
|
7186
7267
|
const schemaName = `${pascalOperationId}QueryParams`;
|
|
7187
7268
|
if (!this.schemaDependencies.has(schemaName)) {
|
|
7188
7269
|
this.schemaDependencies.set(schemaName, /* @__PURE__ */ new Set());
|
|
@@ -7230,8 +7311,9 @@ ${propsCode}
|
|
|
7230
7311
|
const prefixedName = this.options.prefix ? `${toPascalCase(this.options.prefix)}${operationName}` : operationName;
|
|
7231
7312
|
const suffixedName = this.options.suffix ? `${prefixedName}${toPascalCase(this.options.suffix)}` : prefixedName;
|
|
7232
7313
|
const camelCaseSchemaName = `${suffixedName.charAt(0).toLowerCase() + suffixedName.slice(1)}QueryParamsSchema`;
|
|
7314
|
+
const jsdocOperationName = operation.operationId || `${method.toUpperCase()} ${path2}`;
|
|
7233
7315
|
const jsdoc = `/**
|
|
7234
|
-
* Query parameters for ${
|
|
7316
|
+
* Query parameters for ${jsdocOperationName}
|
|
7235
7317
|
*/
|
|
7236
7318
|
`;
|
|
7237
7319
|
const fullSchemaCode = `${jsdoc}export const ${camelCaseSchemaName} = ${schemaCode};`;
|
|
@@ -7240,6 +7322,35 @@ ${propsCode}
|
|
|
7240
7322
|
}
|
|
7241
7323
|
}
|
|
7242
7324
|
}
|
|
7325
|
+
/**
|
|
7326
|
+
* Generate a PascalCase method name from HTTP method and path
|
|
7327
|
+
* Used as fallback when operationId is not available
|
|
7328
|
+
* @internal
|
|
7329
|
+
*/
|
|
7330
|
+
generateMethodNameFromPath(method, path2) {
|
|
7331
|
+
const segments = path2.split("/").filter(Boolean).map((segment) => {
|
|
7332
|
+
if (segment.startsWith("{") && segment.endsWith("}")) {
|
|
7333
|
+
const paramName = segment.slice(1, -1);
|
|
7334
|
+
return `By${this.capitalizeSegment(paramName)}`;
|
|
7335
|
+
}
|
|
7336
|
+
return this.capitalizeSegment(segment);
|
|
7337
|
+
}).join("");
|
|
7338
|
+
const capitalizedMethod = method.charAt(0).toUpperCase() + method.slice(1).toLowerCase();
|
|
7339
|
+
return `${capitalizedMethod}${segments}`;
|
|
7340
|
+
}
|
|
7341
|
+
/**
|
|
7342
|
+
* Capitalizes a path segment, handling special characters like dashes, underscores, and dots
|
|
7343
|
+
* @internal
|
|
7344
|
+
*/
|
|
7345
|
+
capitalizeSegment(str) {
|
|
7346
|
+
if (str.includes("-") || str.includes("_") || str.includes(".")) {
|
|
7347
|
+
return str.split(/[-_.]/).map((part) => {
|
|
7348
|
+
if (!part) return "";
|
|
7349
|
+
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
7350
|
+
}).join("");
|
|
7351
|
+
}
|
|
7352
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
7353
|
+
}
|
|
7243
7354
|
/**
|
|
7244
7355
|
* Check if a header should be ignored based on filter patterns
|
|
7245
7356
|
* @internal
|
|
@@ -7255,7 +7366,7 @@ ${propsCode}
|
|
|
7255
7366
|
const headerLower = headerName.toLowerCase();
|
|
7256
7367
|
return ignorePatterns.some((pattern) => {
|
|
7257
7368
|
const patternLower = pattern.toLowerCase();
|
|
7258
|
-
return
|
|
7369
|
+
return minimatch3(headerLower, patternLower);
|
|
7259
7370
|
});
|
|
7260
7371
|
}
|
|
7261
7372
|
/**
|
|
@@ -7276,7 +7387,7 @@ ${propsCode}
|
|
|
7276
7387
|
if (!shouldIncludeOperation(operation, path2, method, this.options.operationFilters)) {
|
|
7277
7388
|
continue;
|
|
7278
7389
|
}
|
|
7279
|
-
if (!operation.
|
|
7390
|
+
if (!operation.parameters || !Array.isArray(operation.parameters)) {
|
|
7280
7391
|
continue;
|
|
7281
7392
|
}
|
|
7282
7393
|
const headerParams = operation.parameters.filter(
|
|
@@ -7285,7 +7396,13 @@ ${propsCode}
|
|
|
7285
7396
|
if (headerParams.length === 0) {
|
|
7286
7397
|
continue;
|
|
7287
7398
|
}
|
|
7288
|
-
|
|
7399
|
+
let pascalOperationId;
|
|
7400
|
+
if (operation.operationId) {
|
|
7401
|
+
pascalOperationId = operation.operationId.includes("-") ? toPascalCase(operation.operationId) : operation.operationId.charAt(0).toUpperCase() + operation.operationId.slice(1);
|
|
7402
|
+
} else {
|
|
7403
|
+
const strippedPath = stripPathPrefix(path2, this.options.stripPathPrefix);
|
|
7404
|
+
pascalOperationId = this.generateMethodNameFromPath(method, strippedPath);
|
|
7405
|
+
}
|
|
7289
7406
|
const schemaName = `${pascalOperationId}HeaderParams`;
|
|
7290
7407
|
if (!this.schemaDependencies.has(schemaName)) {
|
|
7291
7408
|
this.schemaDependencies.set(schemaName, /* @__PURE__ */ new Set());
|
|
@@ -7322,8 +7439,9 @@ ${propsCode}
|
|
|
7322
7439
|
const prefixedName = this.options.prefix ? `${toPascalCase(this.options.prefix)}${operationName}` : operationName;
|
|
7323
7440
|
const suffixedName = this.options.suffix ? `${prefixedName}${toPascalCase(this.options.suffix)}` : prefixedName;
|
|
7324
7441
|
const camelCaseSchemaName = `${suffixedName.charAt(0).toLowerCase() + suffixedName.slice(1)}HeaderParamsSchema`;
|
|
7442
|
+
const jsdocOperationName = operation.operationId || `${method.toUpperCase()} ${path2}`;
|
|
7325
7443
|
const jsdoc = `/**
|
|
7326
|
-
* Header parameters for ${
|
|
7444
|
+
* Header parameters for ${jsdocOperationName}
|
|
7327
7445
|
*/
|
|
7328
7446
|
`;
|
|
7329
7447
|
const fullSchemaCode = `${jsdoc}export const ${camelCaseSchemaName} = ${schemaCode};`;
|
|
@@ -7343,8 +7461,22 @@ ${propsCode}
|
|
|
7343
7461
|
return `${schemaName}Schema`;
|
|
7344
7462
|
}
|
|
7345
7463
|
if (schema.enum) {
|
|
7346
|
-
const
|
|
7347
|
-
|
|
7464
|
+
const allBooleans = schema.enum.every((v) => typeof v === "boolean");
|
|
7465
|
+
if (allBooleans) {
|
|
7466
|
+
return "z.boolean()";
|
|
7467
|
+
}
|
|
7468
|
+
const allStrings = schema.enum.every((v) => typeof v === "string");
|
|
7469
|
+
if (allStrings) {
|
|
7470
|
+
const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
|
|
7471
|
+
return `z.enum([${enumValues}])`;
|
|
7472
|
+
}
|
|
7473
|
+
const literalValues = schema.enum.map((v) => {
|
|
7474
|
+
if (typeof v === "string") {
|
|
7475
|
+
return `z.literal("${v}")`;
|
|
7476
|
+
}
|
|
7477
|
+
return `z.literal(${v})`;
|
|
7478
|
+
}).join(", ");
|
|
7479
|
+
return `z.union([${literalValues}])`;
|
|
7348
7480
|
}
|
|
7349
7481
|
const type = schema.type;
|
|
7350
7482
|
if (type === "string") {
|
|
@@ -7490,7 +7622,8 @@ var init_config_schemas = __esm({
|
|
|
7490
7622
|
RequestResponseOptionsSchema = z.strictObject({
|
|
7491
7623
|
mode: z.enum(["strict", "normal", "loose"]).optional(),
|
|
7492
7624
|
useDescribe: z.boolean().optional(),
|
|
7493
|
-
includeDescriptions: z.boolean().optional()
|
|
7625
|
+
includeDescriptions: z.boolean().optional(),
|
|
7626
|
+
defaultNullable: z.boolean().optional()
|
|
7494
7627
|
});
|
|
7495
7628
|
OperationFiltersSchema = z.strictObject({
|
|
7496
7629
|
includeTags: z.array(z.string()).optional(),
|
|
@@ -7621,10 +7754,12 @@ function mergeConfigWithDefaults(config) {
|
|
|
7621
7754
|
mode: defaults.mode,
|
|
7622
7755
|
includeDescriptions: defaults.includeDescriptions,
|
|
7623
7756
|
useDescribe: defaults.useDescribe,
|
|
7757
|
+
defaultNullable: defaults.defaultNullable,
|
|
7624
7758
|
schemaType: defaults.schemaType,
|
|
7625
7759
|
prefix: defaults.prefix,
|
|
7626
7760
|
suffix: defaults.suffix,
|
|
7627
7761
|
showStats: defaults.showStats,
|
|
7762
|
+
customDateTimeFormatRegex: defaults.customDateTimeFormatRegex,
|
|
7628
7763
|
// Override with spec-specific values (including required input/output)
|
|
7629
7764
|
...spec
|
|
7630
7765
|
};
|
|
@@ -7645,6 +7780,7 @@ var init_config_loader = __esm({
|
|
|
7645
7780
|
output: z2.string(),
|
|
7646
7781
|
includeDescriptions: z2.boolean().optional(),
|
|
7647
7782
|
useDescribe: z2.boolean().optional(),
|
|
7783
|
+
defaultNullable: z2.boolean().optional(),
|
|
7648
7784
|
schemaType: z2.enum(["all", "request", "response"]).optional(),
|
|
7649
7785
|
prefix: z2.string().optional(),
|
|
7650
7786
|
suffix: z2.string().optional(),
|
|
@@ -7655,13 +7791,28 @@ var init_config_loader = __esm({
|
|
|
7655
7791
|
name: z2.string().optional(),
|
|
7656
7792
|
operationFilters: OperationFiltersSchema.optional(),
|
|
7657
7793
|
cacheSize: z2.number().positive().optional(),
|
|
7658
|
-
batchSize: z2.number().positive().optional()
|
|
7794
|
+
batchSize: z2.number().positive().optional(),
|
|
7795
|
+
customDateTimeFormatRegex: z2.union([
|
|
7796
|
+
z2.string().refine(
|
|
7797
|
+
(pattern) => {
|
|
7798
|
+
try {
|
|
7799
|
+
new RegExp(pattern);
|
|
7800
|
+
return true;
|
|
7801
|
+
} catch {
|
|
7802
|
+
return false;
|
|
7803
|
+
}
|
|
7804
|
+
},
|
|
7805
|
+
{ message: "Must be a valid regular expression pattern" }
|
|
7806
|
+
),
|
|
7807
|
+
z2.instanceof(RegExp)
|
|
7808
|
+
]).optional()
|
|
7659
7809
|
});
|
|
7660
7810
|
ConfigFileSchema = z2.strictObject({
|
|
7661
7811
|
defaults: z2.strictObject({
|
|
7662
7812
|
mode: z2.enum(["strict", "normal", "loose"]).optional(),
|
|
7663
7813
|
includeDescriptions: z2.boolean().optional(),
|
|
7664
7814
|
useDescribe: z2.boolean().optional(),
|
|
7815
|
+
defaultNullable: z2.boolean().optional(),
|
|
7665
7816
|
schemaType: z2.enum(["all", "request", "response"]).optional(),
|
|
7666
7817
|
prefix: z2.string().optional(),
|
|
7667
7818
|
suffix: z2.string().optional(),
|
|
@@ -7671,7 +7822,21 @@ var init_config_loader = __esm({
|
|
|
7671
7822
|
response: RequestResponseOptionsSchema.optional(),
|
|
7672
7823
|
operationFilters: OperationFiltersSchema.optional(),
|
|
7673
7824
|
cacheSize: z2.number().positive().optional(),
|
|
7674
|
-
batchSize: z2.number().positive().optional()
|
|
7825
|
+
batchSize: z2.number().positive().optional(),
|
|
7826
|
+
customDateTimeFormatRegex: z2.union([
|
|
7827
|
+
z2.string().refine(
|
|
7828
|
+
(pattern) => {
|
|
7829
|
+
try {
|
|
7830
|
+
new RegExp(pattern);
|
|
7831
|
+
return true;
|
|
7832
|
+
} catch {
|
|
7833
|
+
return false;
|
|
7834
|
+
}
|
|
7835
|
+
},
|
|
7836
|
+
{ message: "Must be a valid regular expression pattern" }
|
|
7837
|
+
),
|
|
7838
|
+
z2.instanceof(RegExp)
|
|
7839
|
+
]).optional()
|
|
7675
7840
|
}).optional(),
|
|
7676
7841
|
specs: z2.array(OpenApiGeneratorOptionsSchema).min(1, {
|
|
7677
7842
|
message: "Configuration must include at least one specification. Each specification should have 'input' and 'output' paths."
|