@cerios/openapi-to-zod 0.6.0 → 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);
@@ -5181,6 +5300,9 @@ var init_lru_cache = __esm({
5181
5300
  this.cache = /* @__PURE__ */ new Map();
5182
5301
  this.maxSize = maxSize;
5183
5302
  }
5303
+ get capacity() {
5304
+ return this.maxSize;
5305
+ }
5184
5306
  get(key) {
5185
5307
  if (!this.cache.has(key)) return void 0;
5186
5308
  const value = this.cache.get(key);
@@ -5766,6 +5888,11 @@ var init_object_validator = __esm({
5766
5888
  });
5767
5889
 
5768
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
+ }
5769
5896
  function generateStringValidation(schema, useDescribe) {
5770
5897
  let validation = FORMAT_MAP[schema.format || ""] || "z.string()";
5771
5898
  if (schema.minLength !== void 0) {
@@ -6411,6 +6538,7 @@ var init_operation_filters = __esm({
6411
6538
  // src/openapi-generator.ts
6412
6539
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
6413
6540
  import { dirname, normalize } from "path";
6541
+ import { minimatch as minimatch2 } from "minimatch";
6414
6542
  import { parse } from "yaml";
6415
6543
  var OpenApiGenerator;
6416
6544
  var init_openapi_generator = __esm({
@@ -6423,6 +6551,7 @@ var init_openapi_generator = __esm({
6423
6551
  init_property_generator();
6424
6552
  init_name_utils();
6425
6553
  init_operation_filters();
6554
+ init_string_validator();
6426
6555
  OpenApiGenerator = class {
6427
6556
  constructor(options) {
6428
6557
  this.schemas = /* @__PURE__ */ new Map();
@@ -6431,7 +6560,7 @@ var init_openapi_generator = __esm({
6431
6560
  this.schemaUsageMap = /* @__PURE__ */ new Map();
6432
6561
  this.needsZodImport = true;
6433
6562
  this.filterStats = createFilterStatistics();
6434
- var _a, _b, _c;
6563
+ var _a, _b, _c, _d, _e;
6435
6564
  if (!options.input) {
6436
6565
  throw new ConfigurationError("Input path is required", { providedOptions: options });
6437
6566
  }
@@ -6447,8 +6576,14 @@ var init_openapi_generator = __esm({
6447
6576
  showStats: (_c = options.showStats) != null ? _c : true,
6448
6577
  request: options.request,
6449
6578
  response: options.response,
6450
- 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
6451
6583
  };
6584
+ if (this.options.cacheSize) {
6585
+ configurePatternCache(this.options.cacheSize);
6586
+ }
6452
6587
  try {
6453
6588
  const fs = __require("fs");
6454
6589
  if (!fs.existsSync(this.options.input)) {
@@ -6584,6 +6719,7 @@ var init_openapi_generator = __esm({
6584
6719
  const normalizedOutput = normalize(this.options.output);
6585
6720
  this.ensureDirectoryExists(normalizedOutput);
6586
6721
  writeFileSync(normalizedOutput, output);
6722
+ console.log(` \u2713 Generated ${normalizedOutput}`);
6587
6723
  }
6588
6724
  /**
6589
6725
  * Resolve options for a specific context (request or response)
@@ -6994,6 +7130,24 @@ ${propsCode}
6994
7130
  }
6995
7131
  }
6996
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
+ }
6997
7151
  /**
6998
7152
  * Generate header parameter schemas for each operation
6999
7153
  * Header parameters are always string type (HTTP header semantics)
@@ -7016,7 +7170,7 @@ ${propsCode}
7016
7170
  continue;
7017
7171
  }
7018
7172
  const headerParams = operation.parameters.filter(
7019
- (param) => param && typeof param === "object" && param.in === "header"
7173
+ (param) => param && typeof param === "object" && param.in === "header" && !this.shouldIgnoreHeader(param.name)
7020
7174
  );
7021
7175
  if (headerParams.length === 0) {
7022
7176
  continue;
@@ -7215,120 +7369,108 @@ ${propsCode}
7215
7369
  }
7216
7370
  });
7217
7371
 
7218
- // src/batch-executor.ts
7219
- async function processSpec(spec, index, total) {
7220
- console.log(`Processing [${index + 1}/${total}] ${spec.input}...`);
7221
- try {
7222
- const generator = new OpenApiGenerator(spec);
7223
- generator.generate();
7224
- console.log(`\u2713 Successfully generated ${spec.output}`);
7225
- return {
7226
- spec,
7227
- success: true
7228
- };
7229
- } catch (error) {
7230
- const errorMessage = error instanceof Error ? error.message : String(error);
7231
- console.error(`\u2717 Failed to generate ${spec.output}: ${errorMessage}`);
7232
- return {
7233
- spec,
7234
- success: false,
7235
- error: errorMessage
7236
- };
7237
- }
7238
- }
7239
- async function executeParallel(specs) {
7240
- console.log(`
7241
- Executing ${specs.length} spec(s) in parallel...
7242
- `);
7243
- const promises = specs.map((spec, index) => processSpec(spec, index, specs.length));
7244
- const results = await Promise.allSettled(promises);
7245
- return results.map((result, index) => {
7246
- if (result.status === "fulfilled") {
7247
- return result.value;
7248
- }
7249
- return {
7250
- spec: specs[index],
7251
- success: false,
7252
- error: result.reason instanceof Error ? result.reason.message : String(result.reason)
7253
- };
7254
- });
7255
- }
7256
- async function executeSequential(specs) {
7257
- console.log(`
7258
- Executing ${specs.length} spec(s) sequentially...
7259
- `);
7260
- const results = [];
7261
- for (let i = 0; i < specs.length; i++) {
7262
- const result = await processSpec(specs[i], i, specs.length);
7263
- 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
+ });
7264
7395
  }
7265
- return results;
7266
- }
7267
- function printSummary(summary) {
7268
- console.log(`
7269
- ${"=".repeat(50)}`);
7270
- console.log("Batch Execution Summary");
7271
- console.log("=".repeat(50));
7272
- console.log(`Total specs: ${summary.total}`);
7273
- console.log(`Successful: ${summary.successful}`);
7274
- console.log(`Failed: ${summary.failed}`);
7275
- if (summary.failed > 0) {
7276
- console.log("\nFailed specs:");
7277
- for (const result of summary.results) {
7278
- if (!result.success) {
7279
- console.error(` \u2717 ${result.spec.input}`);
7280
- console.error(` Error: ${result.error}`);
7281
- }
7282
- }
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}`));
7283
7420
  }
7284
- console.log(`${"=".repeat(50)}
7285
- `);
7421
+ return lines.join("\n");
7286
7422
  }
7287
- async function executeBatch(specs, executionMode = "parallel") {
7288
- if (specs.length === 0) {
7289
- 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();
7290
7427
  }
7291
- let results = [];
7292
- try {
7293
- results = executionMode === "parallel" ? await executeParallel(specs) : await executeSequential(specs);
7294
- const summary = {
7295
- total: results.length,
7296
- successful: results.filter((r) => r.success).length,
7297
- failed: results.filter((r) => !r.success).length,
7298
- results
7299
- };
7300
- printSummary(summary);
7301
- return summary;
7302
- } finally {
7303
- if (results.length > 10) {
7304
- for (const result of results) {
7305
- if (result.spec) {
7306
- result.spec = null;
7307
- }
7308
- }
7309
- if (global.gc) {
7310
- global.gc();
7311
- }
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
+ );
7312
7460
  }
7313
- }
7314
- }
7315
- function getBatchExitCode(summary) {
7316
- return summary.failed > 0 ? 1 : 0;
7461
+ };
7317
7462
  }
7318
- var init_batch_executor = __esm({
7319
- "src/batch-executor.ts"() {
7463
+ var init_typescript_loader = __esm({
7464
+ "src/utils/typescript-loader.ts"() {
7320
7465
  "use strict";
7321
7466
  init_esm_shims();
7322
- init_errors();
7323
- init_openapi_generator();
7324
7467
  }
7325
7468
  });
7326
7469
 
7327
7470
  // src/utils/config-loader.ts
7328
7471
  import { cosmiconfig } from "cosmiconfig";
7329
- import { z } from "zod";
7472
+ import { z as z2 } from "zod";
7330
7473
  async function loadConfig(configPath) {
7331
- var _a;
7332
7474
  const explorer = cosmiconfig("openapi-to-zod", {
7333
7475
  searchPlaces: ["openapi-to-zod.config.ts", "openapi-to-zod.config.json", "package.json"],
7334
7476
  loaders: {
@@ -7350,24 +7492,8 @@ async function loadConfig(configPath) {
7350
7492
  const validatedConfig = ConfigFileSchema.parse(result.config);
7351
7493
  return validatedConfig;
7352
7494
  } catch (error) {
7353
- if (error instanceof z.ZodError) {
7354
- const formattedErrors = ((_a = error.issues) == null ? void 0 : _a.map((err) => {
7355
- const path2 = err.path.length > 0 ? err.path.join(".") : "root";
7356
- return ` - ${path2}: ${err.message}`;
7357
- }).join("\n")) || "Unknown validation error";
7358
- const configSource = result.filepath || configPath || "config file";
7359
- const errorMessage = [
7360
- `Invalid configuration file at: ${configSource}`,
7361
- "",
7362
- "Validation errors:",
7363
- formattedErrors,
7364
- "",
7365
- "Please check your configuration file and ensure:",
7366
- " - All required fields are present (specs array with input/output)",
7367
- " - Field names are spelled correctly (no typos)",
7368
- " - Values match the expected types (e.g., mode: 'strict' | 'normal' | 'loose')",
7369
- " - No unknown/extra properties are included"
7370
- ].join("\n");
7495
+ if (error instanceof z2.ZodError) {
7496
+ const errorMessage = formatConfigValidationError(error, result.filepath, configPath);
7371
7497
  throw new Error(errorMessage);
7372
7498
  }
7373
7499
  throw error;
@@ -7394,90 +7520,53 @@ function mergeConfigWithDefaults(config) {
7394
7520
  return merged;
7395
7521
  });
7396
7522
  }
7397
- var RequestResponseOptionsSchema, OperationFiltersSchema, OpenApiGeneratorOptionsSchema, ConfigFileSchema, createTypeScriptLoader;
7523
+ var OpenApiGeneratorOptionsSchema, ConfigFileSchema;
7398
7524
  var init_config_loader = __esm({
7399
7525
  "src/utils/config-loader.ts"() {
7400
7526
  "use strict";
7401
7527
  init_esm_shims();
7402
- RequestResponseOptionsSchema = z.strictObject({
7403
- mode: z.enum(["strict", "normal", "loose"]).optional(),
7404
- useDescribe: z.boolean().optional(),
7405
- includeDescriptions: z.boolean().optional()
7406
- });
7407
- OperationFiltersSchema = z.strictObject({
7408
- includeTags: z.array(z.string()).optional(),
7409
- excludeTags: z.array(z.string()).optional(),
7410
- includePaths: z.array(z.string()).optional(),
7411
- excludePaths: z.array(z.string()).optional(),
7412
- includeMethods: z.array(z.string()).optional(),
7413
- excludeMethods: z.array(z.string()).optional(),
7414
- includeOperationIds: z.array(z.string()).optional(),
7415
- excludeOperationIds: z.array(z.string()).optional(),
7416
- excludeDeprecated: z.boolean().optional()
7417
- });
7418
- OpenApiGeneratorOptionsSchema = z.strictObject({
7419
- mode: z.enum(["strict", "normal", "loose"]).optional(),
7420
- input: z.string(),
7421
- output: z.string(),
7422
- includeDescriptions: z.boolean().optional(),
7423
- useDescribe: z.boolean().optional(),
7424
- schemaType: z.enum(["all", "request", "response"]).optional(),
7425
- prefix: z.string().optional(),
7426
- suffix: z.string().optional(),
7427
- showStats: z.boolean().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(),
7428
7541
  request: RequestResponseOptionsSchema.optional(),
7429
7542
  response: RequestResponseOptionsSchema.optional(),
7430
- name: z.string().optional(),
7431
- operationFilters: OperationFiltersSchema.optional()
7543
+ name: z2.string().optional(),
7544
+ operationFilters: OperationFiltersSchema.optional(),
7545
+ cacheSize: z2.number().positive().optional(),
7546
+ batchSize: z2.number().positive().optional()
7432
7547
  });
7433
- ConfigFileSchema = z.strictObject({
7434
- defaults: z.strictObject({
7435
- mode: z.enum(["strict", "normal", "loose"]).optional(),
7436
- includeDescriptions: z.boolean().optional(),
7437
- useDescribe: z.boolean().optional(),
7438
- schemaType: z.enum(["all", "request", "response"]).optional(),
7439
- prefix: z.string().optional(),
7440
- suffix: z.string().optional(),
7441
- showStats: z.boolean().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(),
7442
7557
  request: RequestResponseOptionsSchema.optional(),
7443
7558
  response: RequestResponseOptionsSchema.optional(),
7444
- operationFilters: OperationFiltersSchema.optional()
7559
+ operationFilters: OperationFiltersSchema.optional(),
7560
+ cacheSize: z2.number().positive().optional(),
7561
+ batchSize: z2.number().positive().optional()
7445
7562
  }).optional(),
7446
- specs: z.array(OpenApiGeneratorOptionsSchema).min(1, "At least one spec is required"),
7447
- 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()
7448
7569
  });
7449
- createTypeScriptLoader = () => {
7450
- return async (filepath) => {
7451
- try {
7452
- const esbuild = await import("esbuild");
7453
- const fs = await import("fs");
7454
- const path2 = await import("path");
7455
- const tsCode = fs.readFileSync(filepath, "utf-8");
7456
- const result = await esbuild.build({
7457
- stdin: {
7458
- contents: tsCode,
7459
- loader: "ts",
7460
- resolveDir: path2.dirname(filepath),
7461
- sourcefile: filepath
7462
- },
7463
- format: "cjs",
7464
- platform: "node",
7465
- target: "node18",
7466
- bundle: false,
7467
- write: false
7468
- });
7469
- const jsCode = result.outputFiles[0].text;
7470
- const module = { exports: {} };
7471
- const func = new Function("exports", "module", "require", "__filename", "__dirname", jsCode);
7472
- func(module.exports, module, __require, filepath, path2.dirname(filepath));
7473
- return module.exports.default || module.exports;
7474
- } catch (error) {
7475
- throw new Error(
7476
- `Failed to load TypeScript config from ${filepath}: ${error instanceof Error ? error.message : String(error)}`
7477
- );
7478
- }
7479
- };
7480
- };
7481
7570
  }
7482
7571
  });
7483
7572
 
@@ -7491,6 +7580,7 @@ var require_cli = __commonJS({
7491
7580
  var import_prompts = __toESM(require_prompts3());
7492
7581
  init_batch_executor();
7493
7582
  init_errors();
7583
+ init_openapi_generator();
7494
7584
  init_config_loader();
7495
7585
  var program = new Command();
7496
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(
@@ -7498,17 +7588,13 @@ var require_cli = __commonJS({
7498
7588
  `
7499
7589
  Examples:
7500
7590
  # Create a new config file
7501
- $ openapi-to-zod --init
7591
+ $ openapi-to-zod init
7502
7592
 
7503
7593
  # Generate with auto-discovered config
7504
7594
  $ openapi-to-zod
7505
7595
 
7506
7596
  # Generate with custom config path
7507
7597
  $ openapi-to-zod --config custom.config.ts
7508
-
7509
- Breaking Changes (v2.0):
7510
- CLI options removed. Use configuration file instead.
7511
- Run 'openapi-to-zod --init' to create a config file.
7512
7598
  `
7513
7599
  ).action(async (options) => {
7514
7600
  try {
@@ -7565,17 +7651,19 @@ Breaking Changes (v2.0):
7565
7651
  return { files, totalCount };
7566
7652
  }
7567
7653
  async function executeConfigMode(options) {
7654
+ var _a, _b;
7568
7655
  let config;
7569
7656
  try {
7570
7657
  config = await loadConfig(options.config);
7571
7658
  } catch {
7572
- 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.", {
7573
7660
  configPath: options.config
7574
7661
  });
7575
7662
  }
7576
7663
  const specs = mergeConfigWithDefaults(config);
7577
7664
  const executionMode = config.executionMode || "parallel";
7578
- 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);
7579
7667
  const exitCode = getBatchExitCode(summary);
7580
7668
  if (exitCode !== 0) {
7581
7669
  process.exit(exitCode);
@@ -7699,7 +7787,7 @@ export default defineConfig({
7699
7787
  mode: 'strict',
7700
7788
  includeDescriptions: true,
7701
7789
  useDescribe: false,
7702
- showStats: false,
7790
+ showStats: true,
7703
7791
  schemaType: 'all',
7704
7792
  },
7705
7793
  specs: [