@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.js CHANGED
@@ -5013,10 +5013,123 @@ var ConfigurationError = class extends GeneratorError {
5013
5013
  }
5014
5014
  };
5015
5015
 
5016
+ // src/batch-executor.ts
5017
+ async function processSpec(spec, index, total, createGenerator) {
5018
+ const specInput = spec.input || "spec";
5019
+ const specOutput = spec.output || "output";
5020
+ console.log(`Processing [${index + 1}/${total}] ${specInput}...`);
5021
+ try {
5022
+ const generator = createGenerator(spec);
5023
+ generator.generate();
5024
+ return {
5025
+ spec,
5026
+ success: true
5027
+ };
5028
+ } catch (error) {
5029
+ const errorMessage = error instanceof Error ? error.message : String(error);
5030
+ console.error(`\u2717 Failed to generate ${specOutput}: ${errorMessage}`);
5031
+ return {
5032
+ spec,
5033
+ success: false,
5034
+ error: errorMessage
5035
+ };
5036
+ }
5037
+ }
5038
+ async function executeParallel(specs, createGenerator, batchSize) {
5039
+ console.log(`
5040
+ Executing ${specs.length} specification(s) in parallel (batch size: ${batchSize})...
5041
+ `);
5042
+ const results = [];
5043
+ for (let i = 0; i < specs.length; i += batchSize) {
5044
+ const batch = specs.slice(i, Math.min(i + batchSize, specs.length));
5045
+ const batchPromises = batch.map(
5046
+ (spec, batchIndex) => processSpec(spec, i + batchIndex, specs.length, createGenerator)
5047
+ );
5048
+ const batchResults = await Promise.allSettled(batchPromises);
5049
+ for (let j = 0; j < batchResults.length; j++) {
5050
+ const result = batchResults[j];
5051
+ if (result.status === "fulfilled") {
5052
+ results.push(result.value);
5053
+ } else {
5054
+ results.push({
5055
+ spec: batch[j],
5056
+ success: false,
5057
+ error: result.reason instanceof Error ? result.reason.message : String(result.reason)
5058
+ });
5059
+ }
5060
+ }
5061
+ }
5062
+ return results;
5063
+ }
5064
+ async function executeSequential(specs, createGenerator) {
5065
+ console.log(`
5066
+ Executing ${specs.length} spec(s) sequentially...
5067
+ `);
5068
+ const results = [];
5069
+ for (let i = 0; i < specs.length; i++) {
5070
+ const result = await processSpec(specs[i], i, specs.length, createGenerator);
5071
+ results.push(result);
5072
+ }
5073
+ return results;
5074
+ }
5075
+ function printSummary(summary) {
5076
+ console.log(`
5077
+ ${"=".repeat(50)}`);
5078
+ console.log("Batch Execution Summary");
5079
+ console.log("=".repeat(50));
5080
+ console.log(`Total specs: ${summary.total}`);
5081
+ console.log(`Successful: ${summary.successful}`);
5082
+ console.log(`Failed: ${summary.failed}`);
5083
+ if (summary.failed > 0) {
5084
+ console.log("\nFailed specs:");
5085
+ for (const result of summary.results) {
5086
+ if (!result.success) {
5087
+ const specInput = result.spec.input || "spec";
5088
+ console.error(` \u2717 ${specInput}`);
5089
+ console.error(` Error: ${result.error}`);
5090
+ }
5091
+ }
5092
+ }
5093
+ console.log(`${"=".repeat(50)}
5094
+ `);
5095
+ }
5096
+ async function executeBatch(specs, executionMode = "parallel", createGenerator, batchSize) {
5097
+ if (specs.length === 0) {
5098
+ throw new ConfigurationError("No specs provided for batch execution", { specsCount: 0, executionMode });
5099
+ }
5100
+ let results = [];
5101
+ try {
5102
+ results = executionMode === "parallel" ? await executeParallel(specs, createGenerator, batchSize) : await executeSequential(specs, createGenerator);
5103
+ const summary = {
5104
+ total: results.length,
5105
+ successful: results.filter((r) => r.success).length,
5106
+ failed: results.filter((r) => !r.success).length,
5107
+ results
5108
+ };
5109
+ printSummary(summary);
5110
+ return summary;
5111
+ } finally {
5112
+ if (results.length > batchSize) {
5113
+ for (const result of results) {
5114
+ if (result.spec) {
5115
+ result.spec = null;
5116
+ }
5117
+ }
5118
+ if (global.gc) {
5119
+ global.gc();
5120
+ }
5121
+ }
5122
+ }
5123
+ }
5124
+ function getBatchExitCode(summary) {
5125
+ return summary.failed > 0 ? 1 : 0;
5126
+ }
5127
+
5016
5128
  // src/openapi-generator.ts
5017
5129
  init_cjs_shims();
5018
5130
  var import_node_fs = require("fs");
5019
5131
  var import_node_path = require("path");
5132
+ var import_minimatch2 = require("minimatch");
5020
5133
  var import_yaml = require("yaml");
5021
5134
 
5022
5135
  // src/generators/enum-generator.ts
@@ -5054,34 +5167,11 @@ function resolveRef(ref) {
5054
5167
 
5055
5168
  // src/generators/enum-generator.ts
5056
5169
  function generateEnum(name, values, options) {
5057
- const enumName = name.endsWith("EnumOptions") ? name.replace("EnumOptions", "Enum") : `${name}Enum`;
5058
5170
  const schemaName = `${toCamelCase(name, options)}Schema`;
5059
- if (options.enumType === "typescript") {
5060
- const usedKeys = /* @__PURE__ */ new Set();
5061
- const enumEntries = values.map((value) => {
5062
- let key = toPascalCase(value);
5063
- if (usedKeys.has(key)) {
5064
- let counter = 2;
5065
- while (usedKeys.has(`${key}${counter}`)) {
5066
- counter++;
5067
- }
5068
- key = `${key}${counter}`;
5069
- }
5070
- usedKeys.add(key);
5071
- const stringValue = typeof value === "string" ? `"${value}"` : value;
5072
- return ` ${key} = ${stringValue},`;
5073
- }).join("\n");
5074
- const enumCode = `export enum ${enumName} {
5075
- ${enumEntries}
5076
- }`;
5077
- const schemaCode2 = `export const ${schemaName} = z.nativeEnum(${enumName});`;
5078
- const typeCode2 = `export type ${name} = z.infer<typeof ${schemaName}>;`;
5079
- return { enumCode, schemaCode: schemaCode2, typeCode: typeCode2 };
5080
- }
5081
5171
  const enumValues = values.map((v) => `"${v}"`).join(", ");
5082
5172
  const schemaCode = `export const ${schemaName} = z.enum([${enumValues}]);`;
5083
5173
  const typeCode = `export type ${name} = z.infer<typeof ${schemaName}>;`;
5084
- return { enumCode: null, schemaCode, typeCode };
5174
+ return { schemaCode, typeCode };
5085
5175
  }
5086
5176
 
5087
5177
  // src/generators/jsdoc-generator.ts
@@ -5188,6 +5278,9 @@ var LRUCache = class {
5188
5278
  this.cache = /* @__PURE__ */ new Map();
5189
5279
  this.maxSize = maxSize;
5190
5280
  }
5281
+ get capacity() {
5282
+ return this.maxSize;
5283
+ }
5191
5284
  get(key) {
5192
5285
  if (!this.cache.has(key)) return void 0;
5193
5286
  const value = this.cache.get(key);
@@ -5745,6 +5838,11 @@ ${properties.join(",\n")}
5745
5838
  // src/validators/string-validator.ts
5746
5839
  init_cjs_shims();
5747
5840
  var PATTERN_CACHE = new LRUCache(1e3);
5841
+ function configurePatternCache(size) {
5842
+ if (size > 0 && size !== PATTERN_CACHE.capacity) {
5843
+ PATTERN_CACHE = new LRUCache(size);
5844
+ }
5845
+ }
5748
5846
  var FORMAT_MAP = {
5749
5847
  uuid: "z.uuid()",
5750
5848
  email: "z.email()",
@@ -6362,14 +6460,11 @@ var OpenApiGenerator = class {
6362
6460
  constructor(options) {
6363
6461
  this.schemas = /* @__PURE__ */ new Map();
6364
6462
  this.types = /* @__PURE__ */ new Map();
6365
- this.enums = /* @__PURE__ */ new Map();
6366
- this.nativeEnums = /* @__PURE__ */ new Map();
6367
6463
  this.schemaDependencies = /* @__PURE__ */ new Map();
6368
6464
  this.schemaUsageMap = /* @__PURE__ */ new Map();
6369
- this.schemaTypeModeMap = /* @__PURE__ */ new Map();
6370
- this.needsZodImport = false;
6465
+ this.needsZodImport = true;
6371
6466
  this.filterStats = createFilterStatistics();
6372
- var _a, _b, _c;
6467
+ var _a, _b, _c, _d, _e;
6373
6468
  if (!options.input) {
6374
6469
  throw new ConfigurationError("Input path is required", { providedOptions: options });
6375
6470
  }
@@ -6378,17 +6473,21 @@ var OpenApiGenerator = class {
6378
6473
  input: options.input,
6379
6474
  output: options.output,
6380
6475
  includeDescriptions: (_a = options.includeDescriptions) != null ? _a : true,
6381
- enumType: options.enumType || "zod",
6382
6476
  useDescribe: (_b = options.useDescribe) != null ? _b : false,
6383
6477
  schemaType: options.schemaType || "all",
6384
6478
  prefix: options.prefix,
6385
6479
  suffix: options.suffix,
6386
6480
  showStats: (_c = options.showStats) != null ? _c : true,
6387
- nativeEnumType: options.nativeEnumType || "union",
6388
6481
  request: options.request,
6389
6482
  response: options.response,
6390
- operationFilters: options.operationFilters
6483
+ operationFilters: options.operationFilters,
6484
+ ignoreHeaders: options.ignoreHeaders,
6485
+ cacheSize: (_d = options.cacheSize) != null ? _d : 1e3,
6486
+ batchSize: (_e = options.batchSize) != null ? _e : 10
6391
6487
  };
6488
+ if (this.options.cacheSize) {
6489
+ configurePatternCache(this.options.cacheSize);
6490
+ }
6392
6491
  try {
6393
6492
  const fs = require("fs");
6394
6493
  if (!fs.existsSync(this.options.input)) {
@@ -6444,7 +6543,6 @@ var OpenApiGenerator = class {
6444
6543
  this.requestOptions = this.resolveOptionsForContext("request");
6445
6544
  this.responseOptions = this.resolveOptionsForContext("response");
6446
6545
  this.analyzeSchemaUsage();
6447
- this.determineSchemaTypeModes();
6448
6546
  this.propertyGenerator = new PropertyGenerator({
6449
6547
  spec: this.spec,
6450
6548
  schemaDependencies: this.schemaDependencies,
@@ -6452,8 +6550,6 @@ var OpenApiGenerator = class {
6452
6550
  mode: this.requestOptions.mode,
6453
6551
  includeDescriptions: this.requestOptions.includeDescriptions,
6454
6552
  useDescribe: this.requestOptions.useDescribe,
6455
- typeMode: this.requestOptions.typeMode,
6456
- nativeEnumType: this.requestOptions.nativeEnumType,
6457
6553
  namingOptions: {
6458
6554
  prefix: this.options.prefix,
6459
6555
  suffix: this.options.suffix
@@ -6469,25 +6565,6 @@ var OpenApiGenerator = class {
6469
6565
  if (!((_a = this.spec.components) == null ? void 0 : _a.schemas)) {
6470
6566
  throw new SpecValidationError("No schemas found in OpenAPI spec", { filePath: this.options.input });
6471
6567
  }
6472
- for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
6473
- if (schema.enum) {
6474
- const context = this.schemaUsageMap.get(name);
6475
- const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
6476
- if (resolvedOptions.enumType === "typescript") {
6477
- this.generateNativeEnum(name, schema);
6478
- } else {
6479
- const { enumCode } = generateEnum(name, schema.enum, {
6480
- enumType: "zod",
6481
- prefix: this.options.prefix,
6482
- suffix: this.options.suffix
6483
- });
6484
- if (enumCode) {
6485
- this.enums.set(name, enumCode);
6486
- this.needsZodImport = true;
6487
- }
6488
- }
6489
- }
6490
- }
6491
6568
  for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
6492
6569
  this.generateComponentSchema(name, schema);
6493
6570
  }
@@ -6504,22 +6581,11 @@ var OpenApiGenerator = class {
6504
6581
  output.push('import { z } from "zod";');
6505
6582
  output.push("");
6506
6583
  }
6507
- if (this.nativeEnums.size > 0) {
6508
- output.push("// Native Enums");
6509
- for (const enumCode of this.nativeEnums.values()) {
6510
- output.push(enumCode);
6511
- output.push("");
6512
- }
6513
- }
6514
6584
  output.push("// Schemas and Types");
6515
6585
  for (const name of orderedSchemaNames) {
6516
- const enumCode = this.enums.get(name);
6517
6586
  const schemaCode = this.schemas.get(name);
6518
6587
  const typeCode = this.types.get(name);
6519
- if (enumCode) {
6520
- output.push(enumCode);
6521
- output.push("");
6522
- } else if (schemaCode) {
6588
+ if (schemaCode) {
6523
6589
  output.push(schemaCode);
6524
6590
  if (!schemaCode.includes(`export type ${name}`)) {
6525
6591
  const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
@@ -6557,25 +6623,19 @@ var OpenApiGenerator = class {
6557
6623
  const normalizedOutput = (0, import_node_path.normalize)(this.options.output);
6558
6624
  this.ensureDirectoryExists(normalizedOutput);
6559
6625
  (0, import_node_fs.writeFileSync)(normalizedOutput, output);
6626
+ console.log(` \u2713 Generated ${normalizedOutput}`);
6560
6627
  }
6561
6628
  /**
6562
6629
  * Resolve options for a specific context (request or response)
6563
6630
  * Nested options silently override root-level options
6564
- * Response schemas always use 'inferred' mode (Zod schemas)
6565
6631
  */
6566
6632
  resolveOptionsForContext(context) {
6567
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
6633
+ var _a, _b, _c, _d, _e, _f;
6568
6634
  const contextOptions = context === "request" ? this.options.request : this.options.response;
6569
- 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";
6570
6635
  return {
6571
- mode: (_f = (_e = contextOptions == null ? void 0 : contextOptions.mode) != null ? _e : this.options.mode) != null ? _f : "normal",
6572
- enumType: (_h = (_g = contextOptions == null ? void 0 : contextOptions.enumType) != null ? _g : this.options.enumType) != null ? _h : "zod",
6573
- useDescribe: (_j = (_i = contextOptions == null ? void 0 : contextOptions.useDescribe) != null ? _i : this.options.useDescribe) != null ? _j : false,
6574
- includeDescriptions: (_l = (_k = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _k : this.options.includeDescriptions) != null ? _l : true,
6575
- // Response schemas always use 'inferred' mode (Zod schemas are required)
6576
- // Request schemas can optionally use 'native' mode
6577
- typeMode: context === "response" ? "inferred" : (_n = (_m = this.options.request) == null ? void 0 : _m.typeMode) != null ? _n : "inferred",
6578
- nativeEnumType
6636
+ mode: (_b = (_a = contextOptions == null ? void 0 : contextOptions.mode) != null ? _a : this.options.mode) != null ? _b : "normal",
6637
+ useDescribe: (_d = (_c = contextOptions == null ? void 0 : contextOptions.useDescribe) != null ? _c : this.options.useDescribe) != null ? _d : false,
6638
+ includeDescriptions: (_f = (_e = contextOptions == null ? void 0 : contextOptions.includeDescriptions) != null ? _e : this.options.includeDescriptions) != null ? _f : true
6579
6639
  };
6580
6640
  }
6581
6641
  /**
@@ -6766,28 +6826,6 @@ var OpenApiGenerator = class {
6766
6826
  detectCycle(name);
6767
6827
  }
6768
6828
  }
6769
- /**
6770
- * Determine the typeMode for each schema based on its usage context
6771
- * Response schemas always use 'inferred' mode
6772
- */
6773
- determineSchemaTypeModes() {
6774
- var _a;
6775
- for (const [name] of Object.entries(((_a = this.spec.components) == null ? void 0 : _a.schemas) || {})) {
6776
- const context = this.schemaUsageMap.get(name);
6777
- if (context === "request") {
6778
- this.schemaTypeModeMap.set(name, this.requestOptions.typeMode);
6779
- } else if (context === "response") {
6780
- this.schemaTypeModeMap.set(name, "inferred");
6781
- } else if (context === "both") {
6782
- this.schemaTypeModeMap.set(name, "inferred");
6783
- } else {
6784
- this.schemaTypeModeMap.set(name, "inferred");
6785
- }
6786
- if (this.schemaTypeModeMap.get(name) === "inferred") {
6787
- this.needsZodImport = true;
6788
- }
6789
- }
6790
- }
6791
6829
  /**
6792
6830
  * Validate the OpenAPI specification
6793
6831
  */
@@ -6863,80 +6901,54 @@ var OpenApiGenerator = class {
6863
6901
  if (!this.schemaDependencies.has(name)) {
6864
6902
  this.schemaDependencies.set(name, /* @__PURE__ */ new Set());
6865
6903
  }
6866
- const typeMode = this.schemaTypeModeMap.get(name) || "inferred";
6867
6904
  const context = this.schemaUsageMap.get(name);
6868
6905
  const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
6869
6906
  if (schema.enum) {
6870
- const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6871
- if (resolvedOptions.enumType === "typescript") {
6872
- const { schemaCode, typeCode } = generateEnum(name, schema.enum, {
6873
- enumType: "typescript",
6874
- prefix: this.options.prefix,
6875
- suffix: this.options.suffix
6876
- });
6877
- const enumSchemaCode = `${jsdoc}${schemaCode}
6878
- ${typeCode}`;
6879
- this.schemas.set(name, enumSchemaCode);
6880
- } else {
6881
- const { enumCode, schemaCode, typeCode } = generateEnum(name, schema.enum, {
6882
- enumType: "zod",
6883
- prefix: this.options.prefix,
6884
- suffix: this.options.suffix
6885
- });
6886
- if (enumCode) {
6887
- this.enums.set(name, enumCode);
6888
- }
6889
- const enumSchemaCode = `${jsdoc}${schemaCode}
6907
+ const jsdoc2 = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6908
+ const { schemaCode, typeCode } = generateEnum(name, schema.enum, {
6909
+ prefix: this.options.prefix,
6910
+ suffix: this.options.suffix
6911
+ });
6912
+ const enumSchemaCode = `${jsdoc2}${schemaCode}
6890
6913
  ${typeCode}`;
6891
- this.schemas.set(name, enumSchemaCode);
6892
- }
6914
+ this.schemas.set(name, enumSchemaCode);
6893
6915
  return;
6894
6916
  }
6895
- if (typeMode === "native") {
6896
- const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6897
- const jsdocWithConstraints = this.addConstraintsToJSDoc(jsdoc, schema, resolvedOptions.includeDescriptions);
6898
- const typeDefinition = this.generateNativeTypeDefinition(schema, name);
6899
- const typeCode = `${jsdocWithConstraints}export type ${name} = ${typeDefinition};`;
6900
- this.types.set(name, typeCode);
6901
- } else {
6902
- const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
6903
- const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6904
- if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref) {
6905
- const refName = resolveRef(schema.allOf[0].$ref);
6906
- (_a = this.schemaDependencies.get(name)) == null ? void 0 : _a.add(refName);
6907
- }
6908
- this.propertyGenerator = new PropertyGenerator({
6909
- spec: this.spec,
6910
- schemaDependencies: this.schemaDependencies,
6911
- schemaType: this.options.schemaType || "all",
6912
- mode: resolvedOptions.mode,
6913
- includeDescriptions: resolvedOptions.includeDescriptions,
6914
- useDescribe: resolvedOptions.useDescribe,
6915
- typeMode: resolvedOptions.typeMode,
6916
- nativeEnumType: resolvedOptions.nativeEnumType,
6917
- namingOptions: {
6918
- prefix: this.options.prefix,
6919
- suffix: this.options.suffix
6920
- }
6921
- });
6922
- const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
6923
- const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
6924
- const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
6925
- if (zodSchema.includes("z.discriminatedUnion(")) {
6926
- const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
6927
- if (match) {
6928
- const refs = match[1].split(",").map((ref) => ref.trim());
6929
- for (const ref of refs) {
6930
- const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
6931
- if (depMatch) {
6932
- const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
6933
- (_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
6934
- }
6917
+ const schemaName = `${toCamelCase(name, { prefix: this.options.prefix, suffix: this.options.suffix })}Schema`;
6918
+ const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
6919
+ if (schema.allOf && schema.allOf.length === 1 && schema.allOf[0].$ref) {
6920
+ const refName = resolveRef(schema.allOf[0].$ref);
6921
+ (_a = this.schemaDependencies.get(name)) == null ? void 0 : _a.add(refName);
6922
+ }
6923
+ this.propertyGenerator = new PropertyGenerator({
6924
+ spec: this.spec,
6925
+ schemaDependencies: this.schemaDependencies,
6926
+ schemaType: this.options.schemaType || "all",
6927
+ mode: resolvedOptions.mode,
6928
+ includeDescriptions: resolvedOptions.includeDescriptions,
6929
+ useDescribe: resolvedOptions.useDescribe,
6930
+ namingOptions: {
6931
+ prefix: this.options.prefix,
6932
+ suffix: this.options.suffix
6933
+ }
6934
+ });
6935
+ const isAlias = !!(schema.$ref && !schema.properties && !schema.allOf && !schema.oneOf && !schema.anyOf);
6936
+ const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, isAlias);
6937
+ const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;
6938
+ if (zodSchema.includes("z.discriminatedUnion(")) {
6939
+ const match = zodSchema.match(/z\.discriminatedUnion\([^,]+,\s*\[([^\]]+)\]/);
6940
+ if (match) {
6941
+ const refs = match[1].split(",").map((ref) => ref.trim());
6942
+ for (const ref of refs) {
6943
+ const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
6944
+ if (depMatch) {
6945
+ const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
6946
+ (_b = this.schemaDependencies.get(name)) == null ? void 0 : _b.add(depName);
6935
6947
  }
6936
6948
  }
6937
6949
  }
6938
- this.schemas.set(name, zodSchemaCode);
6939
6950
  }
6951
+ this.schemas.set(name, zodSchemaCode);
6940
6952
  }
6941
6953
  /**
6942
6954
  * Generate query parameter schemas for each operation
@@ -7022,6 +7034,24 @@ ${propsCode}
7022
7034
  }
7023
7035
  }
7024
7036
  }
7037
+ /**
7038
+ * Check if a header should be ignored based on filter patterns
7039
+ * @internal
7040
+ */
7041
+ shouldIgnoreHeader(headerName) {
7042
+ const ignorePatterns = this.options.ignoreHeaders;
7043
+ if (!ignorePatterns || ignorePatterns.length === 0) {
7044
+ return false;
7045
+ }
7046
+ if (ignorePatterns.includes("*")) {
7047
+ return true;
7048
+ }
7049
+ const headerLower = headerName.toLowerCase();
7050
+ return ignorePatterns.some((pattern) => {
7051
+ const patternLower = pattern.toLowerCase();
7052
+ return (0, import_minimatch2.minimatch)(headerLower, patternLower);
7053
+ });
7054
+ }
7025
7055
  /**
7026
7056
  * Generate header parameter schemas for each operation
7027
7057
  * Header parameters are always string type (HTTP header semantics)
@@ -7044,7 +7074,7 @@ ${propsCode}
7044
7074
  continue;
7045
7075
  }
7046
7076
  const headerParams = operation.parameters.filter(
7047
- (param) => param && typeof param === "object" && param.in === "header"
7077
+ (param) => param && typeof param === "object" && param.in === "header" && !this.shouldIgnoreHeader(param.name)
7048
7078
  );
7049
7079
  if (headerParams.length === 0) {
7050
7080
  continue;
@@ -7142,151 +7172,11 @@ ${propsCode}
7142
7172
  }
7143
7173
  return "z.unknown()";
7144
7174
  }
7145
- /**
7146
- * Generate native TypeScript enum
7147
- */
7148
- generateNativeEnum(name, schema) {
7149
- if (!schema.enum) return;
7150
- const context = this.schemaUsageMap.get(name);
7151
- const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
7152
- const jsdoc = generateJSDoc(schema, name, { includeDescriptions: resolvedOptions.includeDescriptions });
7153
- if (resolvedOptions.nativeEnumType === "enum") {
7154
- const enumName = `${name}Enum`;
7155
- const members = schema.enum.map((value) => {
7156
- const key = typeof value === "string" ? this.toEnumKey(value) : `N${value}`;
7157
- const val = typeof value === "string" ? `"${value}"` : value;
7158
- return ` ${key} = ${val}`;
7159
- }).join(",\n");
7160
- const enumCode = `${jsdoc}export enum ${enumName} {
7161
- ${members}
7162
- }`;
7163
- this.nativeEnums.set(name, enumCode);
7164
- const typeCode = `export type ${name} = ${enumName};`;
7165
- this.types.set(name, typeCode);
7166
- } else {
7167
- const unionType = schema.enum.map((v) => typeof v === "string" ? `"${v}"` : v).join(" | ");
7168
- const typeCode = `${jsdoc}export type ${name} = ${unionType};`;
7169
- this.types.set(name, typeCode);
7170
- }
7171
- }
7172
- /**
7173
- * Convert string to valid enum key
7174
- */
7175
- toEnumKey(value) {
7176
- const cleaned = value.replace(/[^a-zA-Z0-9]/g, "_");
7177
- const pascalCase = cleaned.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
7178
- return pascalCase || "Value";
7179
- }
7180
- /**
7181
- * Add constraint annotations to JSDoc for native types
7182
- */
7183
- addConstraintsToJSDoc(jsdoc, schema, includeDescriptions) {
7184
- if (!includeDescriptions) return jsdoc;
7185
- const constraints = [];
7186
- if (schema.minLength !== void 0) constraints.push(`@minLength ${schema.minLength}`);
7187
- if (schema.maxLength !== void 0) constraints.push(`@maxLength ${schema.maxLength}`);
7188
- if (schema.pattern) constraints.push(`@pattern ${schema.pattern}`);
7189
- if (schema.minimum !== void 0) constraints.push(`@minimum ${schema.minimum}`);
7190
- if (schema.maximum !== void 0) constraints.push(`@maximum ${schema.maximum}`);
7191
- if (schema.minItems !== void 0) constraints.push(`@minItems ${schema.minItems}`);
7192
- if (schema.maxItems !== void 0) constraints.push(`@maxItems ${schema.maxItems}`);
7193
- if (schema.minProperties !== void 0) constraints.push(`@minProperties ${schema.minProperties}`);
7194
- if (schema.maxProperties !== void 0) constraints.push(`@maxProperties ${schema.maxProperties}`);
7195
- if (schema.multipleOf !== void 0) constraints.push(`@multipleOf ${schema.multipleOf}`);
7196
- if (schema.format) constraints.push(`@format ${schema.format}`);
7197
- if (constraints.length === 0) return jsdoc;
7198
- if (jsdoc) {
7199
- const lines = jsdoc.trim().split("\n");
7200
- if (lines[0] === "/**" && lines[lines.length - 1] === " */") {
7201
- const newLines = [...lines.slice(0, -1), ...constraints.map((c) => ` * ${c}`), " */\n"];
7202
- return newLines.join("\n");
7203
- }
7204
- const content = jsdoc.replace("/** ", "").replace(" */\n", "");
7205
- return `/**
7206
- * ${content}
7207
- ${constraints.map((c) => ` * ${c}`).join("\n")}
7208
- */
7209
- `;
7210
- }
7211
- return `/**
7212
- ${constraints.map((c) => ` * ${c}`).join("\n")}
7213
- */
7214
- `;
7215
- }
7216
- /**
7217
- * Generate native TypeScript type definition from OpenAPI schema
7218
- */
7219
- generateNativeTypeDefinition(schema, _schemaName) {
7220
- if (schema.$ref) {
7221
- return resolveRef(schema.$ref);
7222
- }
7223
- if (schema.const !== void 0) {
7224
- return typeof schema.const === "string" ? `"${schema.const}"` : String(schema.const);
7225
- }
7226
- const isNullable2 = schema.nullable || Array.isArray(schema.type) && schema.type.includes("null");
7227
- const wrapNullable2 = (type) => isNullable2 ? `(${type}) | null` : type;
7228
- const primaryType = Array.isArray(schema.type) ? schema.type.find((t) => t !== "null") : schema.type;
7229
- switch (primaryType) {
7230
- case "string":
7231
- return wrapNullable2("string");
7232
- case "number":
7233
- case "integer":
7234
- return wrapNullable2("number");
7235
- case "boolean":
7236
- return wrapNullable2("boolean");
7237
- case "array":
7238
- if (schema.items) {
7239
- const itemType = this.generateNativeTypeDefinition(schema.items);
7240
- return wrapNullable2(`${itemType}[]`);
7241
- }
7242
- return wrapNullable2("unknown[]");
7243
- case "object":
7244
- return wrapNullable2(this.generateObjectType(schema));
7245
- default:
7246
- if (schema.allOf) {
7247
- const types = schema.allOf.map((s) => this.generateNativeTypeDefinition(s));
7248
- return wrapNullable2(types.join(" & "));
7249
- }
7250
- if (schema.oneOf || schema.anyOf) {
7251
- const schemas = schema.oneOf || schema.anyOf || [];
7252
- const types = schemas.map((s) => this.generateNativeTypeDefinition(s));
7253
- return wrapNullable2(types.join(" | "));
7254
- }
7255
- return wrapNullable2("unknown");
7256
- }
7257
- }
7258
- /**
7259
- * Generate TypeScript object type definition
7260
- */
7261
- generateObjectType(schema) {
7262
- if (!schema.properties || Object.keys(schema.properties).length === 0) {
7263
- return "Record<string, unknown>";
7264
- }
7265
- const context = this.schemaUsageMap.get(schema.$ref ? resolveRef(schema.$ref) : "");
7266
- const resolvedOptions = context === "response" ? this.responseOptions : this.requestOptions;
7267
- const required = new Set(schema.required || []);
7268
- const props = [];
7269
- for (const [propName, propSchema] of Object.entries(schema.properties)) {
7270
- const propType = this.generateNativeTypeDefinition(propSchema);
7271
- const optional = !required.has(propName) ? "?" : "";
7272
- let propJsdoc = generateJSDoc(propSchema, propName, { includeDescriptions: resolvedOptions.includeDescriptions });
7273
- if (resolvedOptions.includeDescriptions && !propJsdoc) {
7274
- propJsdoc = this.addConstraintsToJSDoc("", propSchema, resolvedOptions.includeDescriptions);
7275
- } else if (propJsdoc && resolvedOptions.includeDescriptions) {
7276
- propJsdoc = this.addConstraintsToJSDoc(propJsdoc, propSchema, resolvedOptions.includeDescriptions);
7277
- }
7278
- if (propJsdoc) {
7279
- const cleanJsdoc = propJsdoc.trimEnd();
7280
- props.push(` ${cleanJsdoc}
7281
- ${propName}${optional}: ${propType};`);
7282
- } else {
7283
- props.push(` ${propName}${optional}: ${propType};`);
7284
- }
7285
- }
7286
- return `{
7287
- ${props.join("\n")}
7288
- }`;
7289
- }
7175
+ // REMOVED: generateNativeEnum method - no longer needed as we only generate Zod schemas
7176
+ // REMOVED: toEnumKey method - was only used by generateNativeEnum
7177
+ // REMOVED: addConstraintsToJSDoc method - was only used for native TypeScript types
7178
+ // REMOVED: generateNativeTypeDefinition method - was only used for native TypeScript types
7179
+ // REMOVED: generateObjectType method - was only used for native TypeScript types
7290
7180
  /**
7291
7181
  * Topological sort for schema dependencies
7292
7182
  * Returns schemas in the order they should be declared
@@ -7298,9 +7188,6 @@ ${props.join("\n")}
7298
7188
  const aliases = [];
7299
7189
  const circularDeps = /* @__PURE__ */ new Set();
7300
7190
  const codeCache = /* @__PURE__ */ new Map();
7301
- for (const [name, code] of this.enums) {
7302
- codeCache.set(name, code);
7303
- }
7304
7191
  for (const [name, code] of this.schemas) {
7305
7192
  codeCache.set(name, code);
7306
7193
  }
@@ -7325,7 +7212,7 @@ ${props.join("\n")}
7325
7212
  const deps = this.schemaDependencies.get(name);
7326
7213
  if (deps && deps.size > 0) {
7327
7214
  for (const dep of deps) {
7328
- if (this.enums.has(dep) || this.schemas.has(dep) || this.types.has(dep)) {
7215
+ if (this.schemas.has(dep) || this.types.has(dep)) {
7329
7216
  visit(dep);
7330
7217
  }
7331
7218
  }
@@ -7336,7 +7223,7 @@ ${props.join("\n")}
7336
7223
  sorted.push(name);
7337
7224
  }
7338
7225
  };
7339
- const allNames = /* @__PURE__ */ new Set([...this.enums.keys(), ...this.schemas.keys(), ...this.types.keys()]);
7226
+ const allNames = /* @__PURE__ */ new Set([...this.schemas.keys(), ...this.types.keys()]);
7340
7227
  for (const name of allNames) {
7341
7228
  visit(name);
7342
7229
  }
@@ -7354,7 +7241,6 @@ ${props.join("\n")}
7354
7241
  generateStats() {
7355
7242
  const stats = {
7356
7243
  totalSchemas: this.schemas.size,
7357
- enums: this.enums.size,
7358
7244
  withCircularRefs: 0,
7359
7245
  withDiscriminators: 0,
7360
7246
  withConstraints: 0
@@ -7369,7 +7255,6 @@ ${props.join("\n")}
7369
7255
  const output = [
7370
7256
  "// Generation Statistics:",
7371
7257
  `// Total schemas: ${stats.totalSchemas}`,
7372
- `// Enums: ${stats.enums}`,
7373
7258
  `// Circular references: ${stats.withCircularRefs}`,
7374
7259
  `// Discriminated unions: ${stats.withDiscriminators}`,
7375
7260
  `// With constraints: ${stats.withConstraints}`
@@ -7386,120 +7271,18 @@ ${props.join("\n")}
7386
7271
  }
7387
7272
  };
7388
7273
 
7389
- // src/batch-executor.ts
7390
- async function processSpec(spec, index, total) {
7391
- console.log(`Processing [${index + 1}/${total}] ${spec.input}...`);
7392
- try {
7393
- const generator = new OpenApiGenerator(spec);
7394
- generator.generate();
7395
- console.log(`\u2713 Successfully generated ${spec.output}`);
7396
- return {
7397
- spec,
7398
- success: true
7399
- };
7400
- } catch (error) {
7401
- const errorMessage = error instanceof Error ? error.message : String(error);
7402
- console.error(`\u2717 Failed to generate ${spec.output}: ${errorMessage}`);
7403
- return {
7404
- spec,
7405
- success: false,
7406
- error: errorMessage
7407
- };
7408
- }
7409
- }
7410
- async function executeParallel(specs) {
7411
- console.log(`
7412
- Executing ${specs.length} spec(s) in parallel...
7413
- `);
7414
- const promises = specs.map((spec, index) => processSpec(spec, index, specs.length));
7415
- const results = await Promise.allSettled(promises);
7416
- return results.map((result, index) => {
7417
- if (result.status === "fulfilled") {
7418
- return result.value;
7419
- }
7420
- return {
7421
- spec: specs[index],
7422
- success: false,
7423
- error: result.reason instanceof Error ? result.reason.message : String(result.reason)
7424
- };
7425
- });
7426
- }
7427
- async function executeSequential(specs) {
7428
- console.log(`
7429
- Executing ${specs.length} spec(s) sequentially...
7430
- `);
7431
- const results = [];
7432
- for (let i = 0; i < specs.length; i++) {
7433
- const result = await processSpec(specs[i], i, specs.length);
7434
- results.push(result);
7435
- }
7436
- return results;
7437
- }
7438
- function printSummary(summary) {
7439
- console.log(`
7440
- ${"=".repeat(50)}`);
7441
- console.log("Batch Execution Summary");
7442
- console.log("=".repeat(50));
7443
- console.log(`Total specs: ${summary.total}`);
7444
- console.log(`Successful: ${summary.successful}`);
7445
- console.log(`Failed: ${summary.failed}`);
7446
- if (summary.failed > 0) {
7447
- console.log("\nFailed specs:");
7448
- for (const result of summary.results) {
7449
- if (!result.success) {
7450
- console.error(` \u2717 ${result.spec.input}`);
7451
- console.error(` Error: ${result.error}`);
7452
- }
7453
- }
7454
- }
7455
- console.log(`${"=".repeat(50)}
7456
- `);
7457
- }
7458
- async function executeBatch(specs, executionMode = "parallel") {
7459
- if (specs.length === 0) {
7460
- throw new ConfigurationError("No specs provided for batch execution", { specsCount: 0, executionMode });
7461
- }
7462
- let results = [];
7463
- try {
7464
- results = executionMode === "parallel" ? await executeParallel(specs) : await executeSequential(specs);
7465
- const summary = {
7466
- total: results.length,
7467
- successful: results.filter((r) => r.success).length,
7468
- failed: results.filter((r) => !r.success).length,
7469
- results
7470
- };
7471
- printSummary(summary);
7472
- return summary;
7473
- } finally {
7474
- if (results.length > 10) {
7475
- for (const result of results) {
7476
- if (result.spec) {
7477
- result.spec = null;
7478
- }
7479
- }
7480
- if (global.gc) {
7481
- global.gc();
7482
- }
7483
- }
7484
- }
7485
- }
7486
- function getBatchExitCode(summary) {
7487
- return summary.failed > 0 ? 1 : 0;
7488
- }
7489
-
7490
7274
  // src/utils/config-loader.ts
7491
7275
  init_cjs_shims();
7492
7276
  var import_cosmiconfig = require("cosmiconfig");
7277
+ var import_zod2 = require("zod");
7278
+
7279
+ // src/utils/config-schemas.ts
7280
+ init_cjs_shims();
7493
7281
  var import_zod = require("zod");
7494
- var TypeModeSchema = import_zod.z.enum(["inferred", "native"]);
7495
- var NativeEnumTypeSchema = import_zod.z.enum(["union", "enum"]);
7496
7282
  var RequestResponseOptionsSchema = import_zod.z.strictObject({
7497
7283
  mode: import_zod.z.enum(["strict", "normal", "loose"]).optional(),
7498
- enumType: import_zod.z.enum(["zod", "typescript"]).optional(),
7499
7284
  useDescribe: import_zod.z.boolean().optional(),
7500
- includeDescriptions: import_zod.z.boolean().optional(),
7501
- typeMode: TypeModeSchema.optional(),
7502
- nativeEnumType: NativeEnumTypeSchema.optional()
7285
+ includeDescriptions: import_zod.z.boolean().optional()
7503
7286
  });
7504
7287
  var OperationFiltersSchema = import_zod.z.strictObject({
7505
7288
  includeTags: import_zod.z.array(import_zod.z.string()).optional(),
@@ -7512,42 +7295,37 @@ var OperationFiltersSchema = import_zod.z.strictObject({
7512
7295
  excludeOperationIds: import_zod.z.array(import_zod.z.string()).optional(),
7513
7296
  excludeDeprecated: import_zod.z.boolean().optional()
7514
7297
  });
7515
- var OpenApiGeneratorOptionsSchema = import_zod.z.strictObject({
7516
- mode: import_zod.z.enum(["strict", "normal", "loose"]).optional(),
7517
- input: import_zod.z.string(),
7518
- output: import_zod.z.string(),
7519
- includeDescriptions: import_zod.z.boolean().optional(),
7520
- enumType: import_zod.z.enum(["zod", "typescript"]).optional(),
7521
- useDescribe: import_zod.z.boolean().optional(),
7522
- schemaType: import_zod.z.enum(["all", "request", "response"]).optional(),
7523
- prefix: import_zod.z.string().optional(),
7524
- suffix: import_zod.z.string().optional(),
7525
- showStats: import_zod.z.boolean().optional(),
7526
- nativeEnumType: NativeEnumTypeSchema.optional(),
7527
- request: RequestResponseOptionsSchema.optional(),
7528
- response: RequestResponseOptionsSchema.optional(),
7529
- name: import_zod.z.string().optional(),
7530
- operationFilters: OperationFiltersSchema.optional()
7531
- });
7532
- var ConfigFileSchema = import_zod.z.strictObject({
7533
- defaults: import_zod.z.strictObject({
7534
- mode: import_zod.z.enum(["strict", "normal", "loose"]).optional(),
7535
- includeDescriptions: import_zod.z.boolean().optional(),
7536
- enumType: import_zod.z.enum(["zod", "typescript"]).optional(),
7537
- useDescribe: import_zod.z.boolean().optional(),
7538
- schemaType: import_zod.z.enum(["all", "request", "response"]).optional(),
7539
- prefix: import_zod.z.string().optional(),
7540
- suffix: import_zod.z.string().optional(),
7541
- showStats: import_zod.z.boolean().optional(),
7542
- nativeEnumType: NativeEnumTypeSchema.optional(),
7543
- request: RequestResponseOptionsSchema.optional(),
7544
- response: RequestResponseOptionsSchema.optional(),
7545
- operationFilters: OperationFiltersSchema.optional()
7546
- }).optional(),
7547
- specs: import_zod.z.array(OpenApiGeneratorOptionsSchema).min(1, "At least one spec is required"),
7548
- executionMode: import_zod.z.enum(["parallel", "sequential"]).optional()
7549
- });
7550
- var createTypeScriptLoader = () => {
7298
+
7299
+ // src/utils/config-validation.ts
7300
+ init_cjs_shims();
7301
+ function formatConfigValidationError(error, filepath, configPath, additionalNotes) {
7302
+ var _a;
7303
+ const formattedErrors = ((_a = error.issues) == null ? void 0 : _a.map((err) => {
7304
+ const path = err.path.length > 0 ? err.path.join(".") : "root";
7305
+ return ` - ${path}: ${err.message}`;
7306
+ }).join("\n")) || "Unknown validation error";
7307
+ const configSource = filepath || configPath || "config file";
7308
+ const lines = [
7309
+ `Invalid configuration file at: ${configSource}`,
7310
+ "",
7311
+ "Validation errors:",
7312
+ formattedErrors,
7313
+ "",
7314
+ "Please check your configuration file and ensure:",
7315
+ " - All required fields are present (specs array with input/output)",
7316
+ " - Field names are spelled correctly (no typos)",
7317
+ " - Values match the expected types (e.g., mode: 'strict' | 'normal' | 'loose')",
7318
+ " - No unknown/extra properties are included"
7319
+ ];
7320
+ if (additionalNotes && additionalNotes.length > 0) {
7321
+ lines.push(...additionalNotes.map((note) => ` - ${note}`));
7322
+ }
7323
+ return lines.join("\n");
7324
+ }
7325
+
7326
+ // src/utils/typescript-loader.ts
7327
+ init_cjs_shims();
7328
+ function createTypeScriptLoader() {
7551
7329
  return async (filepath) => {
7552
7330
  try {
7553
7331
  const esbuild = await import("esbuild");
@@ -7578,9 +7356,49 @@ var createTypeScriptLoader = () => {
7578
7356
  );
7579
7357
  }
7580
7358
  };
7581
- };
7359
+ }
7360
+
7361
+ // src/utils/config-loader.ts
7362
+ var OpenApiGeneratorOptionsSchema = import_zod2.z.strictObject({
7363
+ mode: import_zod2.z.enum(["strict", "normal", "loose"]).optional(),
7364
+ input: import_zod2.z.string(),
7365
+ output: import_zod2.z.string(),
7366
+ includeDescriptions: import_zod2.z.boolean().optional(),
7367
+ useDescribe: import_zod2.z.boolean().optional(),
7368
+ schemaType: import_zod2.z.enum(["all", "request", "response"]).optional(),
7369
+ prefix: import_zod2.z.string().optional(),
7370
+ suffix: import_zod2.z.string().optional(),
7371
+ showStats: import_zod2.z.boolean().optional(),
7372
+ request: RequestResponseOptionsSchema.optional(),
7373
+ response: RequestResponseOptionsSchema.optional(),
7374
+ name: import_zod2.z.string().optional(),
7375
+ operationFilters: OperationFiltersSchema.optional(),
7376
+ cacheSize: import_zod2.z.number().positive().optional(),
7377
+ batchSize: import_zod2.z.number().positive().optional()
7378
+ });
7379
+ var ConfigFileSchema = import_zod2.z.strictObject({
7380
+ defaults: import_zod2.z.strictObject({
7381
+ mode: import_zod2.z.enum(["strict", "normal", "loose"]).optional(),
7382
+ includeDescriptions: import_zod2.z.boolean().optional(),
7383
+ useDescribe: import_zod2.z.boolean().optional(),
7384
+ schemaType: import_zod2.z.enum(["all", "request", "response"]).optional(),
7385
+ prefix: import_zod2.z.string().optional(),
7386
+ suffix: import_zod2.z.string().optional(),
7387
+ showStats: import_zod2.z.boolean().optional(),
7388
+ request: RequestResponseOptionsSchema.optional(),
7389
+ response: RequestResponseOptionsSchema.optional(),
7390
+ operationFilters: OperationFiltersSchema.optional(),
7391
+ cacheSize: import_zod2.z.number().positive().optional(),
7392
+ batchSize: import_zod2.z.number().positive().optional()
7393
+ }).optional(),
7394
+ specs: import_zod2.z.array(OpenApiGeneratorOptionsSchema).min(1, {
7395
+ message: "Configuration must include at least one specification. Each specification should have 'input' and 'output' paths."
7396
+ }).refine((specs) => specs.every((spec) => spec.input && spec.output), {
7397
+ message: "Each specification must have both 'input' and 'output' paths defined"
7398
+ }),
7399
+ executionMode: import_zod2.z.enum(["parallel", "sequential"]).optional()
7400
+ });
7582
7401
  async function loadConfig(configPath) {
7583
- var _a;
7584
7402
  const explorer = (0, import_cosmiconfig.cosmiconfig)("openapi-to-zod", {
7585
7403
  searchPlaces: ["openapi-to-zod.config.ts", "openapi-to-zod.config.json", "package.json"],
7586
7404
  loaders: {
@@ -7602,24 +7420,8 @@ async function loadConfig(configPath) {
7602
7420
  const validatedConfig = ConfigFileSchema.parse(result.config);
7603
7421
  return validatedConfig;
7604
7422
  } catch (error) {
7605
- if (error instanceof import_zod.z.ZodError) {
7606
- const formattedErrors = ((_a = error.issues) == null ? void 0 : _a.map((err) => {
7607
- const path = err.path.length > 0 ? err.path.join(".") : "root";
7608
- return ` - ${path}: ${err.message}`;
7609
- }).join("\n")) || "Unknown validation error";
7610
- const configSource = result.filepath || configPath || "config file";
7611
- const errorMessage = [
7612
- `Invalid configuration file at: ${configSource}`,
7613
- "",
7614
- "Validation errors:",
7615
- formattedErrors,
7616
- "",
7617
- "Please check your configuration file and ensure:",
7618
- " - All required fields are present (specs array with input/output)",
7619
- " - Field names are spelled correctly (no typos)",
7620
- " - Values match the expected types (e.g., mode: 'strict' | 'normal' | 'loose')",
7621
- " - No unknown/extra properties are included"
7622
- ].join("\n");
7423
+ if (error instanceof import_zod2.z.ZodError) {
7424
+ const errorMessage = formatConfigValidationError(error, result.filepath, configPath);
7623
7425
  throw new Error(errorMessage);
7624
7426
  }
7625
7427
  throw error;
@@ -7635,7 +7437,6 @@ function mergeConfigWithDefaults(config) {
7635
7437
  // Apply defaults first
7636
7438
  mode: defaults.mode,
7637
7439
  includeDescriptions: defaults.includeDescriptions,
7638
- enumType: defaults.enumType,
7639
7440
  useDescribe: defaults.useDescribe,
7640
7441
  schemaType: defaults.schemaType,
7641
7442
  prefix: defaults.prefix,
@@ -7655,17 +7456,13 @@ program.name("openapi-to-zod").description("Generate Zod v4 schemas from OpenAPI
7655
7456
  `
7656
7457
  Examples:
7657
7458
  # Create a new config file
7658
- $ openapi-to-zod --init
7459
+ $ openapi-to-zod init
7659
7460
 
7660
7461
  # Generate with auto-discovered config
7661
7462
  $ openapi-to-zod
7662
7463
 
7663
7464
  # Generate with custom config path
7664
7465
  $ openapi-to-zod --config custom.config.ts
7665
-
7666
- Breaking Changes (v2.0):
7667
- CLI options removed. Use configuration file instead.
7668
- Run 'openapi-to-zod --init' to create a config file.
7669
7466
  `
7670
7467
  ).action(async (options) => {
7671
7468
  try {
@@ -7722,17 +7519,19 @@ function findSpecFiles() {
7722
7519
  return { files, totalCount };
7723
7520
  }
7724
7521
  async function executeConfigMode(options) {
7522
+ var _a, _b;
7725
7523
  let config;
7726
7524
  try {
7727
7525
  config = await loadConfig(options.config);
7728
7526
  } catch {
7729
- throw new CliOptionsError("No config file found. Run 'openapi-to-zod --init' to create one.", {
7527
+ throw new CliOptionsError("No config file found. Run 'openapi-to-zod init' to create one.", {
7730
7528
  configPath: options.config
7731
7529
  });
7732
7530
  }
7733
7531
  const specs = mergeConfigWithDefaults(config);
7734
7532
  const executionMode = config.executionMode || "parallel";
7735
- const summary = await executeBatch(specs, executionMode);
7533
+ const batchSize = (_b = (_a = specs[0]) == null ? void 0 : _a.batchSize) != null ? _b : 10;
7534
+ const summary = await executeBatch(specs, executionMode, (spec) => new OpenApiGenerator(spec), batchSize);
7736
7535
  const exitCode = getBatchExitCode(summary);
7737
7536
  if (exitCode !== 0) {
7738
7537
  process.exit(exitCode);
@@ -7834,7 +7633,7 @@ async function initConfigFile() {
7834
7633
  {
7835
7634
  type: "confirm",
7836
7635
  name: "includeDefaults",
7837
- message: "Include commonly-used defaults? (mode: strict, includeDescriptions: true, showStats: false)",
7636
+ message: "Include commonly-used recommended defaults?",
7838
7637
  initial: true
7839
7638
  }
7840
7639
  ]);
@@ -7855,7 +7654,9 @@ export default defineConfig({
7855
7654
  defaults: {
7856
7655
  mode: 'strict',
7857
7656
  includeDescriptions: true,
7858
- showStats: false,
7657
+ useDescribe: false,
7658
+ showStats: true,
7659
+ schemaType: 'all',
7859
7660
  },
7860
7661
  specs: [
7861
7662
  {