@cerios/openapi-to-zod 1.2.0 → 1.3.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
@@ -5514,12 +5514,56 @@ var init_array_validator = __esm({
5514
5514
  });
5515
5515
 
5516
5516
  // src/validators/composition-validator.ts
5517
+ function isDiscriminatorRequired(schemas, discriminator, context) {
5518
+ const invalidSchemas = [];
5519
+ for (const schema of schemas) {
5520
+ const resolved = resolveSchema(schema, context);
5521
+ const required = resolved.required || [];
5522
+ if (!required.includes(discriminator)) {
5523
+ const schemaName = schema.$ref ? schema.$ref.split("/").pop() || "inline" : "inline";
5524
+ invalidSchemas.push(schemaName);
5525
+ }
5526
+ }
5527
+ return {
5528
+ valid: invalidSchemas.length === 0,
5529
+ invalidSchemas
5530
+ };
5531
+ }
5517
5532
  function generateUnion(schemas, discriminator, isNullable2, context, options, currentSchema) {
5533
+ if (schemas.length === 0) {
5534
+ console.warn(
5535
+ "[openapi-to-zod] Warning: Empty oneOf/anyOf array encountered. This is likely a malformed OpenAPI spec. Generating z.never() as fallback."
5536
+ );
5537
+ return wrapNullable(
5538
+ 'z.never().describe("Empty oneOf/anyOf in OpenAPI spec - no valid schema defined")',
5539
+ isNullable2
5540
+ );
5541
+ }
5542
+ if (schemas.length === 1) {
5543
+ let singleSchema = context.generatePropertySchema(schemas[0], currentSchema);
5544
+ if ((options == null ? void 0 : options.passthrough) && !singleSchema.includes(".catchall(")) {
5545
+ singleSchema = `${singleSchema}.catchall(z.unknown())`;
5546
+ }
5547
+ return wrapNullable(singleSchema, isNullable2);
5548
+ }
5518
5549
  if (discriminator) {
5519
5550
  let resolvedSchemas = schemas;
5520
5551
  if ((options == null ? void 0 : options.discriminatorMapping) && context.resolveDiscriminatorMapping) {
5521
5552
  resolvedSchemas = context.resolveDiscriminatorMapping(options.discriminatorMapping, schemas);
5522
5553
  }
5554
+ const discriminatorCheck = isDiscriminatorRequired(resolvedSchemas, discriminator, context);
5555
+ if (!discriminatorCheck.valid) {
5556
+ console.warn(
5557
+ `[openapi-to-zod] Warning: Discriminator "${discriminator}" is not required in schemas: ${discriminatorCheck.invalidSchemas.join(", ")}. Falling back to z.union() instead of z.discriminatedUnion().`
5558
+ );
5559
+ let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
5560
+ if (options == null ? void 0 : options.passthrough) {
5561
+ schemaStrings3 = schemaStrings3.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
5562
+ }
5563
+ const fallbackDescription = `Discriminator "${discriminator}" is optional in some schemas (${discriminatorCheck.invalidSchemas.join(", ")}), using z.union() instead of z.discriminatedUnion()`;
5564
+ const union3 = `z.union([${schemaStrings3.join(", ")}]).describe("${fallbackDescription}")`;
5565
+ return wrapNullable(union3, isNullable2);
5566
+ }
5523
5567
  let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
5524
5568
  if (options == null ? void 0 : options.passthrough) {
5525
5569
  schemaStrings2 = schemaStrings2.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
@@ -5534,25 +5578,102 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5534
5578
  const union = `z.union([${schemaStrings.join(", ")}])`;
5535
5579
  return wrapNullable(union, isNullable2);
5536
5580
  }
5581
+ function resolveSchema(schema, context) {
5582
+ if (schema.$ref && context.resolveSchemaRef) {
5583
+ const resolved = context.resolveSchemaRef(schema.$ref);
5584
+ if (resolved) {
5585
+ return resolved;
5586
+ }
5587
+ }
5588
+ return schema;
5589
+ }
5590
+ function collectProperties(schema, context) {
5591
+ const resolved = resolveSchema(schema, context);
5592
+ const props = /* @__PURE__ */ new Map();
5593
+ const sourceName = schema.$ref ? schema.$ref.split("/").pop() || "unknown" : "inline";
5594
+ if (resolved.properties) {
5595
+ for (const [key, value] of Object.entries(resolved.properties)) {
5596
+ props.set(key, { schema: value, source: sourceName });
5597
+ }
5598
+ }
5599
+ if (resolved.allOf) {
5600
+ for (const subSchema of resolved.allOf) {
5601
+ const subProps = collectProperties(subSchema, context);
5602
+ for (const [key, value] of subProps) {
5603
+ if (!props.has(key)) {
5604
+ props.set(key, value);
5605
+ }
5606
+ }
5607
+ }
5608
+ }
5609
+ return props;
5610
+ }
5611
+ function schemasMatch(a, b) {
5612
+ return JSON.stringify(a) === JSON.stringify(b);
5613
+ }
5614
+ function detectConflictingProperties(schemas, context) {
5615
+ const conflicts = [];
5616
+ const propertyMap = /* @__PURE__ */ new Map();
5617
+ for (const schema of schemas) {
5618
+ const schemaProps = collectProperties(schema, context);
5619
+ for (const [propName, propInfo] of schemaProps) {
5620
+ const existing = propertyMap.get(propName);
5621
+ if (existing) {
5622
+ if (!schemasMatch(existing.schema, propInfo.schema)) {
5623
+ conflicts.push(
5624
+ `Property "${propName}" has conflicting definitions in ${existing.source} and ${propInfo.source}`
5625
+ );
5626
+ }
5627
+ } else {
5628
+ propertyMap.set(propName, propInfo);
5629
+ }
5630
+ }
5631
+ }
5632
+ return conflicts;
5633
+ }
5537
5634
  function generateAllOf(schemas, isNullable2, context, currentSchema) {
5538
5635
  if (schemas.length === 1) {
5539
5636
  const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false);
5540
5637
  return wrapNullable(singleSchema, isNullable2);
5541
5638
  }
5639
+ const conflicts = detectConflictingProperties(schemas, context);
5640
+ let conflictDescription = "";
5641
+ if (conflicts.length > 0) {
5642
+ for (const conflict of conflicts) {
5643
+ console.warn(`[openapi-to-zod] Warning: allOf composition conflict - ${conflict}`);
5644
+ }
5645
+ conflictDescription = `allOf property conflicts detected: ${conflicts.join("; ")}`;
5646
+ }
5542
5647
  const allObjects = schemas.every((s) => s.type === "object" || s.properties || s.$ref || s.allOf);
5543
- const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false));
5648
+ let result;
5544
5649
  if (allObjects) {
5545
- let merged2 = schemaStrings[0];
5650
+ let merged = context.generatePropertySchema(schemas[0], currentSchema, false);
5651
+ for (let i = 1; i < schemas.length; i++) {
5652
+ const schema = schemas[i];
5653
+ if (schema.$ref) {
5654
+ const refSchema = context.generatePropertySchema(schema, currentSchema, false);
5655
+ merged = `${merged}.extend(${refSchema}.shape)`;
5656
+ } else if (context.generateInlineObjectShape && (schema.properties || schema.type === "object")) {
5657
+ const inlineShape = context.generateInlineObjectShape(schema, currentSchema);
5658
+ merged = `${merged}.extend(${inlineShape})`;
5659
+ } else {
5660
+ const schemaString = context.generatePropertySchema(schema, currentSchema, false);
5661
+ merged = `${merged}.extend(${schemaString}.shape)`;
5662
+ }
5663
+ }
5664
+ result = merged;
5665
+ } else {
5666
+ const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false));
5667
+ let merged = schemaStrings[0];
5546
5668
  for (let i = 1; i < schemaStrings.length; i++) {
5547
- merged2 = `${merged2}.merge(${schemaStrings[i]})`;
5669
+ merged = `${merged}.and(${schemaStrings[i]})`;
5548
5670
  }
5549
- return wrapNullable(merged2, isNullable2);
5671
+ result = merged;
5550
5672
  }
5551
- let merged = schemaStrings[0];
5552
- for (let i = 1; i < schemaStrings.length; i++) {
5553
- merged = `${merged}.and(${schemaStrings[i]})`;
5673
+ if (conflictDescription) {
5674
+ result = `${result}.describe("${conflictDescription}")`;
5554
5675
  }
5555
- return wrapNullable(merged, isNullable2);
5676
+ return wrapNullable(result, isNullable2);
5556
5677
  }
5557
5678
  var init_composition_validator = __esm({
5558
5679
  "src/validators/composition-validator.ts"() {
@@ -6279,6 +6400,15 @@ var init_property_generator = __esm({
6279
6400
  }
6280
6401
  return mappedSchemas;
6281
6402
  }
6403
+ /**
6404
+ * Resolve a $ref string to the actual schema
6405
+ */
6406
+ resolveSchemaRef(ref) {
6407
+ var _a, _b;
6408
+ const schemaName = ref.split("/").pop();
6409
+ if (!schemaName) return void 0;
6410
+ return (_b = (_a = this.context.spec.components) == null ? void 0 : _a.schemas) == null ? void 0 : _b[schemaName];
6411
+ }
6282
6412
  /**
6283
6413
  * Resolve a schema name through any aliases to get the actual schema name
6284
6414
  * If the schema is an alias (allOf with single $ref), return the target name
@@ -6356,7 +6486,7 @@ var init_property_generator = __esm({
6356
6486
  let schemaWithCatchall = baseSchema;
6357
6487
  if (baseSchema.includes(".union([") || baseSchema.includes(".discriminatedUnion(")) {
6358
6488
  schemaWithCatchall = baseSchema;
6359
- } else if (baseSchema.includes(".merge(")) {
6489
+ } else if (baseSchema.includes(".extend(")) {
6360
6490
  schemaWithCatchall = `${baseSchema}.catchall(z.unknown())`;
6361
6491
  }
6362
6492
  if (schema.unevaluatedProperties === false) {
@@ -6383,7 +6513,11 @@ var init_property_generator = __esm({
6383
6513
  if ((this.context.schemaType === "request" || this.context.schemaType === "response") && schema.properties) {
6384
6514
  schema = this.filterNestedProperties(schema);
6385
6515
  }
6386
- const effectiveDefaultNullable = isTopLevel ? false : this.context.defaultNullable;
6516
+ const isSchemaRef = !!schema.$ref;
6517
+ const isEnum = !!schema.enum;
6518
+ const isConst = schema.const !== void 0;
6519
+ const shouldApplyDefaultNullable = !isTopLevel && !isSchemaRef && !isEnum && !isConst;
6520
+ const effectiveDefaultNullable = shouldApplyDefaultNullable ? this.context.defaultNullable : false;
6387
6521
  const nullable = isNullable(schema, effectiveDefaultNullable);
6388
6522
  if (hasMultipleTypes(schema)) {
6389
6523
  const union = this.generateMultiTypeUnion(schema, currentSchema);
@@ -6436,7 +6570,11 @@ var init_property_generator = __esm({
6436
6570
  let composition = generateAllOf(
6437
6571
  schema.allOf,
6438
6572
  nullable,
6439
- { generatePropertySchema: this.generatePropertySchema.bind(this) },
6573
+ {
6574
+ generatePropertySchema: this.generatePropertySchema.bind(this),
6575
+ generateInlineObjectShape: this.generateInlineObjectShape.bind(this),
6576
+ resolveSchemaRef: this.resolveSchemaRef.bind(this)
6577
+ },
6440
6578
  currentSchema
6441
6579
  );
6442
6580
  if (schema.unevaluatedProperties !== void 0) {
@@ -6452,7 +6590,8 @@ var init_property_generator = __esm({
6452
6590
  nullable,
6453
6591
  {
6454
6592
  generatePropertySchema: this.generatePropertySchema.bind(this),
6455
- resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this)
6593
+ resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
6594
+ resolveSchemaRef: this.resolveSchemaRef.bind(this)
6456
6595
  },
6457
6596
  {
6458
6597
  passthrough: needsPassthrough,
@@ -6473,7 +6612,8 @@ var init_property_generator = __esm({
6473
6612
  nullable,
6474
6613
  {
6475
6614
  generatePropertySchema: this.generatePropertySchema.bind(this),
6476
- resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this)
6615
+ resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
6616
+ resolveSchemaRef: this.resolveSchemaRef.bind(this)
6477
6617
  },
6478
6618
  {
6479
6619
  passthrough: needsPassthrough,
@@ -6536,7 +6676,17 @@ var init_property_generator = __esm({
6536
6676
  );
6537
6677
  validation = addDescription(validation, schema.description, this.context.useDescribe);
6538
6678
  } else {
6539
- validation = "z.record(z.string(), z.unknown())";
6679
+ switch (this.context.emptyObjectBehavior) {
6680
+ case "strict":
6681
+ validation = "z.strictObject({})";
6682
+ break;
6683
+ case "loose":
6684
+ validation = "z.looseObject({})";
6685
+ break;
6686
+ default:
6687
+ validation = "z.record(z.string(), z.unknown())";
6688
+ break;
6689
+ }
6540
6690
  validation = addDescription(validation, schema.description, this.context.useDescribe);
6541
6691
  }
6542
6692
  break;
@@ -6551,6 +6701,44 @@ var init_property_generator = __esm({
6551
6701
  }
6552
6702
  return result;
6553
6703
  }
6704
+ /**
6705
+ * Generate inline object shape for use with .extend()
6706
+ * Returns just the shape object literal: { prop1: z.string(), prop2: z.number() }
6707
+ *
6708
+ * This method is specifically for allOf compositions where we need to pass
6709
+ * the shape directly to .extend() instead of using z.object({...}).shape.
6710
+ * This avoids the .nullable().shape bug when inline objects have nullable: true.
6711
+ *
6712
+ * According to Zod docs (https://zod.dev/api?id=extend):
6713
+ * - .extend() accepts an object of shape definitions
6714
+ * - e.g., baseSchema.extend({ prop: z.string() })
6715
+ */
6716
+ generateInlineObjectShape(schema, currentSchema) {
6717
+ const required = new Set(schema.required || []);
6718
+ const properties = [];
6719
+ if (schema.properties) {
6720
+ for (const [propName, propSchema] of Object.entries(schema.properties)) {
6721
+ if (!this.shouldIncludeProperty(propSchema)) {
6722
+ continue;
6723
+ }
6724
+ const isRequired = required.has(propName);
6725
+ const zodSchema = this.generatePropertySchema(propSchema, currentSchema);
6726
+ const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
6727
+ const quotedPropName = validIdentifier.test(propName) ? propName : `"${propName}"`;
6728
+ let propertyDef = `${quotedPropName}: ${zodSchema}`;
6729
+ if (!isRequired) {
6730
+ propertyDef += ".optional()";
6731
+ }
6732
+ properties.push(propertyDef);
6733
+ }
6734
+ }
6735
+ if (properties.length === 0) {
6736
+ return "{}";
6737
+ }
6738
+ return `{
6739
+ ${properties.map((p) => ` ${p}`).join(",\n")}
6740
+ }`;
6741
+ }
6554
6742
  };
6555
6743
  // Performance optimization: Lookup table for faster inclusion checks
6556
6744
  _PropertyGenerator.INCLUSION_RULES = {
@@ -6702,6 +6890,65 @@ var init_operation_filters = __esm({
6702
6890
  }
6703
6891
  });
6704
6892
 
6893
+ // src/utils/ref-resolver.ts
6894
+ function resolveRef2(obj, spec, maxDepth = 10) {
6895
+ var _a, _b, _c, _d;
6896
+ if (!obj || typeof obj !== "object" || maxDepth <= 0) return obj;
6897
+ if (!obj.$ref) return obj;
6898
+ const ref = obj.$ref;
6899
+ let resolved = null;
6900
+ const paramMatch = ref.match(/^#\/components\/parameters\/(.+)$/);
6901
+ const requestBodyMatch = ref.match(/^#\/components\/requestBodies\/(.+)$/);
6902
+ const responseMatch = ref.match(/^#\/components\/responses\/(.+)$/);
6903
+ const schemaMatch = ref.match(/^#\/components\/schemas\/(.+)$/);
6904
+ if (paramMatch && ((_a = spec.components) == null ? void 0 : _a.parameters)) {
6905
+ const name = paramMatch[1];
6906
+ resolved = spec.components.parameters[name];
6907
+ } else if (requestBodyMatch && ((_b = spec.components) == null ? void 0 : _b.requestBodies)) {
6908
+ const name = requestBodyMatch[1];
6909
+ resolved = spec.components.requestBodies[name];
6910
+ } else if (responseMatch && ((_c = spec.components) == null ? void 0 : _c.responses)) {
6911
+ const name = responseMatch[1];
6912
+ resolved = spec.components.responses[name];
6913
+ } else if (schemaMatch && ((_d = spec.components) == null ? void 0 : _d.schemas)) {
6914
+ const name = schemaMatch[1];
6915
+ resolved = spec.components.schemas[name];
6916
+ }
6917
+ if (resolved) {
6918
+ if (resolved.$ref) {
6919
+ return resolveRef2(resolved, spec, maxDepth - 1);
6920
+ }
6921
+ return resolved;
6922
+ }
6923
+ return obj;
6924
+ }
6925
+ function resolveParameterRef(param, spec) {
6926
+ return resolveRef2(param, spec);
6927
+ }
6928
+ function mergeParameters(pathParams, operationParams, spec) {
6929
+ const resolvedPathParams = (pathParams || []).map((p) => resolveParameterRef(p, spec));
6930
+ const resolvedOperationParams = (operationParams || []).map((p) => resolveParameterRef(p, spec));
6931
+ const merged = [...resolvedPathParams];
6932
+ for (const opParam of resolvedOperationParams) {
6933
+ if (!opParam || typeof opParam !== "object") continue;
6934
+ const existingIndex = merged.findIndex(
6935
+ (p) => p && typeof p === "object" && p.name === opParam.name && p.in === opParam.in
6936
+ );
6937
+ if (existingIndex >= 0) {
6938
+ merged[existingIndex] = opParam;
6939
+ } else {
6940
+ merged.push(opParam);
6941
+ }
6942
+ }
6943
+ return merged;
6944
+ }
6945
+ var init_ref_resolver = __esm({
6946
+ "src/utils/ref-resolver.ts"() {
6947
+ "use strict";
6948
+ init_esm_shims();
6949
+ }
6950
+ });
6951
+
6705
6952
  // src/openapi-generator.ts
6706
6953
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
6707
6954
  import { dirname, normalize } from "path";
@@ -6719,6 +6966,7 @@ var init_openapi_generator = __esm({
6719
6966
  init_name_utils();
6720
6967
  init_operation_filters();
6721
6968
  init_pattern_utils();
6969
+ init_ref_resolver();
6722
6970
  init_string_validator();
6723
6971
  OpenApiGenerator = class {
6724
6972
  constructor(options) {
@@ -6728,7 +6976,7 @@ var init_openapi_generator = __esm({
6728
6976
  this.schemaUsageMap = /* @__PURE__ */ new Map();
6729
6977
  this.needsZodImport = true;
6730
6978
  this.filterStats = createFilterStatistics();
6731
- var _a, _b, _c, _d, _e, _f, _g;
6979
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
6732
6980
  if (!options.input) {
6733
6981
  throw new ConfigurationError("Input path is required", { providedOptions: options });
6734
6982
  }
@@ -6739,18 +6987,19 @@ var init_openapi_generator = __esm({
6739
6987
  includeDescriptions: (_a = options.includeDescriptions) != null ? _a : true,
6740
6988
  useDescribe: (_b = options.useDescribe) != null ? _b : false,
6741
6989
  defaultNullable: (_c = options.defaultNullable) != null ? _c : false,
6990
+ emptyObjectBehavior: (_d = options.emptyObjectBehavior) != null ? _d : "loose",
6742
6991
  schemaType: options.schemaType || "all",
6743
6992
  prefix: options.prefix,
6744
6993
  suffix: options.suffix,
6745
6994
  stripSchemaPrefix: options.stripSchemaPrefix,
6746
6995
  stripPathPrefix: options.stripPathPrefix,
6747
- showStats: (_d = options.showStats) != null ? _d : true,
6996
+ showStats: (_e = options.showStats) != null ? _e : true,
6748
6997
  request: options.request,
6749
6998
  response: options.response,
6750
6999
  operationFilters: options.operationFilters,
6751
7000
  ignoreHeaders: options.ignoreHeaders,
6752
- cacheSize: (_e = options.cacheSize) != null ? _e : 1e3,
6753
- batchSize: (_f = options.batchSize) != null ? _f : 10,
7001
+ cacheSize: (_f = options.cacheSize) != null ? _f : 1e3,
7002
+ batchSize: (_g = options.batchSize) != null ? _g : 10,
6754
7003
  customDateTimeFormatRegex: options.customDateTimeFormatRegex
6755
7004
  };
6756
7005
  if (this.options.cacheSize) {
@@ -6821,7 +7070,8 @@ var init_openapi_generator = __esm({
6821
7070
  mode: this.requestOptions.mode,
6822
7071
  includeDescriptions: this.requestOptions.includeDescriptions,
6823
7072
  useDescribe: this.requestOptions.useDescribe,
6824
- defaultNullable: (_g = this.options.defaultNullable) != null ? _g : false,
7073
+ defaultNullable: (_h = this.options.defaultNullable) != null ? _h : false,
7074
+ emptyObjectBehavior: (_i = this.options.emptyObjectBehavior) != null ? _i : "loose",
6825
7075
  namingOptions: {
6826
7076
  prefix: this.options.prefix,
6827
7077
  suffix: this.options.suffix
@@ -7175,7 +7425,7 @@ var init_openapi_generator = __esm({
7175
7425
  * Generate schema for a component
7176
7426
  */
7177
7427
  generateComponentSchema(name, schema) {
7178
- var _a, _b, _c;
7428
+ var _a, _b, _c, _d;
7179
7429
  if (!this.schemaDependencies.has(name)) {
7180
7430
  this.schemaDependencies.set(name, /* @__PURE__ */ new Set());
7181
7431
  }
@@ -7208,6 +7458,7 @@ ${typeCode}`;
7208
7458
  includeDescriptions: resolvedOptions.includeDescriptions,
7209
7459
  useDescribe: resolvedOptions.useDescribe,
7210
7460
  defaultNullable: (_b = this.options.defaultNullable) != null ? _b : false,
7461
+ emptyObjectBehavior: (_c = this.options.emptyObjectBehavior) != null ? _c : "loose",
7211
7462
  namingOptions: {
7212
7463
  prefix: this.options.prefix,
7213
7464
  suffix: this.options.suffix
@@ -7224,7 +7475,7 @@ ${typeCode}`;
7224
7475
  const depMatch = ref.match(/^([a-z][a-zA-Z0-9]*?)Schema$/);
7225
7476
  if (depMatch) {
7226
7477
  const depName = depMatch[1].charAt(0).toUpperCase() + depMatch[1].slice(1);
7227
- (_c = this.schemaDependencies.get(name)) == null ? void 0 : _c.add(depName);
7478
+ (_d = this.schemaDependencies.get(name)) == null ? void 0 : _d.add(depName);
7228
7479
  }
7229
7480
  }
7230
7481
  }
@@ -7248,10 +7499,8 @@ ${typeCode}`;
7248
7499
  if (!shouldIncludeOperation(operation, path2, method, this.options.operationFilters)) {
7249
7500
  continue;
7250
7501
  }
7251
- if (!operation.parameters || !Array.isArray(operation.parameters)) {
7252
- continue;
7253
- }
7254
- const queryParams = operation.parameters.filter(
7502
+ const allParams = mergeParameters(pathItem.parameters, operation.parameters, this.spec);
7503
+ const queryParams = allParams.filter(
7255
7504
  (param) => param && typeof param === "object" && param.in === "query"
7256
7505
  );
7257
7506
  if (queryParams.length === 0) {
@@ -7387,10 +7636,8 @@ ${propsCode}
7387
7636
  if (!shouldIncludeOperation(operation, path2, method, this.options.operationFilters)) {
7388
7637
  continue;
7389
7638
  }
7390
- if (!operation.parameters || !Array.isArray(operation.parameters)) {
7391
- continue;
7392
- }
7393
- const headerParams = operation.parameters.filter(
7639
+ const allParams = mergeParameters(pathItem.parameters, operation.parameters, this.spec);
7640
+ const headerParams = allParams.filter(
7394
7641
  (param) => param && typeof param === "object" && param.in === "header" && !this.shouldIgnoreHeader(param.name)
7395
7642
  );
7396
7643
  if (headerParams.length === 0) {
@@ -7480,13 +7727,23 @@ ${propsCode}
7480
7727
  }
7481
7728
  const type = schema.type;
7482
7729
  if (type === "string") {
7730
+ const formatMap = {
7731
+ email: "z.email()",
7732
+ uri: "z.url()",
7733
+ url: "z.url()",
7734
+ uuid: "z.uuid()"
7735
+ };
7736
+ if (schema.format && formatMap[schema.format]) {
7737
+ let zodType2 = formatMap[schema.format];
7738
+ if (schema.minLength !== void 0) zodType2 = `${zodType2}.min(${schema.minLength})`;
7739
+ if (schema.maxLength !== void 0) zodType2 = `${zodType2}.max(${schema.maxLength})`;
7740
+ if (schema.pattern) zodType2 = `${zodType2}.regex(/${schema.pattern}/)`;
7741
+ return zodType2;
7742
+ }
7483
7743
  let zodType = "z.string()";
7484
7744
  if (schema.minLength !== void 0) zodType = `${zodType}.min(${schema.minLength})`;
7485
7745
  if (schema.maxLength !== void 0) zodType = `${zodType}.max(${schema.maxLength})`;
7486
7746
  if (schema.pattern) zodType = `${zodType}.regex(/${schema.pattern}/)`;
7487
- if (schema.format === "email") zodType = `${zodType}.email()`;
7488
- if (schema.format === "uri" || schema.format === "url") zodType = `${zodType}.url()`;
7489
- if (schema.format === "uuid") zodType = `${zodType}.uuid()`;
7490
7747
  return zodType;
7491
7748
  }
7492
7749
  if (type === "number" || type === "integer") {
@@ -7511,11 +7768,6 @@ ${propsCode}
7511
7768
  }
7512
7769
  return "z.unknown()";
7513
7770
  }
7514
- // REMOVED: generateNativeEnum method - no longer needed as we only generate Zod schemas
7515
- // REMOVED: toEnumKey method - was only used by generateNativeEnum
7516
- // REMOVED: addConstraintsToJSDoc method - was only used for native TypeScript types
7517
- // REMOVED: generateNativeTypeDefinition method - was only used for native TypeScript types
7518
- // REMOVED: generateObjectType method - was only used for native TypeScript types
7519
7771
  /**
7520
7772
  * Topological sort for schema dependencies
7521
7773
  * Returns schemas in the order they should be declared