@cerios/openapi-to-zod 1.5.1 → 1.6.1

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
@@ -5140,9 +5140,11 @@ function isDiscriminatorRequired(schemas, discriminator, context) {
5140
5140
  };
5141
5141
  }
5142
5142
  function generateUnion(schemas, discriminator, isNullable2, context, options, currentSchema) {
5143
+ var _a, _b;
5143
5144
  if (schemas.length === 0) {
5144
- console.warn(
5145
- "[openapi-to-zod] Warning: Empty oneOf/anyOf array encountered. This is likely a malformed OpenAPI spec. Generating z.never() as fallback."
5145
+ (_a = context.warn) == null ? void 0 : _a.call(
5146
+ context,
5147
+ "Empty oneOf/anyOf array encountered. This is likely a malformed OpenAPI spec. Generating z.never() as fallback."
5146
5148
  );
5147
5149
  return wrapNullable(
5148
5150
  'z.never().describe("Empty oneOf/anyOf in OpenAPI spec - no valid schema defined")',
@@ -5163,8 +5165,9 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5163
5165
  }
5164
5166
  const discriminatorCheck = isDiscriminatorRequired(resolvedSchemas, discriminator, context);
5165
5167
  if (!discriminatorCheck.valid) {
5166
- console.warn(
5167
- `[openapi-to-zod] Warning: Discriminator "${discriminator}" is not required in schemas: ${discriminatorCheck.invalidSchemas.join(", ")}. Falling back to z.union() instead of z.discriminatedUnion().`
5168
+ (_b = context.warn) == null ? void 0 : _b.call(
5169
+ context,
5170
+ `Discriminator "${discriminator}" is not required in schemas: ${discriminatorCheck.invalidSchemas.join(", ")}. Falling back to z.union() instead of z.discriminatedUnion().`
5168
5171
  );
5169
5172
  let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5170
5173
  if (options == null ? void 0 : options.passthrough) {
@@ -5242,6 +5245,7 @@ function detectConflictingProperties(schemas, context) {
5242
5245
  return conflicts;
5243
5246
  }
5244
5247
  function generateAllOf(schemas, isNullable2, context, currentSchema) {
5248
+ var _a;
5245
5249
  if (schemas.length === 1) {
5246
5250
  const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
5247
5251
  return { schema: wrapNullable(singleSchema, isNullable2), conflicts: [] };
@@ -5250,7 +5254,7 @@ function generateAllOf(schemas, isNullable2, context, currentSchema) {
5250
5254
  const uniqueConflicts = [...new Set(conflicts)];
5251
5255
  if (uniqueConflicts.length > 0) {
5252
5256
  for (const conflict of uniqueConflicts) {
5253
- console.warn(`[openapi-to-zod] Warning: allOf composition conflict - ${conflict}`);
5257
+ (_a = context.warn) == null ? void 0 : _a.call(context, `allOf composition conflict - ${conflict}`);
5254
5258
  }
5255
5259
  }
5256
5260
  const allObjects = schemas.every((s) => s.type === "object" || s.properties || s.$ref || s.allOf);
@@ -6222,7 +6226,8 @@ var init_property_generator = __esm({
6222
6226
  {
6223
6227
  generatePropertySchema: this.generatePropertySchema.bind(this),
6224
6228
  generateInlineObjectShape: this.generateInlineObjectShape.bind(this),
6225
- resolveSchemaRef: this.resolveSchemaRef.bind(this)
6229
+ resolveSchemaRef: this.resolveSchemaRef.bind(this),
6230
+ warn: this.context.warn
6226
6231
  },
6227
6232
  currentSchema
6228
6233
  );
@@ -6245,7 +6250,8 @@ var init_property_generator = __esm({
6245
6250
  {
6246
6251
  generatePropertySchema: this.generatePropertySchema.bind(this),
6247
6252
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
6248
- resolveSchemaRef: this.resolveSchemaRef.bind(this)
6253
+ resolveSchemaRef: this.resolveSchemaRef.bind(this),
6254
+ warn: this.context.warn
6249
6255
  },
6250
6256
  {
6251
6257
  passthrough: needsPassthrough,
@@ -6268,7 +6274,8 @@ var init_property_generator = __esm({
6268
6274
  {
6269
6275
  generatePropertySchema: this.generatePropertySchema.bind(this),
6270
6276
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
6271
- resolveSchemaRef: this.resolveSchemaRef.bind(this)
6277
+ resolveSchemaRef: this.resolveSchemaRef.bind(this),
6278
+ warn: this.context.warn
6272
6279
  },
6273
6280
  {
6274
6281
  passthrough: needsPassthrough,
@@ -6420,6 +6427,8 @@ import {
6420
6427
  expandTransitiveReferences,
6421
6428
  extractSchemaRefs,
6422
6429
  formatFilterStatistics,
6430
+ generateCustomFileHeader,
6431
+ generateFileHeader,
6423
6432
  getOperationName,
6424
6433
  LRUCache as LRUCache2,
6425
6434
  loadOpenAPISpec,
@@ -6432,7 +6441,8 @@ import {
6432
6441
  stripPrefix as stripPrefix2,
6433
6442
  toCamelCase as toCamelCase3,
6434
6443
  toPascalCase as toPascalCase3,
6435
- validateFilters
6444
+ validateFilters,
6445
+ WarningCollector
6436
6446
  } from "@cerios/openapi-core";
6437
6447
  import { TypeScriptGenerator } from "@cerios/openapi-to-typescript";
6438
6448
  import { minimatch } from "minimatch";
@@ -6460,8 +6470,6 @@ var init_openapi_generator = __esm({
6460
6470
  this.schemaUsageMap = /* @__PURE__ */ new Map();
6461
6471
  this.needsZodImport = true;
6462
6472
  this.filterStats = createFilterStatistics();
6463
- /** Track total allOf conflicts detected across all schemas */
6464
- this.allOfConflictCount = 0;
6465
6473
  /** Track schemas involved in circular dependency chains */
6466
6474
  this.circularDependencies = /* @__PURE__ */ new Set();
6467
6475
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
@@ -6469,6 +6477,11 @@ var init_openapi_generator = __esm({
6469
6477
  throw new ConfigurationError("Input path is required", { providedOptions: options });
6470
6478
  }
6471
6479
  this.separateSchemasMode = Boolean(options.outputZodSchemas);
6480
+ const showWarnings = options.showWarnings !== false;
6481
+ this.warningCollector = new WarningCollector({
6482
+ packageName: "@cerios/openapi-to-zod",
6483
+ enabled: showWarnings
6484
+ });
6472
6485
  this.options = {
6473
6486
  mode: options.mode || "normal",
6474
6487
  input: options.input,
@@ -6487,13 +6500,16 @@ var init_openapi_generator = __esm({
6487
6500
  stripPathPrefix: options.stripPathPrefix,
6488
6501
  useOperationId: (_f = options.useOperationId) != null ? _f : true,
6489
6502
  showStats: (_g = options.showStats) != null ? _g : true,
6503
+ showWarnings,
6490
6504
  request: options.request,
6491
6505
  response: options.response,
6492
6506
  operationFilters: options.operationFilters,
6493
6507
  ignoreHeaders: options.ignoreHeaders,
6494
6508
  cacheSize: (_h = options.cacheSize) != null ? _h : 1e3,
6495
6509
  batchSize: (_i = options.batchSize) != null ? _i : 10,
6496
- customDateTimeFormatRegex: options.customDateTimeFormatRegex
6510
+ customDateTimeFormatRegex: options.customDateTimeFormatRegex,
6511
+ includeHeader: options.includeHeader,
6512
+ fileHeader: options.fileHeader
6497
6513
  };
6498
6514
  this.patternCache = new LRUCache2((_j = this.options.cacheSize) != null ? _j : 1e3);
6499
6515
  this.dateTimeValidation = buildDateTimeValidation(this.options.customDateTimeFormatRegex);
@@ -6518,7 +6534,10 @@ var init_openapi_generator = __esm({
6518
6534
  stripSchemaPrefix: this.options.stripSchemaPrefix,
6519
6535
  dateTimeValidation: this.dateTimeValidation,
6520
6536
  patternCache: this.patternCache,
6521
- separateTypesFile: this.separateSchemasMode
6537
+ separateTypesFile: this.separateSchemasMode,
6538
+ warn: (msg) => {
6539
+ this.warningCollector.add(msg);
6540
+ }
6522
6541
  });
6523
6542
  }
6524
6543
  /**
@@ -6527,7 +6546,7 @@ var init_openapi_generator = __esm({
6527
6546
  * @returns The generated TypeScript code as a string
6528
6547
  */
6529
6548
  generateString() {
6530
- var _a;
6549
+ var _a, _b, _c;
6531
6550
  if (!((_a = this.spec.components) == null ? void 0 : _a.schemas)) {
6532
6551
  throw new SpecValidationError("No schemas found in OpenAPI spec", { filePath: this.options.input });
6533
6552
  }
@@ -6544,9 +6563,26 @@ var init_openapi_generator = __esm({
6544
6563
  }
6545
6564
  this.generateQueryParameterSchemas();
6546
6565
  this.generateHeaderParameterSchemas();
6547
- validateFilters(this.filterStats, this.options.operationFilters);
6566
+ validateFilters(this.filterStats, this.options.operationFilters, (msg) => {
6567
+ this.warningCollector.add(msg);
6568
+ });
6548
6569
  const orderedSchemaNames = this.topologicalSort();
6549
- const output = ["// Auto-generated by @cerios/openapi-to-zod", "// Do not edit this file manually", ""];
6570
+ const output = [];
6571
+ const customHeader = generateCustomFileHeader(this.options.fileHeader);
6572
+ if (customHeader) {
6573
+ output.push(customHeader.trimEnd());
6574
+ output.push("");
6575
+ }
6576
+ if (this.options.includeHeader !== false) {
6577
+ output.push(
6578
+ generateFileHeader({
6579
+ packageName: "@cerios/openapi-to-zod",
6580
+ apiTitle: (_b = this.spec.info) == null ? void 0 : _b.title,
6581
+ apiVersion: (_c = this.spec.info) == null ? void 0 : _c.version
6582
+ }).trimEnd()
6583
+ );
6584
+ output.push("");
6585
+ }
6550
6586
  if (this.options.showStats === true) {
6551
6587
  output.push(...this.generateStats());
6552
6588
  output.push("");
@@ -6573,6 +6609,7 @@ var init_openapi_generator = __esm({
6573
6609
  output.push("");
6574
6610
  }
6575
6611
  }
6612
+ this.warningCollector.flush();
6576
6613
  return output.join("\n");
6577
6614
  }
6578
6615
  /**
@@ -6612,6 +6649,7 @@ var init_openapi_generator = __esm({
6612
6649
  writeFileSync(normalizedOutput, output);
6613
6650
  console.log(` \u2713 Generated ${normalizedOutput}`);
6614
6651
  }
6652
+ this.warningCollector.flush();
6615
6653
  }
6616
6654
  /**
6617
6655
  * Generate Zod schemas with explicit type annotations (for outputZodSchemas mode)
@@ -6619,7 +6657,7 @@ var init_openapi_generator = __esm({
6619
6657
  * @returns The generated Zod schemas TypeScript code
6620
6658
  */
6621
6659
  generateSeparateSchemasString() {
6622
- var _a;
6660
+ var _a, _b, _c;
6623
6661
  const schemas = (_a = this.spec.components) == null ? void 0 : _a.schemas;
6624
6662
  if (!schemas) {
6625
6663
  return "";
@@ -6638,9 +6676,24 @@ var init_openapi_generator = __esm({
6638
6676
  }
6639
6677
  this.generateQueryParameterSchemas();
6640
6678
  this.generateHeaderParameterSchemas();
6641
- validateFilters(this.filterStats, this.options.operationFilters);
6679
+ validateFilters(this.filterStats, this.options.operationFilters, (msg) => {
6680
+ this.warningCollector.add(msg);
6681
+ });
6642
6682
  const orderedSchemaNames = this.topologicalSort();
6643
- const output = ["// Auto-generated by @cerios/openapi-to-zod", "// Do not edit this file manually", ""];
6683
+ const output = [];
6684
+ const customHeader = generateCustomFileHeader(this.options.fileHeader);
6685
+ if (customHeader) {
6686
+ output.push(customHeader.trimEnd());
6687
+ output.push("");
6688
+ }
6689
+ output.push(
6690
+ generateFileHeader({
6691
+ packageName: "@cerios/openapi-to-zod",
6692
+ apiTitle: (_b = this.spec.info) == null ? void 0 : _b.title,
6693
+ apiVersion: (_c = this.spec.info) == null ? void 0 : _c.version
6694
+ }).trimEnd()
6695
+ );
6696
+ output.push("");
6644
6697
  if (this.options.showStats === true) {
6645
6698
  output.push(...this.generateStats());
6646
6699
  output.push("");
@@ -6678,8 +6731,8 @@ var init_openapi_generator = __esm({
6678
6731
  * @returns The generated TypeScript types code
6679
6732
  */
6680
6733
  generateTypesString() {
6681
- var _a;
6682
- const tsGenerator = new TypeScriptGenerator({
6734
+ var _a, _b, _c;
6735
+ const internalOptions = {
6683
6736
  input: this.options.input,
6684
6737
  outputTypes: this.options.outputTypes,
6685
6738
  includeDescriptions: this.options.includeDescriptions,
@@ -6690,9 +6743,20 @@ var init_openapi_generator = __esm({
6690
6743
  stripPathPrefix: this.options.stripPathPrefix,
6691
6744
  operationFilters: this.options.operationFilters,
6692
6745
  showStats: this.options.showStats,
6693
- enumFormat: (_a = this.options.enumFormat) != null ? _a : "const-object"
6746
+ enumFormat: (_a = this.options.enumFormat) != null ? _a : "const-object",
6747
+ includeHeader: false,
6748
+ // We add our own header for consistent branding
6749
+ showWarnings: false
6750
+ // We handle warnings ourselves
6751
+ };
6752
+ const tsGenerator = new TypeScriptGenerator(internalOptions);
6753
+ const customHeader = generateCustomFileHeader(this.options.fileHeader);
6754
+ const header = generateFileHeader({
6755
+ packageName: "@cerios/openapi-to-zod",
6756
+ apiTitle: (_b = this.spec.info) == null ? void 0 : _b.title,
6757
+ apiVersion: (_c = this.spec.info) == null ? void 0 : _c.version
6694
6758
  });
6695
- return tsGenerator.generateString();
6759
+ return customHeader + header + tsGenerator.generateString();
6696
6760
  }
6697
6761
  /**
6698
6762
  * Add explicit type annotation to a schema declaration
@@ -7011,14 +7075,16 @@ ${typeCode}`;
7011
7075
  stripSchemaPrefix: this.options.stripSchemaPrefix,
7012
7076
  dateTimeValidation: this.dateTimeValidation,
7013
7077
  patternCache: this.patternCache,
7014
- separateTypesFile: this.separateSchemasMode
7078
+ separateTypesFile: this.separateSchemasMode,
7079
+ warn: (msg) => {
7080
+ this.warningCollector.add(msg);
7081
+ }
7015
7082
  });
7016
7083
  this.propertyGenerator.setCircularDependencies(this.circularDependencies);
7017
7084
  this.propertyGenerator.clearAllOfConflicts();
7018
7085
  const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, true);
7019
7086
  const allOfConflicts = this.propertyGenerator.getAllOfConflicts();
7020
7087
  if (allOfConflicts.length > 0) {
7021
- this.allOfConflictCount += allOfConflicts.length;
7022
7088
  const conflictWarning = this.generateConflictJSDoc(allOfConflicts);
7023
7089
  if (jsdoc) {
7024
7090
  jsdoc = jsdoc.replace(/ \*\/\n$/, `
@@ -7382,8 +7448,7 @@ ${propsCode}
7382
7448
  `// Total schemas: ${stats.totalSchemas}`,
7383
7449
  `// Circular references: ${stats.withCircularRefs}`,
7384
7450
  `// Discriminated unions: ${stats.withDiscriminators}`,
7385
- `// With constraints: ${stats.withConstraints}`,
7386
- `// AllOf conflicts: ${this.allOfConflictCount}`
7451
+ `// With constraints: ${stats.withConstraints}`
7387
7452
  ];
7388
7453
  if (this.options.operationFilters && this.filterStats.totalOperations > 0) {
7389
7454
  output.push("//");
@@ -7556,6 +7621,7 @@ function mergeConfigWithDefaults(config) {
7556
7621
  showStats: defaults.showStats,
7557
7622
  customDateTimeFormatRegex: defaults.customDateTimeFormatRegex,
7558
7623
  enumFormat: defaults.enumFormat,
7624
+ fileHeader: defaults.fileHeader,
7559
7625
  // Override with spec-specific values
7560
7626
  ...specWithoutDeprecatedOutput,
7561
7627
  outputTypes: resolvedOutputTypes