@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/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 { enumCode: null, schemaCode, typeCode };
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.schemaTypeModeMap = /* @__PURE__ */ new Map();
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 (enumCode) {
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, _g, _h, _i, _j, _k, _l, _m, _n;
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: (_f = (_e = contextOptions == null ? void 0 : contextOptions.mode) != null ? _e : this.options.mode) != null ? _f : "normal",
6660
- enumType: (_h = (_g = contextOptions == null ? void 0 : contextOptions.enumType) != null ? _g : this.options.enumType) != null ? _h : "zod",
6661
- useDescribe: (_j = (_i = contextOptions == null ? void 0 : contextOptions.useDescribe) != null ? _i : this.options.useDescribe) != null ? _j : false,
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 jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6959
- if (resolvedOptions.enumType === "typescript") {
6960
- const { schemaCode, typeCode } = generateEnum(name, schema.enum, {
6961
- enumType: "typescript",
6962
- prefix: this.options.prefix,
6963
- suffix: this.options.suffix
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
- this.schemas.set(name, enumSchemaCode);
6980
- }
7010
+ this.schemas.set(name, enumSchemaCode);
6981
7011
  return;
6982
7012
  }
6983
- if (typeMode === "native") {
6984
- const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6985
- const jsdocWithConstraints = this.addConstraintsToJSDoc(jsdoc, schema, resolvedOptions.includeDescriptions);
6986
- const typeDefinition = this.generateNativeTypeDefinition(schema, name);
6987
- const typeCode = `${jsdocWithConstraints}export type ${name} = ${typeDefinition};`;
6988
- this.types.set(name, typeCode);
6989
- } else {
6990
- const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
6991
- const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6992
- if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref) {
6993
- const refName = resolveRef(schema.allOf[0].$ref);
6994
- (_a = this.schemaDependencies.get(name)) == null ? void 0 : _a.add(refName);
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
- this.propertyGenerator = new PropertyGenerator({
6997
- spec: this.spec,
6998
- schemaDependencies: this.schemaDependencies,
6999
- schemaType: this.options.schemaType || "all",
7000
- mode: resolvedOptions.mode,
7001
- includeDescriptions: resolvedOptions.includeDescriptions,
7002
- useDescribe: resolvedOptions.useDescribe,
7003
- typeMode: resolvedOptions.typeMode,
7004
- nativeEnumType: resolvedOptions.nativeEnumType,
7005
- namingOptions: {
7006
- prefix: this.options.prefix,
7007
- suffix: this.options.suffix
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
- * Generate native TypeScript enum
7235
- */
7236
- generateNativeEnum(name, schema) {
7237
- if (!schema.enum) return;
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.enums.has(dep) || this.schemas.has(dep) || this.types.has(dep)) {
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.enums.keys(), ...this.schemas.keys(), ...this.types.keys()]);
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/batch-executor.ts
7480
- async function processSpec(spec, index, total) {
7481
- console.log(`Processing [${index + 1}/${total}] ${spec.input}...`);
7482
- try {
7483
- const generator = new OpenApiGenerator(spec);
7484
- generator.generate();
7485
- console.log(`\u2713 Successfully generated ${spec.output}`);
7486
- return {
7487
- spec,
7488
- success: true
7489
- };
7490
- } catch (error) {
7491
- const errorMessage = error instanceof Error ? error.message : String(error);
7492
- console.error(`\u2717 Failed to generate ${spec.output}: ${errorMessage}`);
7493
- return {
7494
- spec,
7495
- success: false,
7496
- error: errorMessage
7497
- };
7498
- }
7499
- }
7500
- async function executeParallel(specs) {
7501
- console.log(`
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
- return results;
7527
- }
7528
- function printSummary(summary) {
7529
- console.log(`
7530
- ${"=".repeat(50)}`);
7531
- console.log("Batch Execution Summary");
7532
- console.log("=".repeat(50));
7533
- console.log(`Total specs: ${summary.total}`);
7534
- console.log(`Successful: ${summary.successful}`);
7535
- console.log(`Failed: ${summary.failed}`);
7536
- if (summary.failed > 0) {
7537
- console.log("\nFailed specs:");
7538
- for (const result of summary.results) {
7539
- if (!result.success) {
7540
- console.error(` \u2717 ${result.spec.input}`);
7541
- console.error(` Error: ${result.error}`);
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
- console.log(`${"=".repeat(50)}
7546
- `);
7421
+ return lines.join("\n");
7547
7422
  }
7548
- async function executeBatch(specs, executionMode = "parallel") {
7549
- if (specs.length === 0) {
7550
- throw new ConfigurationError("No specs provided for batch execution", { specsCount: 0, executionMode });
7423
+ var init_config_validation = __esm({
7424
+ "src/utils/config-validation.ts"() {
7425
+ "use strict";
7426
+ init_esm_shims();
7551
7427
  }
7552
- let results = [];
7553
- try {
7554
- results = executionMode === "parallel" ? await executeParallel(specs) : await executeSequential(specs);
7555
- const summary = {
7556
- total: results.length,
7557
- successful: results.filter((r) => r.success).length,
7558
- failed: results.filter((r) => !r.success).length,
7559
- results
7560
- };
7561
- printSummary(summary);
7562
- return summary;
7563
- } finally {
7564
- if (results.length > 10) {
7565
- for (const result of results) {
7566
- if (result.spec) {
7567
- result.spec = null;
7568
- }
7569
- }
7570
- if (global.gc) {
7571
- global.gc();
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 init_batch_executor = __esm({
7580
- "src/batch-executor.ts"() {
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 z.ZodError) {
7615
- const formattedErrors = ((_a = error.issues) == null ? void 0 : _a.map((err) => {
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 TypeModeSchema, NativeEnumTypeSchema, RequestResponseOptionsSchema, OperationFiltersSchema, OpenApiGeneratorOptionsSchema, ConfigFileSchema, createTypeScriptLoader;
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
- TypeModeSchema = z.enum(["inferred", "native"]);
7665
- NativeEnumTypeSchema = z.enum(["union", "enum"]);
7666
- RequestResponseOptionsSchema = z.strictObject({
7667
- mode: z.enum(["strict", "normal", "loose"]).optional(),
7668
- enumType: z.enum(["zod", "typescript"]).optional(),
7669
- useDescribe: z.boolean().optional(),
7670
- includeDescriptions: z.boolean().optional(),
7671
- typeMode: TypeModeSchema.optional(),
7672
- nativeEnumType: NativeEnumTypeSchema.optional()
7673
- });
7674
- OperationFiltersSchema = z.strictObject({
7675
- includeTags: z.array(z.string()).optional(),
7676
- excludeTags: z.array(z.string()).optional(),
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: z.string().optional(),
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 = z.strictObject({
7703
- defaults: z.strictObject({
7704
- mode: z.enum(["strict", "normal", "loose"]).optional(),
7705
- includeDescriptions: z.boolean().optional(),
7706
- enumType: z.enum(["zod", "typescript"]).optional(),
7707
- useDescribe: z.boolean().optional(),
7708
- schemaType: z.enum(["all", "request", "response"]).optional(),
7709
- prefix: z.string().optional(),
7710
- suffix: z.string().optional(),
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: z.array(OpenApiGeneratorOptionsSchema).min(1, "At least one spec is required"),
7718
- executionMode: z.enum(["parallel", "sequential"]).optional()
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 --init
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 --init' to create one.", {
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 summary = await executeBatch(specs, executionMode);
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? (mode: strict, includeDescriptions: true, showStats: false)",
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
- showStats: false,
7789
+ useDescribe: false,
7790
+ showStats: true,
7791
+ schemaType: 'all',
7973
7792
  },
7974
7793
  specs: [
7975
7794
  {