@cerios/openapi-to-zod 0.5.3 → 1.0.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 +275 -65
- package/dist/cli.js +290 -489
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +344 -525
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +9 -420
- package/dist/index.d.ts +9 -420
- package/dist/index.js +90 -325
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +89 -320
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +200 -0
- package/dist/internal.d.ts +200 -0
- package/dist/internal.js +464 -0
- package/dist/internal.js.map +1 -0
- package/dist/internal.mjs +422 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/types-BjoP91vk.d.mts +314 -0
- package/dist/types-BjoP91vk.d.ts +314 -0
- package/package.json +21 -10
package/dist/cli.mjs
CHANGED
|
@@ -5016,6 +5016,125 @@ var init_errors = __esm({
|
|
|
5016
5016
|
}
|
|
5017
5017
|
});
|
|
5018
5018
|
|
|
5019
|
+
// src/batch-executor.ts
|
|
5020
|
+
async function processSpec(spec, index, total, createGenerator) {
|
|
5021
|
+
const specInput = spec.input || "spec";
|
|
5022
|
+
const specOutput = spec.output || "output";
|
|
5023
|
+
console.log(`Processing [${index + 1}/${total}] ${specInput}...`);
|
|
5024
|
+
try {
|
|
5025
|
+
const generator = createGenerator(spec);
|
|
5026
|
+
generator.generate();
|
|
5027
|
+
return {
|
|
5028
|
+
spec,
|
|
5029
|
+
success: true
|
|
5030
|
+
};
|
|
5031
|
+
} catch (error) {
|
|
5032
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
5033
|
+
console.error(`\u2717 Failed to generate ${specOutput}: ${errorMessage}`);
|
|
5034
|
+
return {
|
|
5035
|
+
spec,
|
|
5036
|
+
success: false,
|
|
5037
|
+
error: errorMessage
|
|
5038
|
+
};
|
|
5039
|
+
}
|
|
5040
|
+
}
|
|
5041
|
+
async function executeParallel(specs, createGenerator, batchSize) {
|
|
5042
|
+
console.log(`
|
|
5043
|
+
Executing ${specs.length} specification(s) in parallel (batch size: ${batchSize})...
|
|
5044
|
+
`);
|
|
5045
|
+
const results = [];
|
|
5046
|
+
for (let i = 0; i < specs.length; i += batchSize) {
|
|
5047
|
+
const batch = specs.slice(i, Math.min(i + batchSize, specs.length));
|
|
5048
|
+
const batchPromises = batch.map(
|
|
5049
|
+
(spec, batchIndex) => processSpec(spec, i + batchIndex, specs.length, createGenerator)
|
|
5050
|
+
);
|
|
5051
|
+
const batchResults = await Promise.allSettled(batchPromises);
|
|
5052
|
+
for (let j = 0; j < batchResults.length; j++) {
|
|
5053
|
+
const result = batchResults[j];
|
|
5054
|
+
if (result.status === "fulfilled") {
|
|
5055
|
+
results.push(result.value);
|
|
5056
|
+
} else {
|
|
5057
|
+
results.push({
|
|
5058
|
+
spec: batch[j],
|
|
5059
|
+
success: false,
|
|
5060
|
+
error: result.reason instanceof Error ? result.reason.message : String(result.reason)
|
|
5061
|
+
});
|
|
5062
|
+
}
|
|
5063
|
+
}
|
|
5064
|
+
}
|
|
5065
|
+
return results;
|
|
5066
|
+
}
|
|
5067
|
+
async function executeSequential(specs, createGenerator) {
|
|
5068
|
+
console.log(`
|
|
5069
|
+
Executing ${specs.length} spec(s) sequentially...
|
|
5070
|
+
`);
|
|
5071
|
+
const results = [];
|
|
5072
|
+
for (let i = 0; i < specs.length; i++) {
|
|
5073
|
+
const result = await processSpec(specs[i], i, specs.length, createGenerator);
|
|
5074
|
+
results.push(result);
|
|
5075
|
+
}
|
|
5076
|
+
return results;
|
|
5077
|
+
}
|
|
5078
|
+
function printSummary(summary) {
|
|
5079
|
+
console.log(`
|
|
5080
|
+
${"=".repeat(50)}`);
|
|
5081
|
+
console.log("Batch Execution Summary");
|
|
5082
|
+
console.log("=".repeat(50));
|
|
5083
|
+
console.log(`Total specs: ${summary.total}`);
|
|
5084
|
+
console.log(`Successful: ${summary.successful}`);
|
|
5085
|
+
console.log(`Failed: ${summary.failed}`);
|
|
5086
|
+
if (summary.failed > 0) {
|
|
5087
|
+
console.log("\nFailed specs:");
|
|
5088
|
+
for (const result of summary.results) {
|
|
5089
|
+
if (!result.success) {
|
|
5090
|
+
const specInput = result.spec.input || "spec";
|
|
5091
|
+
console.error(` \u2717 ${specInput}`);
|
|
5092
|
+
console.error(` Error: ${result.error}`);
|
|
5093
|
+
}
|
|
5094
|
+
}
|
|
5095
|
+
}
|
|
5096
|
+
console.log(`${"=".repeat(50)}
|
|
5097
|
+
`);
|
|
5098
|
+
}
|
|
5099
|
+
async function executeBatch(specs, executionMode = "parallel", createGenerator, batchSize) {
|
|
5100
|
+
if (specs.length === 0) {
|
|
5101
|
+
throw new ConfigurationError("No specs provided for batch execution", { specsCount: 0, executionMode });
|
|
5102
|
+
}
|
|
5103
|
+
let results = [];
|
|
5104
|
+
try {
|
|
5105
|
+
results = executionMode === "parallel" ? await executeParallel(specs, createGenerator, batchSize) : await executeSequential(specs, createGenerator);
|
|
5106
|
+
const summary = {
|
|
5107
|
+
total: results.length,
|
|
5108
|
+
successful: results.filter((r) => r.success).length,
|
|
5109
|
+
failed: results.filter((r) => !r.success).length,
|
|
5110
|
+
results
|
|
5111
|
+
};
|
|
5112
|
+
printSummary(summary);
|
|
5113
|
+
return summary;
|
|
5114
|
+
} finally {
|
|
5115
|
+
if (results.length > batchSize) {
|
|
5116
|
+
for (const result of results) {
|
|
5117
|
+
if (result.spec) {
|
|
5118
|
+
result.spec = null;
|
|
5119
|
+
}
|
|
5120
|
+
}
|
|
5121
|
+
if (global.gc) {
|
|
5122
|
+
global.gc();
|
|
5123
|
+
}
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
5126
|
+
}
|
|
5127
|
+
function getBatchExitCode(summary) {
|
|
5128
|
+
return summary.failed > 0 ? 1 : 0;
|
|
5129
|
+
}
|
|
5130
|
+
var init_batch_executor = __esm({
|
|
5131
|
+
"src/batch-executor.ts"() {
|
|
5132
|
+
"use strict";
|
|
5133
|
+
init_esm_shims();
|
|
5134
|
+
init_errors();
|
|
5135
|
+
}
|
|
5136
|
+
});
|
|
5137
|
+
|
|
5019
5138
|
// src/utils/name-utils.ts
|
|
5020
5139
|
function toCamelCase(str, options) {
|
|
5021
5140
|
let name = str.charAt(0).toLowerCase() + str.slice(1);
|
|
@@ -5053,34 +5172,11 @@ var init_name_utils = __esm({
|
|
|
5053
5172
|
|
|
5054
5173
|
// src/generators/enum-generator.ts
|
|
5055
5174
|
function generateEnum(name, values, options) {
|
|
5056
|
-
const enumName = name.endsWith("EnumOptions") ? name.replace("EnumOptions", "Enum") : `${name}Enum`;
|
|
5057
5175
|
const schemaName = `${toCamelCase(name, options)}Schema`;
|
|
5058
|
-
if (options.enumType === "typescript") {
|
|
5059
|
-
const usedKeys = /* @__PURE__ */ new Set();
|
|
5060
|
-
const enumEntries = values.map((value) => {
|
|
5061
|
-
let key = toPascalCase(value);
|
|
5062
|
-
if (usedKeys.has(key)) {
|
|
5063
|
-
let counter = 2;
|
|
5064
|
-
while (usedKeys.has(`${key}${counter}`)) {
|
|
5065
|
-
counter++;
|
|
5066
|
-
}
|
|
5067
|
-
key = `${key}${counter}`;
|
|
5068
|
-
}
|
|
5069
|
-
usedKeys.add(key);
|
|
5070
|
-
const stringValue = typeof value === "string" ? `"${value}"` : value;
|
|
5071
|
-
return ` ${key} = ${stringValue},`;
|
|
5072
|
-
}).join("\n");
|
|
5073
|
-
const enumCode = `export enum ${enumName} {
|
|
5074
|
-
${enumEntries}
|
|
5075
|
-
}`;
|
|
5076
|
-
const schemaCode2 = `export const ${schemaName} = z.nativeEnum(${enumName});`;
|
|
5077
|
-
const typeCode2 = `export type ${name} = z.infer<typeof ${schemaName}>;`;
|
|
5078
|
-
return { enumCode, schemaCode: schemaCode2, typeCode: typeCode2 };
|
|
5079
|
-
}
|
|
5080
5176
|
const enumValues = values.map((v) => `"${v}"`).join(", ");
|
|
5081
5177
|
const schemaCode = `export const ${schemaName} = z.enum([${enumValues}]);`;
|
|
5082
5178
|
const typeCode = `export type ${name} = z.infer<typeof ${schemaName}>;`;
|
|
5083
|
-
return {
|
|
5179
|
+
return { schemaCode, typeCode };
|
|
5084
5180
|
}
|
|
5085
5181
|
var init_enum_generator = __esm({
|
|
5086
5182
|
"src/generators/enum-generator.ts"() {
|
|
@@ -5204,6 +5300,9 @@ var init_lru_cache = __esm({
|
|
|
5204
5300
|
this.cache = /* @__PURE__ */ new Map();
|
|
5205
5301
|
this.maxSize = maxSize;
|
|
5206
5302
|
}
|
|
5303
|
+
get capacity() {
|
|
5304
|
+
return this.maxSize;
|
|
5305
|
+
}
|
|
5207
5306
|
get(key) {
|
|
5208
5307
|
if (!this.cache.has(key)) return void 0;
|
|
5209
5308
|
const value = this.cache.get(key);
|
|
@@ -5789,6 +5888,11 @@ var init_object_validator = __esm({
|
|
|
5789
5888
|
});
|
|
5790
5889
|
|
|
5791
5890
|
// src/validators/string-validator.ts
|
|
5891
|
+
function configurePatternCache(size) {
|
|
5892
|
+
if (size > 0 && size !== PATTERN_CACHE.capacity) {
|
|
5893
|
+
PATTERN_CACHE = new LRUCache(size);
|
|
5894
|
+
}
|
|
5895
|
+
}
|
|
5792
5896
|
function generateStringValidation(schema, useDescribe) {
|
|
5793
5897
|
let validation = FORMAT_MAP[schema.format || ""] || "z.string()";
|
|
5794
5898
|
if (schema.minLength !== void 0) {
|
|
@@ -6434,6 +6538,7 @@ var init_operation_filters = __esm({
|
|
|
6434
6538
|
// src/openapi-generator.ts
|
|
6435
6539
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
6436
6540
|
import { dirname, normalize } from "path";
|
|
6541
|
+
import { minimatch as minimatch2 } from "minimatch";
|
|
6437
6542
|
import { parse } from "yaml";
|
|
6438
6543
|
var OpenApiGenerator;
|
|
6439
6544
|
var init_openapi_generator = __esm({
|
|
@@ -6446,18 +6551,16 @@ var init_openapi_generator = __esm({
|
|
|
6446
6551
|
init_property_generator();
|
|
6447
6552
|
init_name_utils();
|
|
6448
6553
|
init_operation_filters();
|
|
6554
|
+
init_string_validator();
|
|
6449
6555
|
OpenApiGenerator = class {
|
|
6450
6556
|
constructor(options) {
|
|
6451
6557
|
this.schemas = /* @__PURE__ */ new Map();
|
|
6452
6558
|
this.types = /* @__PURE__ */ new Map();
|
|
6453
|
-
this.enums = /* @__PURE__ */ new Map();
|
|
6454
|
-
this.nativeEnums = /* @__PURE__ */ new Map();
|
|
6455
6559
|
this.schemaDependencies = /* @__PURE__ */ new Map();
|
|
6456
6560
|
this.schemaUsageMap = /* @__PURE__ */ new Map();
|
|
6457
|
-
this.
|
|
6458
|
-
this.needsZodImport = false;
|
|
6561
|
+
this.needsZodImport = true;
|
|
6459
6562
|
this.filterStats = createFilterStatistics();
|
|
6460
|
-
var _a, _b, _c;
|
|
6563
|
+
var _a, _b, _c, _d, _e;
|
|
6461
6564
|
if (!options.input) {
|
|
6462
6565
|
throw new ConfigurationError("Input path is required", { providedOptions: options });
|
|
6463
6566
|
}
|
|
@@ -6466,17 +6569,21 @@ var init_openapi_generator = __esm({
|
|
|
6466
6569
|
input: options.input,
|
|
6467
6570
|
output: options.output,
|
|
6468
6571
|
includeDescriptions: (_a = options.includeDescriptions) != null ? _a : true,
|
|
6469
|
-
enumType: options.enumType || "zod",
|
|
6470
6572
|
useDescribe: (_b = options.useDescribe) != null ? _b : false,
|
|
6471
6573
|
schemaType: options.schemaType || "all",
|
|
6472
6574
|
prefix: options.prefix,
|
|
6473
6575
|
suffix: options.suffix,
|
|
6474
6576
|
showStats: (_c = options.showStats) != null ? _c : true,
|
|
6475
|
-
nativeEnumType: options.nativeEnumType || "union",
|
|
6476
6577
|
request: options.request,
|
|
6477
6578
|
response: options.response,
|
|
6478
|
-
operationFilters: options.operationFilters
|
|
6579
|
+
operationFilters: options.operationFilters,
|
|
6580
|
+
ignoreHeaders: options.ignoreHeaders,
|
|
6581
|
+
cacheSize: (_d = options.cacheSize) != null ? _d : 1e3,
|
|
6582
|
+
batchSize: (_e = options.batchSize) != null ? _e : 10
|
|
6479
6583
|
};
|
|
6584
|
+
if (this.options.cacheSize) {
|
|
6585
|
+
configurePatternCache(this.options.cacheSize);
|
|
6586
|
+
}
|
|
6480
6587
|
try {
|
|
6481
6588
|
const fs = __require("fs");
|
|
6482
6589
|
if (!fs.existsSync(this.options.input)) {
|
|
@@ -6532,7 +6639,6 @@ var init_openapi_generator = __esm({
|
|
|
6532
6639
|
this.requestOptions = this.resolveOptionsForContext("request");
|
|
6533
6640
|
this.responseOptions = this.resolveOptionsForContext("response");
|
|
6534
6641
|
this.analyzeSchemaUsage();
|
|
6535
|
-
this.determineSchemaTypeModes();
|
|
6536
6642
|
this.propertyGenerator = new PropertyGenerator({
|
|
6537
6643
|
spec: this.spec,
|
|
6538
6644
|
schemaDependencies: this.schemaDependencies,
|
|
@@ -6540,8 +6646,6 @@ var init_openapi_generator = __esm({
|
|
|
6540
6646
|
mode: this.requestOptions.mode,
|
|
6541
6647
|
includeDescriptions: this.requestOptions.includeDescriptions,
|
|
6542
6648
|
useDescribe: this.requestOptions.useDescribe,
|
|
6543
|
-
typeMode: this.requestOptions.typeMode,
|
|
6544
|
-
nativeEnumType: this.requestOptions.nativeEnumType,
|
|
6545
6649
|
namingOptions: {
|
|
6546
6650
|
prefix: this.options.prefix,
|
|
6547
6651
|
suffix: this.options.suffix
|
|
@@ -6557,25 +6661,6 @@ var init_openapi_generator = __esm({
|
|
|
6557
6661
|
if (!((_a = this.spec.components) == null ? void 0 : _a.schemas)) {
|
|
6558
6662
|
throw new SpecValidationError("No schemas found in OpenAPI spec", { filePath: this.options.input });
|
|
6559
6663
|
}
|
|
6560
|
-
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
6561
|
-
if (schema.enum) {
|
|
6562
|
-
const context = this.schemaUsageMap.get(name);
|
|
6563
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
6564
|
-
if (resolvedOptions.enumType === "typescript") {
|
|
6565
|
-
this.generateNativeEnum(name, schema);
|
|
6566
|
-
} else {
|
|
6567
|
-
const { enumCode } = generateEnum(name, schema.enum, {
|
|
6568
|
-
enumType: "zod",
|
|
6569
|
-
prefix: this.options.prefix,
|
|
6570
|
-
suffix: this.options.suffix
|
|
6571
|
-
});
|
|
6572
|
-
if (enumCode) {
|
|
6573
|
-
this.enums.set(name, enumCode);
|
|
6574
|
-
this.needsZodImport = true;
|
|
6575
|
-
}
|
|
6576
|
-
}
|
|
6577
|
-
}
|
|
6578
|
-
}
|
|
6579
6664
|
for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
|
|
6580
6665
|
this.generateComponentSchema(name, schema);
|
|
6581
6666
|
}
|
|
@@ -6592,22 +6677,11 @@ var init_openapi_generator = __esm({
|
|
|
6592
6677
|
output.push('import { z } from "zod";');
|
|
6593
6678
|
output.push("");
|
|
6594
6679
|
}
|
|
6595
|
-
if (this.nativeEnums.size > 0) {
|
|
6596
|
-
output.push("// Native Enums");
|
|
6597
|
-
for (const enumCode of this.nativeEnums.values()) {
|
|
6598
|
-
output.push(enumCode);
|
|
6599
|
-
output.push("");
|
|
6600
|
-
}
|
|
6601
|
-
}
|
|
6602
6680
|
output.push("// Schemas and Types");
|
|
6603
6681
|
for (const name of orderedSchemaNames) {
|
|
6604
|
-
const enumCode = this.enums.get(name);
|
|
6605
6682
|
const schemaCode = this.schemas.get(name);
|
|
6606
6683
|
const typeCode = this.types.get(name);
|
|
6607
|
-
if (
|
|
6608
|
-
output.push(enumCode);
|
|
6609
|
-
output.push("");
|
|
6610
|
-
} else if (schemaCode) {
|
|
6684
|
+
if (schemaCode) {
|
|
6611
6685
|
output.push(schemaCode);
|
|
6612
6686
|
if (!schemaCode.includes(`export type ${name}`)) {
|
|
6613
6687
|
const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
@@ -6645,25 +6719,19 @@ var init_openapi_generator = __esm({
|
|
|
6645
6719
|
const normalizedOutput = normalize(this.options.output);
|
|
6646
6720
|
this.ensureDirectoryExists(normalizedOutput);
|
|
6647
6721
|
writeFileSync(normalizedOutput, output);
|
|
6722
|
+
console.log(` \u2713 Generated ${normalizedOutput}`);
|
|
6648
6723
|
}
|
|
6649
6724
|
/**
|
|
6650
6725
|
* Resolve options for a specific context (request or response)
|
|
6651
6726
|
* Nested options silently override root-level options
|
|
6652
|
-
* Response schemas always use 'inferred' mode (Zod schemas)
|
|
6653
6727
|
*/
|
|
6654
6728
|
resolveOptionsForContext(context) {
|
|
6655
|
-
var _a, _b, _c, _d, _e, _f
|
|
6729
|
+
var _a, _b, _c, _d, _e, _f;
|
|
6656
6730
|
const contextOptions = context === "request" ? this.options.request : this.options.response;
|
|
6657
|
-
const nativeEnumType = context === "request" ? (_c = (_b = (_a = this.options.request) == null ? void 0 : _a.nativeEnumType) != null ? _b : this.options.nativeEnumType) != null ? _c : "union" : (_d = this.options.nativeEnumType) != null ? _d : "union";
|
|
6658
6731
|
return {
|
|
6659
|
-
mode: (
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
includeDescriptions: (_l = (_k = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _k : this.options.includeDescriptions) != null ? _l : true,
|
|
6663
|
-
// Response schemas always use 'inferred' mode (Zod schemas are required)
|
|
6664
|
-
// Request schemas can optionally use 'native' mode
|
|
6665
|
-
typeMode: context === "response" ? "inferred" : (_n = (_m = this.options.request) == null ? void 0 : _m.typeMode) != null ? _n : "inferred",
|
|
6666
|
-
nativeEnumType
|
|
6732
|
+
mode: (_b = (_a = contextOptions == null ? void 0 : contextOptions.mode) != null ? _a : this.options.mode) != null ? _b : "normal",
|
|
6733
|
+
useDescribe: (_d = (_c = contextOptions == null ? void 0 : contextOptions.useDescribe) != null ? _c : this.options.useDescribe) != null ? _d : false,
|
|
6734
|
+
includeDescriptions: (_f = (_e = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _e : this.options.includeDescriptions) != null ? _f : true
|
|
6667
6735
|
};
|
|
6668
6736
|
}
|
|
6669
6737
|
/**
|
|
@@ -6854,28 +6922,6 @@ var init_openapi_generator = __esm({
|
|
|
6854
6922
|
detectCycle(name);
|
|
6855
6923
|
}
|
|
6856
6924
|
}
|
|
6857
|
-
/**
|
|
6858
|
-
* Determine the typeMode for each schema based on its usage context
|
|
6859
|
-
* Response schemas always use 'inferred' mode
|
|
6860
|
-
*/
|
|
6861
|
-
determineSchemaTypeModes() {
|
|
6862
|
-
var _a;
|
|
6863
|
-
for (const [name] of Object.entries(((_a = this.spec.components) == null ? void 0 : _a.schemas) || {})) {
|
|
6864
|
-
const context = this.schemaUsageMap.get(name);
|
|
6865
|
-
if (context === "request") {
|
|
6866
|
-
this.schemaTypeModeMap.set(name, this.requestOptions.typeMode);
|
|
6867
|
-
} else if (context === "response") {
|
|
6868
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
6869
|
-
} else if (context === "both") {
|
|
6870
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
6871
|
-
} else {
|
|
6872
|
-
this.schemaTypeModeMap.set(name, "inferred");
|
|
6873
|
-
}
|
|
6874
|
-
if (this.schemaTypeModeMap.get(name) === "inferred") {
|
|
6875
|
-
this.needsZodImport = true;
|
|
6876
|
-
}
|
|
6877
|
-
}
|
|
6878
|
-
}
|
|
6879
6925
|
/**
|
|
6880
6926
|
* Validate the OpenAPI specification
|
|
6881
6927
|
*/
|
|
@@ -6951,80 +6997,54 @@ var init_openapi_generator = __esm({
|
|
|
6951
6997
|
if (!this.schemaDependencies.has(name)) {
|
|
6952
6998
|
this.schemaDependencies.set(name, /* @__PURE__ */ new Set());
|
|
6953
6999
|
}
|
|
6954
|
-
const typeMode = this.schemaTypeModeMap.get(name) || "inferred";
|
|
6955
7000
|
const context = this.schemaUsageMap.get(name);
|
|
6956
7001
|
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
6957
7002
|
if (schema.enum) {
|
|
6958
|
-
const
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
});
|
|
6965
|
-
const enumSchemaCode = `${jsdoc}${schemaCode}
|
|
6966
|
-
${typeCode}`;
|
|
6967
|
-
this.schemas.set(name, enumSchemaCode);
|
|
6968
|
-
} else {
|
|
6969
|
-
const { enumCode, schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
6970
|
-
enumType: "zod",
|
|
6971
|
-
prefix: this.options.prefix,
|
|
6972
|
-
suffix: this.options.suffix
|
|
6973
|
-
});
|
|
6974
|
-
if (enumCode) {
|
|
6975
|
-
this.enums.set(name, enumCode);
|
|
6976
|
-
}
|
|
6977
|
-
const enumSchemaCode = `${jsdoc}${schemaCode}
|
|
7003
|
+
const jsdoc2 = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
7004
|
+
const { schemaCode, typeCode } = generateEnum(name, schema.enum, {
|
|
7005
|
+
prefix: this.options.prefix,
|
|
7006
|
+
suffix: this.options.suffix
|
|
7007
|
+
});
|
|
7008
|
+
const enumSchemaCode = `${jsdoc2}${schemaCode}
|
|
6978
7009
|
${typeCode}`;
|
|
6979
|
-
|
|
6980
|
-
}
|
|
7010
|
+
this.schemas.set(name, enumSchemaCode);
|
|
6981
7011
|
return;
|
|
6982
7012
|
}
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
const
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
7013
|
+
const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
|
|
7014
|
+
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
7015
|
+
if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref) {
|
|
7016
|
+
const refName = resolveRef(schema.allOf[0].$ref);
|
|
7017
|
+
(_a = this.schemaDependencies.get(name)) == null ? void 0 : _a.add(refName);
|
|
7018
|
+
}
|
|
7019
|
+
this.propertyGenerator = new PropertyGenerator({
|
|
7020
|
+
spec: this.spec,
|
|
7021
|
+
schemaDependencies: this.schemaDependencies,
|
|
7022
|
+
schemaType: this.options.schemaType || "all",
|
|
7023
|
+
mode: resolvedOptions.mode,
|
|
7024
|
+
includeDescriptions: resolvedOptions.includeDescriptions,
|
|
7025
|
+
useDescribe: resolvedOptions.useDescribe,
|
|
7026
|
+
namingOptions: {
|
|
7027
|
+
prefix: this.options.prefix,
|
|
7028
|
+
suffix: this.options.suffix
|
|
6995
7029
|
}
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
});
|
|
7010
|
-
const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
|
|
7011
|
-
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
7012
|
-
const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
|
|
7013
|
-
if (zodSchema.includes("z.discriminatedUnion(")) {
|
|
7014
|
-
const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
|
|
7015
|
-
if (match) {
|
|
7016
|
-
const refs = match[1].split(",").map((ref) => ref.trim());
|
|
7017
|
-
for (const ref of refs) {
|
|
7018
|
-
const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
|
|
7019
|
-
if (depMatch) {
|
|
7020
|
-
const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
|
|
7021
|
-
(_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
|
|
7022
|
-
}
|
|
7030
|
+
});
|
|
7031
|
+
const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
|
|
7032
|
+
const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
|
|
7033
|
+
const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
|
|
7034
|
+
if (zodSchema.includes("z.discriminatedUnion(")) {
|
|
7035
|
+
const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
|
|
7036
|
+
if (match) {
|
|
7037
|
+
const refs = match[1].split(",").map((ref) => ref.trim());
|
|
7038
|
+
for (const ref of refs) {
|
|
7039
|
+
const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
|
|
7040
|
+
if (depMatch) {
|
|
7041
|
+
const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
|
|
7042
|
+
(_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
|
|
7023
7043
|
}
|
|
7024
7044
|
}
|
|
7025
7045
|
}
|
|
7026
|
-
this.schemas.set(name, zodSchemaCode);
|
|
7027
7046
|
}
|
|
7047
|
+
this.schemas.set(name, zodSchemaCode);
|
|
7028
7048
|
}
|
|
7029
7049
|
/**
|
|
7030
7050
|
* Generate query parameter schemas for each operation
|
|
@@ -7110,6 +7130,24 @@ ${propsCode}
|
|
|
7110
7130
|
}
|
|
7111
7131
|
}
|
|
7112
7132
|
}
|
|
7133
|
+
/**
|
|
7134
|
+
* Check if a header should be ignored based on filter patterns
|
|
7135
|
+
* @internal
|
|
7136
|
+
*/
|
|
7137
|
+
shouldIgnoreHeader(headerName) {
|
|
7138
|
+
const ignorePatterns = this.options.ignoreHeaders;
|
|
7139
|
+
if (!ignorePatterns || ignorePatterns.length === 0) {
|
|
7140
|
+
return false;
|
|
7141
|
+
}
|
|
7142
|
+
if (ignorePatterns.includes("*")) {
|
|
7143
|
+
return true;
|
|
7144
|
+
}
|
|
7145
|
+
const headerLower = headerName.toLowerCase();
|
|
7146
|
+
return ignorePatterns.some((pattern) => {
|
|
7147
|
+
const patternLower = pattern.toLowerCase();
|
|
7148
|
+
return minimatch2(headerLower, patternLower);
|
|
7149
|
+
});
|
|
7150
|
+
}
|
|
7113
7151
|
/**
|
|
7114
7152
|
* Generate header parameter schemas for each operation
|
|
7115
7153
|
* Header parameters are always string type (HTTP header semantics)
|
|
@@ -7132,7 +7170,7 @@ ${propsCode}
|
|
|
7132
7170
|
continue;
|
|
7133
7171
|
}
|
|
7134
7172
|
const headerParams = operation.parameters.filter(
|
|
7135
|
-
(param) => param && typeof param === "object" && param.in === "header"
|
|
7173
|
+
(param) => param && typeof param === "object" && param.in === "header" && !this.shouldIgnoreHeader(param.name)
|
|
7136
7174
|
);
|
|
7137
7175
|
if (headerParams.length === 0) {
|
|
7138
7176
|
continue;
|
|
@@ -7230,151 +7268,11 @@ ${propsCode}
|
|
|
7230
7268
|
}
|
|
7231
7269
|
return "z.unknown()";
|
|
7232
7270
|
}
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
const context = this.schemaUsageMap.get(name);
|
|
7239
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
7240
|
-
const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
7241
|
-
if (resolvedOptions.nativeEnumType === "enum") {
|
|
7242
|
-
const enumName = `${name}Enum`;
|
|
7243
|
-
const members = schema.enum.map((value) => {
|
|
7244
|
-
const key = typeof value === "string" ? this.toEnumKey(value) : `N${value}`;
|
|
7245
|
-
const val = typeof value === "string" ? `"${value}"` : value;
|
|
7246
|
-
return ` ${key} = ${val}`;
|
|
7247
|
-
}).join(",\n");
|
|
7248
|
-
const enumCode = `${jsdoc}export enum ${enumName} {
|
|
7249
|
-
${members}
|
|
7250
|
-
}`;
|
|
7251
|
-
this.nativeEnums.set(name, enumCode);
|
|
7252
|
-
const typeCode = `export type ${name} = ${enumName};`;
|
|
7253
|
-
this.types.set(name, typeCode);
|
|
7254
|
-
} else {
|
|
7255
|
-
const unionType = schema.enum.map((v) => typeof v === "string" ? `"${v}"` : v).join(" | ");
|
|
7256
|
-
const typeCode = `${jsdoc}export type ${name} = ${unionType};`;
|
|
7257
|
-
this.types.set(name, typeCode);
|
|
7258
|
-
}
|
|
7259
|
-
}
|
|
7260
|
-
/**
|
|
7261
|
-
* Convert string to valid enum key
|
|
7262
|
-
*/
|
|
7263
|
-
toEnumKey(value) {
|
|
7264
|
-
const cleaned = value.replace(/[^a-zA-Z0-9]/g, "_");
|
|
7265
|
-
const pascalCase = cleaned.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
7266
|
-
return pascalCase || "Value";
|
|
7267
|
-
}
|
|
7268
|
-
/**
|
|
7269
|
-
* Add constraint annotations to JSDoc for native types
|
|
7270
|
-
*/
|
|
7271
|
-
addConstraintsToJSDoc(jsdoc, schema, includeDescriptions) {
|
|
7272
|
-
if (!includeDescriptions) return jsdoc;
|
|
7273
|
-
const constraints = [];
|
|
7274
|
-
if (schema.minLength !== void 0) constraints.push(`@minLength ${schema.minLength}`);
|
|
7275
|
-
if (schema.maxLength !== void 0) constraints.push(`@maxLength ${schema.maxLength}`);
|
|
7276
|
-
if (schema.pattern) constraints.push(`@pattern ${schema.pattern}`);
|
|
7277
|
-
if (schema.minimum !== void 0) constraints.push(`@minimum ${schema.minimum}`);
|
|
7278
|
-
if (schema.maximum !== void 0) constraints.push(`@maximum ${schema.maximum}`);
|
|
7279
|
-
if (schema.minItems !== void 0) constraints.push(`@minItems ${schema.minItems}`);
|
|
7280
|
-
if (schema.maxItems !== void 0) constraints.push(`@maxItems ${schema.maxItems}`);
|
|
7281
|
-
if (schema.minProperties !== void 0) constraints.push(`@minProperties ${schema.minProperties}`);
|
|
7282
|
-
if (schema.maxProperties !== void 0) constraints.push(`@maxProperties ${schema.maxProperties}`);
|
|
7283
|
-
if (schema.multipleOf !== void 0) constraints.push(`@multipleOf ${schema.multipleOf}`);
|
|
7284
|
-
if (schema.format) constraints.push(`@format ${schema.format}`);
|
|
7285
|
-
if (constraints.length === 0) return jsdoc;
|
|
7286
|
-
if (jsdoc) {
|
|
7287
|
-
const lines = jsdoc.trim().split("\n");
|
|
7288
|
-
if (lines[0] === "/**" && lines[lines.length - 1] === " */") {
|
|
7289
|
-
const newLines = [...lines.slice(0, -1), ...constraints.map((c) => ` * ${c}`), " */\n"];
|
|
7290
|
-
return newLines.join("\n");
|
|
7291
|
-
}
|
|
7292
|
-
const content = jsdoc.replace("/** ", "").replace(" */\n", "");
|
|
7293
|
-
return `/**
|
|
7294
|
-
* ${content}
|
|
7295
|
-
${constraints.map((c) => ` * ${c}`).join("\n")}
|
|
7296
|
-
*/
|
|
7297
|
-
`;
|
|
7298
|
-
}
|
|
7299
|
-
return `/**
|
|
7300
|
-
${constraints.map((c) => ` * ${c}`).join("\n")}
|
|
7301
|
-
*/
|
|
7302
|
-
`;
|
|
7303
|
-
}
|
|
7304
|
-
/**
|
|
7305
|
-
* Generate native TypeScript type definition from OpenAPI schema
|
|
7306
|
-
*/
|
|
7307
|
-
generateNativeTypeDefinition(schema, _schemaName) {
|
|
7308
|
-
if (schema.$ref) {
|
|
7309
|
-
return resolveRef(schema.$ref);
|
|
7310
|
-
}
|
|
7311
|
-
if (schema.const !== void 0) {
|
|
7312
|
-
return typeof schema.const === "string" ? `"${schema.const}"` : String(schema.const);
|
|
7313
|
-
}
|
|
7314
|
-
const isNullable2 = schema.nullable || Array.isArray(schema.type) && schema.type.includes("null");
|
|
7315
|
-
const wrapNullable2 = (type) => isNullable2 ? `(${type}) | null` : type;
|
|
7316
|
-
const primaryType = Array.isArray(schema.type) ? schema.type.find((t) => t !== "null") : schema.type;
|
|
7317
|
-
switch (primaryType) {
|
|
7318
|
-
case "string":
|
|
7319
|
-
return wrapNullable2("string");
|
|
7320
|
-
case "number":
|
|
7321
|
-
case "integer":
|
|
7322
|
-
return wrapNullable2("number");
|
|
7323
|
-
case "boolean":
|
|
7324
|
-
return wrapNullable2("boolean");
|
|
7325
|
-
case "array":
|
|
7326
|
-
if (schema.items) {
|
|
7327
|
-
const itemType = this.generateNativeTypeDefinition(schema.items);
|
|
7328
|
-
return wrapNullable2(`${itemType}[]`);
|
|
7329
|
-
}
|
|
7330
|
-
return wrapNullable2("unknown[]");
|
|
7331
|
-
case "object":
|
|
7332
|
-
return wrapNullable2(this.generateObjectType(schema));
|
|
7333
|
-
default:
|
|
7334
|
-
if (schema.allOf) {
|
|
7335
|
-
const types = schema.allOf.map((s) => this.generateNativeTypeDefinition(s));
|
|
7336
|
-
return wrapNullable2(types.join(" & "));
|
|
7337
|
-
}
|
|
7338
|
-
if (schema.oneOf || schema.anyOf) {
|
|
7339
|
-
const schemas = schema.oneOf || schema.anyOf || [];
|
|
7340
|
-
const types = schemas.map((s) => this.generateNativeTypeDefinition(s));
|
|
7341
|
-
return wrapNullable2(types.join(" | "));
|
|
7342
|
-
}
|
|
7343
|
-
return wrapNullable2("unknown");
|
|
7344
|
-
}
|
|
7345
|
-
}
|
|
7346
|
-
/**
|
|
7347
|
-
* Generate TypeScript object type definition
|
|
7348
|
-
*/
|
|
7349
|
-
generateObjectType(schema) {
|
|
7350
|
-
if (!schema.properties || Object.keys(schema.properties).length === 0) {
|
|
7351
|
-
return "Record<string, unknown>";
|
|
7352
|
-
}
|
|
7353
|
-
const context = this.schemaUsageMap.get(schema.$ref ? resolveRef(schema.$ref) : "");
|
|
7354
|
-
const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
|
|
7355
|
-
const required = new Set(schema.required || []);
|
|
7356
|
-
const props = [];
|
|
7357
|
-
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
7358
|
-
const propType = this.generateNativeTypeDefinition(propSchema);
|
|
7359
|
-
const optional = !required.has(propName) ? "?" : "";
|
|
7360
|
-
let propJsdoc = generateJSDoc(propSchema, propName, { includeDescriptions: resolvedOptions.includeDescriptions });
|
|
7361
|
-
if (resolvedOptions.includeDescriptions && !propJsdoc) {
|
|
7362
|
-
propJsdoc = this.addConstraintsToJSDoc("", propSchema, resolvedOptions.includeDescriptions);
|
|
7363
|
-
} else if (propJsdoc && resolvedOptions.includeDescriptions) {
|
|
7364
|
-
propJsdoc = this.addConstraintsToJSDoc(propJsdoc, propSchema, resolvedOptions.includeDescriptions);
|
|
7365
|
-
}
|
|
7366
|
-
if (propJsdoc) {
|
|
7367
|
-
const cleanJsdoc = propJsdoc.trimEnd();
|
|
7368
|
-
props.push(` ${cleanJsdoc}
|
|
7369
|
-
${propName}${optional}: ${propType};`);
|
|
7370
|
-
} else {
|
|
7371
|
-
props.push(` ${propName}${optional}: ${propType};`);
|
|
7372
|
-
}
|
|
7373
|
-
}
|
|
7374
|
-
return `{
|
|
7375
|
-
${props.join("\n")}
|
|
7376
|
-
}`;
|
|
7377
|
-
}
|
|
7271
|
+
// REMOVED: generateNativeEnum method - no longer needed as we only generate Zod schemas
|
|
7272
|
+
// REMOVED: toEnumKey method - was only used by generateNativeEnum
|
|
7273
|
+
// REMOVED: addConstraintsToJSDoc method - was only used for native TypeScript types
|
|
7274
|
+
// REMOVED: generateNativeTypeDefinition method - was only used for native TypeScript types
|
|
7275
|
+
// REMOVED: generateObjectType method - was only used for native TypeScript types
|
|
7378
7276
|
/**
|
|
7379
7277
|
* Topological sort for schema dependencies
|
|
7380
7278
|
* Returns schemas in the order they should be declared
|
|
@@ -7386,9 +7284,6 @@ ${props.join("\n")}
|
|
|
7386
7284
|
const aliases = [];
|
|
7387
7285
|
const circularDeps = /* @__PURE__ */ new Set();
|
|
7388
7286
|
const codeCache = /* @__PURE__ */ new Map();
|
|
7389
|
-
for (const [name, code] of this.enums) {
|
|
7390
|
-
codeCache.set(name, code);
|
|
7391
|
-
}
|
|
7392
7287
|
for (const [name, code] of this.schemas) {
|
|
7393
7288
|
codeCache.set(name, code);
|
|
7394
7289
|
}
|
|
@@ -7413,7 +7308,7 @@ ${props.join("\n")}
|
|
|
7413
7308
|
const deps = this.schemaDependencies.get(name);
|
|
7414
7309
|
if (deps && deps.size > 0) {
|
|
7415
7310
|
for (const dep of deps) {
|
|
7416
|
-
if (this.
|
|
7311
|
+
if (this.schemas.has(dep) || this.types.has(dep)) {
|
|
7417
7312
|
visit(dep);
|
|
7418
7313
|
}
|
|
7419
7314
|
}
|
|
@@ -7424,7 +7319,7 @@ ${props.join("\n")}
|
|
|
7424
7319
|
sorted.push(name);
|
|
7425
7320
|
}
|
|
7426
7321
|
};
|
|
7427
|
-
const allNames = /* @__PURE__ */ new Set([...this.
|
|
7322
|
+
const allNames = /* @__PURE__ */ new Set([...this.schemas.keys(), ...this.types.keys()]);
|
|
7428
7323
|
for (const name of allNames) {
|
|
7429
7324
|
visit(name);
|
|
7430
7325
|
}
|
|
@@ -7442,7 +7337,6 @@ ${props.join("\n")}
|
|
|
7442
7337
|
generateStats() {
|
|
7443
7338
|
const stats = {
|
|
7444
7339
|
totalSchemas: this.schemas.size,
|
|
7445
|
-
enums: this.enums.size,
|
|
7446
7340
|
withCircularRefs: 0,
|
|
7447
7341
|
withDiscriminators: 0,
|
|
7448
7342
|
withConstraints: 0
|
|
@@ -7457,7 +7351,6 @@ ${props.join("\n")}
|
|
|
7457
7351
|
const output = [
|
|
7458
7352
|
"// Generation Statistics:",
|
|
7459
7353
|
`// Total schemas: ${stats.totalSchemas}`,
|
|
7460
|
-
`// Enums: ${stats.enums}`,
|
|
7461
7354
|
`// Circular references: ${stats.withCircularRefs}`,
|
|
7462
7355
|
`// Discriminated unions: ${stats.withDiscriminators}`,
|
|
7463
7356
|
`// With constraints: ${stats.withConstraints}`
|
|
@@ -7476,120 +7369,108 @@ ${props.join("\n")}
|
|
|
7476
7369
|
}
|
|
7477
7370
|
});
|
|
7478
7371
|
|
|
7479
|
-
// src/
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
Executing ${specs.length} spec(s) in parallel...
|
|
7503
|
-
`);
|
|
7504
|
-
const promises = specs.map((spec, index) => processSpec(spec, index, specs.length));
|
|
7505
|
-
const results = await Promise.allSettled(promises);
|
|
7506
|
-
return results.map((result, index) => {
|
|
7507
|
-
if (result.status === "fulfilled") {
|
|
7508
|
-
return result.value;
|
|
7509
|
-
}
|
|
7510
|
-
return {
|
|
7511
|
-
spec: specs[index],
|
|
7512
|
-
success: false,
|
|
7513
|
-
error: result.reason instanceof Error ? result.reason.message : String(result.reason)
|
|
7514
|
-
};
|
|
7515
|
-
});
|
|
7516
|
-
}
|
|
7517
|
-
async function executeSequential(specs) {
|
|
7518
|
-
console.log(`
|
|
7519
|
-
Executing ${specs.length} spec(s) sequentially...
|
|
7520
|
-
`);
|
|
7521
|
-
const results = [];
|
|
7522
|
-
for (let i = 0; i < specs.length; i++) {
|
|
7523
|
-
const result = await processSpec(specs[i], i, specs.length);
|
|
7524
|
-
results.push(result);
|
|
7372
|
+
// src/utils/config-schemas.ts
|
|
7373
|
+
import { z } from "zod";
|
|
7374
|
+
var RequestResponseOptionsSchema, OperationFiltersSchema;
|
|
7375
|
+
var init_config_schemas = __esm({
|
|
7376
|
+
"src/utils/config-schemas.ts"() {
|
|
7377
|
+
"use strict";
|
|
7378
|
+
init_esm_shims();
|
|
7379
|
+
RequestResponseOptionsSchema = z.strictObject({
|
|
7380
|
+
mode: z.enum(["strict", "normal", "loose"]).optional(),
|
|
7381
|
+
useDescribe: z.boolean().optional(),
|
|
7382
|
+
includeDescriptions: z.boolean().optional()
|
|
7383
|
+
});
|
|
7384
|
+
OperationFiltersSchema = z.strictObject({
|
|
7385
|
+
includeTags: z.array(z.string()).optional(),
|
|
7386
|
+
excludeTags: z.array(z.string()).optional(),
|
|
7387
|
+
includePaths: z.array(z.string()).optional(),
|
|
7388
|
+
excludePaths: z.array(z.string()).optional(),
|
|
7389
|
+
includeMethods: z.array(z.string()).optional(),
|
|
7390
|
+
excludeMethods: z.array(z.string()).optional(),
|
|
7391
|
+
includeOperationIds: z.array(z.string()).optional(),
|
|
7392
|
+
excludeOperationIds: z.array(z.string()).optional(),
|
|
7393
|
+
excludeDeprecated: z.boolean().optional()
|
|
7394
|
+
});
|
|
7525
7395
|
}
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7396
|
+
});
|
|
7397
|
+
|
|
7398
|
+
// src/utils/config-validation.ts
|
|
7399
|
+
function formatConfigValidationError(error, filepath, configPath, additionalNotes) {
|
|
7400
|
+
var _a;
|
|
7401
|
+
const formattedErrors = ((_a = error.issues) == null ? void 0 : _a.map((err) => {
|
|
7402
|
+
const path2 = err.path.length > 0 ? err.path.join(".") : "root";
|
|
7403
|
+
return ` - ${path2}: ${err.message}`;
|
|
7404
|
+
}).join("\n")) || "Unknown validation error";
|
|
7405
|
+
const configSource = filepath || configPath || "config file";
|
|
7406
|
+
const lines = [
|
|
7407
|
+
`Invalid configuration file at: ${configSource}`,
|
|
7408
|
+
"",
|
|
7409
|
+
"Validation errors:",
|
|
7410
|
+
formattedErrors,
|
|
7411
|
+
"",
|
|
7412
|
+
"Please check your configuration file and ensure:",
|
|
7413
|
+
" - All required fields are present (specs array with input/output)",
|
|
7414
|
+
" - Field names are spelled correctly (no typos)",
|
|
7415
|
+
" - Values match the expected types (e.g., mode: 'strict' | 'normal' | 'loose')",
|
|
7416
|
+
" - No unknown/extra properties are included"
|
|
7417
|
+
];
|
|
7418
|
+
if (additionalNotes && additionalNotes.length > 0) {
|
|
7419
|
+
lines.push(...additionalNotes.map((note) => ` - ${note}`));
|
|
7544
7420
|
}
|
|
7545
|
-
|
|
7546
|
-
`);
|
|
7421
|
+
return lines.join("\n");
|
|
7547
7422
|
}
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7423
|
+
var init_config_validation = __esm({
|
|
7424
|
+
"src/utils/config-validation.ts"() {
|
|
7425
|
+
"use strict";
|
|
7426
|
+
init_esm_shims();
|
|
7551
7427
|
}
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
}
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7428
|
+
});
|
|
7429
|
+
|
|
7430
|
+
// src/utils/typescript-loader.ts
|
|
7431
|
+
function createTypeScriptLoader() {
|
|
7432
|
+
return async (filepath) => {
|
|
7433
|
+
try {
|
|
7434
|
+
const esbuild = await import("esbuild");
|
|
7435
|
+
const fs = await import("fs");
|
|
7436
|
+
const path2 = await import("path");
|
|
7437
|
+
const tsCode = fs.readFileSync(filepath, "utf-8");
|
|
7438
|
+
const result = await esbuild.build({
|
|
7439
|
+
stdin: {
|
|
7440
|
+
contents: tsCode,
|
|
7441
|
+
loader: "ts",
|
|
7442
|
+
resolveDir: path2.dirname(filepath),
|
|
7443
|
+
sourcefile: filepath
|
|
7444
|
+
},
|
|
7445
|
+
format: "cjs",
|
|
7446
|
+
platform: "node",
|
|
7447
|
+
target: "node18",
|
|
7448
|
+
bundle: false,
|
|
7449
|
+
write: false
|
|
7450
|
+
});
|
|
7451
|
+
const jsCode = result.outputFiles[0].text;
|
|
7452
|
+
const module = { exports: {} };
|
|
7453
|
+
const func = new Function("exports", "module", "require", "__filename", "__dirname", jsCode);
|
|
7454
|
+
func(module.exports, module, __require, filepath, path2.dirname(filepath));
|
|
7455
|
+
return module.exports.default || module.exports;
|
|
7456
|
+
} catch (error) {
|
|
7457
|
+
throw new Error(
|
|
7458
|
+
`Failed to load TypeScript config from ${filepath}: ${error instanceof Error ? error.message : String(error)}`
|
|
7459
|
+
);
|
|
7573
7460
|
}
|
|
7574
|
-
}
|
|
7575
|
-
}
|
|
7576
|
-
function getBatchExitCode(summary) {
|
|
7577
|
-
return summary.failed > 0 ? 1 : 0;
|
|
7461
|
+
};
|
|
7578
7462
|
}
|
|
7579
|
-
var
|
|
7580
|
-
"src/
|
|
7463
|
+
var init_typescript_loader = __esm({
|
|
7464
|
+
"src/utils/typescript-loader.ts"() {
|
|
7581
7465
|
"use strict";
|
|
7582
7466
|
init_esm_shims();
|
|
7583
|
-
init_errors();
|
|
7584
|
-
init_openapi_generator();
|
|
7585
7467
|
}
|
|
7586
7468
|
});
|
|
7587
7469
|
|
|
7588
7470
|
// src/utils/config-loader.ts
|
|
7589
7471
|
import { cosmiconfig } from "cosmiconfig";
|
|
7590
|
-
import { z } from "zod";
|
|
7472
|
+
import { z as z2 } from "zod";
|
|
7591
7473
|
async function loadConfig(configPath) {
|
|
7592
|
-
var _a;
|
|
7593
7474
|
const explorer = cosmiconfig("openapi-to-zod", {
|
|
7594
7475
|
searchPlaces: ["openapi-to-zod.config.ts", "openapi-to-zod.config.json", "package.json"],
|
|
7595
7476
|
loaders: {
|
|
@@ -7611,24 +7492,8 @@ async function loadConfig(configPath) {
|
|
|
7611
7492
|
const validatedConfig = ConfigFileSchema.parse(result.config);
|
|
7612
7493
|
return validatedConfig;
|
|
7613
7494
|
} catch (error) {
|
|
7614
|
-
if (error instanceof
|
|
7615
|
-
const
|
|
7616
|
-
const path2 = err.path.length > 0 ? err.path.join(".") : "root";
|
|
7617
|
-
return ` - ${path2}: ${err.message}`;
|
|
7618
|
-
}).join("\n")) || "Unknown validation error";
|
|
7619
|
-
const configSource = result.filepath || configPath || "config file";
|
|
7620
|
-
const errorMessage = [
|
|
7621
|
-
`Invalid configuration file at: ${configSource}`,
|
|
7622
|
-
"",
|
|
7623
|
-
"Validation errors:",
|
|
7624
|
-
formattedErrors,
|
|
7625
|
-
"",
|
|
7626
|
-
"Please check your configuration file and ensure:",
|
|
7627
|
-
" - All required fields are present (specs array with input/output)",
|
|
7628
|
-
" - Field names are spelled correctly (no typos)",
|
|
7629
|
-
" - Values match the expected types (e.g., mode: 'strict' | 'normal' | 'loose')",
|
|
7630
|
-
" - No unknown/extra properties are included"
|
|
7631
|
-
].join("\n");
|
|
7495
|
+
if (error instanceof z2.ZodError) {
|
|
7496
|
+
const errorMessage = formatConfigValidationError(error, result.filepath, configPath);
|
|
7632
7497
|
throw new Error(errorMessage);
|
|
7633
7498
|
}
|
|
7634
7499
|
throw error;
|
|
@@ -7644,7 +7509,6 @@ function mergeConfigWithDefaults(config) {
|
|
|
7644
7509
|
// Apply defaults first
|
|
7645
7510
|
mode: defaults.mode,
|
|
7646
7511
|
includeDescriptions: defaults.includeDescriptions,
|
|
7647
|
-
enumType: defaults.enumType,
|
|
7648
7512
|
useDescribe: defaults.useDescribe,
|
|
7649
7513
|
schemaType: defaults.schemaType,
|
|
7650
7514
|
prefix: defaults.prefix,
|
|
@@ -7656,99 +7520,53 @@ function mergeConfigWithDefaults(config) {
|
|
|
7656
7520
|
return merged;
|
|
7657
7521
|
});
|
|
7658
7522
|
}
|
|
7659
|
-
var
|
|
7523
|
+
var OpenApiGeneratorOptionsSchema, ConfigFileSchema;
|
|
7660
7524
|
var init_config_loader = __esm({
|
|
7661
7525
|
"src/utils/config-loader.ts"() {
|
|
7662
7526
|
"use strict";
|
|
7663
7527
|
init_esm_shims();
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
includePaths: z.array(z.string()).optional(),
|
|
7678
|
-
excludePaths: z.array(z.string()).optional(),
|
|
7679
|
-
includeMethods: z.array(z.string()).optional(),
|
|
7680
|
-
excludeMethods: z.array(z.string()).optional(),
|
|
7681
|
-
includeOperationIds: z.array(z.string()).optional(),
|
|
7682
|
-
excludeOperationIds: z.array(z.string()).optional(),
|
|
7683
|
-
excludeDeprecated: z.boolean().optional()
|
|
7684
|
-
});
|
|
7685
|
-
OpenApiGeneratorOptionsSchema = z.strictObject({
|
|
7686
|
-
mode: z.enum(["strict", "normal", "loose"]).optional(),
|
|
7687
|
-
input: z.string(),
|
|
7688
|
-
output: z.string(),
|
|
7689
|
-
includeDescriptions: z.boolean().optional(),
|
|
7690
|
-
enumType: z.enum(["zod", "typescript"]).optional(),
|
|
7691
|
-
useDescribe: z.boolean().optional(),
|
|
7692
|
-
schemaType: z.enum(["all", "request", "response"]).optional(),
|
|
7693
|
-
prefix: z.string().optional(),
|
|
7694
|
-
suffix: z.string().optional(),
|
|
7695
|
-
showStats: z.boolean().optional(),
|
|
7696
|
-
nativeEnumType: NativeEnumTypeSchema.optional(),
|
|
7528
|
+
init_config_schemas();
|
|
7529
|
+
init_config_validation();
|
|
7530
|
+
init_typescript_loader();
|
|
7531
|
+
OpenApiGeneratorOptionsSchema = z2.strictObject({
|
|
7532
|
+
mode: z2.enum(["strict", "normal", "loose"]).optional(),
|
|
7533
|
+
input: z2.string(),
|
|
7534
|
+
output: z2.string(),
|
|
7535
|
+
includeDescriptions: z2.boolean().optional(),
|
|
7536
|
+
useDescribe: z2.boolean().optional(),
|
|
7537
|
+
schemaType: z2.enum(["all", "request", "response"]).optional(),
|
|
7538
|
+
prefix: z2.string().optional(),
|
|
7539
|
+
suffix: z2.string().optional(),
|
|
7540
|
+
showStats: z2.boolean().optional(),
|
|
7697
7541
|
request: RequestResponseOptionsSchema.optional(),
|
|
7698
7542
|
response: RequestResponseOptionsSchema.optional(),
|
|
7699
|
-
name:
|
|
7700
|
-
operationFilters: OperationFiltersSchema.optional()
|
|
7543
|
+
name: z2.string().optional(),
|
|
7544
|
+
operationFilters: OperationFiltersSchema.optional(),
|
|
7545
|
+
cacheSize: z2.number().positive().optional(),
|
|
7546
|
+
batchSize: z2.number().positive().optional()
|
|
7701
7547
|
});
|
|
7702
|
-
ConfigFileSchema =
|
|
7703
|
-
defaults:
|
|
7704
|
-
mode:
|
|
7705
|
-
includeDescriptions:
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
showStats: z.boolean().optional(),
|
|
7712
|
-
nativeEnumType: NativeEnumTypeSchema.optional(),
|
|
7548
|
+
ConfigFileSchema = z2.strictObject({
|
|
7549
|
+
defaults: z2.strictObject({
|
|
7550
|
+
mode: z2.enum(["strict", "normal", "loose"]).optional(),
|
|
7551
|
+
includeDescriptions: z2.boolean().optional(),
|
|
7552
|
+
useDescribe: z2.boolean().optional(),
|
|
7553
|
+
schemaType: z2.enum(["all", "request", "response"]).optional(),
|
|
7554
|
+
prefix: z2.string().optional(),
|
|
7555
|
+
suffix: z2.string().optional(),
|
|
7556
|
+
showStats: z2.boolean().optional(),
|
|
7713
7557
|
request: RequestResponseOptionsSchema.optional(),
|
|
7714
7558
|
response: RequestResponseOptionsSchema.optional(),
|
|
7715
|
-
operationFilters: OperationFiltersSchema.optional()
|
|
7559
|
+
operationFilters: OperationFiltersSchema.optional(),
|
|
7560
|
+
cacheSize: z2.number().positive().optional(),
|
|
7561
|
+
batchSize: z2.number().positive().optional()
|
|
7716
7562
|
}).optional(),
|
|
7717
|
-
specs:
|
|
7718
|
-
|
|
7563
|
+
specs: z2.array(OpenApiGeneratorOptionsSchema).min(1, {
|
|
7564
|
+
message: "Configuration must include at least one specification. Each specification should have 'input' and 'output' paths."
|
|
7565
|
+
}).refine((specs) => specs.every((spec) => spec.input && spec.output), {
|
|
7566
|
+
message: "Each specification must have both 'input' and 'output' paths defined"
|
|
7567
|
+
}),
|
|
7568
|
+
executionMode: z2.enum(["parallel", "sequential"]).optional()
|
|
7719
7569
|
});
|
|
7720
|
-
createTypeScriptLoader = () => {
|
|
7721
|
-
return async (filepath) => {
|
|
7722
|
-
try {
|
|
7723
|
-
const esbuild = await import("esbuild");
|
|
7724
|
-
const fs = await import("fs");
|
|
7725
|
-
const path2 = await import("path");
|
|
7726
|
-
const tsCode = fs.readFileSync(filepath, "utf-8");
|
|
7727
|
-
const result = await esbuild.build({
|
|
7728
|
-
stdin: {
|
|
7729
|
-
contents: tsCode,
|
|
7730
|
-
loader: "ts",
|
|
7731
|
-
resolveDir: path2.dirname(filepath),
|
|
7732
|
-
sourcefile: filepath
|
|
7733
|
-
},
|
|
7734
|
-
format: "cjs",
|
|
7735
|
-
platform: "node",
|
|
7736
|
-
target: "node18",
|
|
7737
|
-
bundle: false,
|
|
7738
|
-
write: false
|
|
7739
|
-
});
|
|
7740
|
-
const jsCode = result.outputFiles[0].text;
|
|
7741
|
-
const module = { exports: {} };
|
|
7742
|
-
const func = new Function("exports", "module", "require", "__filename", "__dirname", jsCode);
|
|
7743
|
-
func(module.exports, module, __require, filepath, path2.dirname(filepath));
|
|
7744
|
-
return module.exports.default || module.exports;
|
|
7745
|
-
} catch (error) {
|
|
7746
|
-
throw new Error(
|
|
7747
|
-
`Failed to load TypeScript config from ${filepath}: ${error instanceof Error ? error.message : String(error)}`
|
|
7748
|
-
);
|
|
7749
|
-
}
|
|
7750
|
-
};
|
|
7751
|
-
};
|
|
7752
7570
|
}
|
|
7753
7571
|
});
|
|
7754
7572
|
|
|
@@ -7762,6 +7580,7 @@ var require_cli = __commonJS({
|
|
|
7762
7580
|
var import_prompts = __toESM(require_prompts3());
|
|
7763
7581
|
init_batch_executor();
|
|
7764
7582
|
init_errors();
|
|
7583
|
+
init_openapi_generator();
|
|
7765
7584
|
init_config_loader();
|
|
7766
7585
|
var program = new Command();
|
|
7767
7586
|
program.name("openapi-to-zod").description("Generate Zod v4 schemas from OpenAPI specifications").version("1.0.0").option("-c, --config <path>", "Path to config file (openapi-to-zod.config.{ts,json})").addHelpText(
|
|
@@ -7769,17 +7588,13 @@ var require_cli = __commonJS({
|
|
|
7769
7588
|
`
|
|
7770
7589
|
Examples:
|
|
7771
7590
|
# Create a new config file
|
|
7772
|
-
$ openapi-to-zod
|
|
7591
|
+
$ openapi-to-zod init
|
|
7773
7592
|
|
|
7774
7593
|
# Generate with auto-discovered config
|
|
7775
7594
|
$ openapi-to-zod
|
|
7776
7595
|
|
|
7777
7596
|
# Generate with custom config path
|
|
7778
7597
|
$ openapi-to-zod --config custom.config.ts
|
|
7779
|
-
|
|
7780
|
-
Breaking Changes (v2.0):
|
|
7781
|
-
CLI options removed. Use configuration file instead.
|
|
7782
|
-
Run 'openapi-to-zod --init' to create a config file.
|
|
7783
7598
|
`
|
|
7784
7599
|
).action(async (options) => {
|
|
7785
7600
|
try {
|
|
@@ -7836,17 +7651,19 @@ Breaking Changes (v2.0):
|
|
|
7836
7651
|
return { files, totalCount };
|
|
7837
7652
|
}
|
|
7838
7653
|
async function executeConfigMode(options) {
|
|
7654
|
+
var _a, _b;
|
|
7839
7655
|
let config;
|
|
7840
7656
|
try {
|
|
7841
7657
|
config = await loadConfig(options.config);
|
|
7842
7658
|
} catch {
|
|
7843
|
-
throw new CliOptionsError("No config file found. Run 'openapi-to-zod
|
|
7659
|
+
throw new CliOptionsError("No config file found. Run 'openapi-to-zod init' to create one.", {
|
|
7844
7660
|
configPath: options.config
|
|
7845
7661
|
});
|
|
7846
7662
|
}
|
|
7847
7663
|
const specs = mergeConfigWithDefaults(config);
|
|
7848
7664
|
const executionMode = config.executionMode || "parallel";
|
|
7849
|
-
const
|
|
7665
|
+
const batchSize = (_b = (_a = specs[0]) == null ? void 0 : _a.batchSize) != null ? _b : 10;
|
|
7666
|
+
const summary = await executeBatch(specs, executionMode, (spec) => new OpenApiGenerator(spec), batchSize);
|
|
7850
7667
|
const exitCode = getBatchExitCode(summary);
|
|
7851
7668
|
if (exitCode !== 0) {
|
|
7852
7669
|
process.exit(exitCode);
|
|
@@ -7948,7 +7765,7 @@ Breaking Changes (v2.0):
|
|
|
7948
7765
|
{
|
|
7949
7766
|
type: "confirm",
|
|
7950
7767
|
name: "includeDefaults",
|
|
7951
|
-
message: "Include commonly-used defaults?
|
|
7768
|
+
message: "Include commonly-used recommended defaults?",
|
|
7952
7769
|
initial: true
|
|
7953
7770
|
}
|
|
7954
7771
|
]);
|
|
@@ -7969,7 +7786,9 @@ export default defineConfig({
|
|
|
7969
7786
|
defaults: {
|
|
7970
7787
|
mode: 'strict',
|
|
7971
7788
|
includeDescriptions: true,
|
|
7972
|
-
|
|
7789
|
+
useDescribe: false,
|
|
7790
|
+
showStats: true,
|
|
7791
|
+
schemaType: 'all',
|
|
7973
7792
|
},
|
|
7974
7793
|
specs: [
|
|
7975
7794
|
{
|