@cerios/openapi-to-zod 1.3.0 → 1.3.2

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
@@ -5152,12 +5152,12 @@ function toCamelCase(str, options) {
5152
5152
  name = words[0].charAt(0).toLowerCase() + words[0].slice(1) + words.slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
5153
5153
  }
5154
5154
  if (options == null ? void 0 : options.prefix) {
5155
- const prefix = options.prefix.toLowerCase();
5155
+ const prefix = options.prefix.charAt(0).toLowerCase() + options.prefix.slice(1);
5156
5156
  name = prefix + name.charAt(0).toUpperCase() + name.slice(1);
5157
5157
  }
5158
5158
  if (options == null ? void 0 : options.suffix) {
5159
- const suffix = options.suffix;
5160
- name = name + suffix.charAt(0).toUpperCase() + suffix.slice(1).toLowerCase();
5159
+ const suffix = options.suffix.charAt(0).toUpperCase() + options.suffix.slice(1);
5160
+ name = name + suffix;
5161
5161
  }
5162
5162
  return name;
5163
5163
  }
@@ -5506,7 +5506,7 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5506
5506
  );
5507
5507
  }
5508
5508
  if (schemas.length === 1) {
5509
- let singleSchema = context.generatePropertySchema(schemas[0], currentSchema);
5509
+ let singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
5510
5510
  if ((options == null ? void 0 : options.passthrough) && !singleSchema.includes(".catchall(")) {
5511
5511
  singleSchema = `${singleSchema}.catchall(z.unknown())`;
5512
5512
  }
@@ -5522,7 +5522,7 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5522
5522
  console.warn(
5523
5523
  `[openapi-to-zod] Warning: Discriminator "${discriminator}" is not required in schemas: ${discriminatorCheck.invalidSchemas.join(", ")}. Falling back to z.union() instead of z.discriminatedUnion().`
5524
5524
  );
5525
- let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
5525
+ let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5526
5526
  if (options == null ? void 0 : options.passthrough) {
5527
5527
  schemaStrings3 = schemaStrings3.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
5528
5528
  }
@@ -5530,14 +5530,14 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5530
5530
  const union3 = `z.union([${schemaStrings3.join(", ")}]).describe("${fallbackDescription}")`;
5531
5531
  return wrapNullable(union3, isNullable2);
5532
5532
  }
5533
- let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
5533
+ let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5534
5534
  if (options == null ? void 0 : options.passthrough) {
5535
5535
  schemaStrings2 = schemaStrings2.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
5536
5536
  }
5537
5537
  const union2 = `z.discriminatedUnion("${discriminator}", [${schemaStrings2.join(", ")}])`;
5538
5538
  return wrapNullable(union2, isNullable2);
5539
5539
  }
5540
- let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema));
5540
+ let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5541
5541
  if (options == null ? void 0 : options.passthrough) {
5542
5542
  schemaStrings = schemaStrings.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
5543
5543
  }
@@ -5599,7 +5599,7 @@ function detectConflictingProperties(schemas, context) {
5599
5599
  }
5600
5600
  function generateAllOf(schemas, isNullable2, context, currentSchema) {
5601
5601
  if (schemas.length === 1) {
5602
- const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false);
5602
+ const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
5603
5603
  return wrapNullable(singleSchema, isNullable2);
5604
5604
  }
5605
5605
  const conflicts = detectConflictingProperties(schemas, context);
@@ -5613,23 +5613,23 @@ function generateAllOf(schemas, isNullable2, context, currentSchema) {
5613
5613
  const allObjects = schemas.every((s) => s.type === "object" || s.properties || s.$ref || s.allOf);
5614
5614
  let result;
5615
5615
  if (allObjects) {
5616
- let merged = context.generatePropertySchema(schemas[0], currentSchema, false);
5616
+ let merged = context.generatePropertySchema(schemas[0], currentSchema, false, true);
5617
5617
  for (let i = 1; i < schemas.length; i++) {
5618
5618
  const schema = schemas[i];
5619
5619
  if (schema.$ref) {
5620
- const refSchema = context.generatePropertySchema(schema, currentSchema, false);
5620
+ const refSchema = context.generatePropertySchema(schema, currentSchema, false, true);
5621
5621
  merged = `${merged}.extend(${refSchema}.shape)`;
5622
5622
  } else if (context.generateInlineObjectShape && (schema.properties || schema.type === "object")) {
5623
5623
  const inlineShape = context.generateInlineObjectShape(schema, currentSchema);
5624
5624
  merged = `${merged}.extend(${inlineShape})`;
5625
5625
  } else {
5626
- const schemaString = context.generatePropertySchema(schema, currentSchema, false);
5626
+ const schemaString = context.generatePropertySchema(schema, currentSchema, false, true);
5627
5627
  merged = `${merged}.extend(${schemaString}.shape)`;
5628
5628
  }
5629
5629
  }
5630
5630
  result = merged;
5631
5631
  } else {
5632
- const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false));
5632
+ const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5633
5633
  let merged = schemaStrings[0];
5634
5634
  for (let i = 1; i < schemaStrings.length; i++) {
5635
5635
  merged = `${merged}.and(${schemaStrings[i]})`;
@@ -6420,12 +6420,21 @@ var _PropertyGenerator = class _PropertyGenerator {
6420
6420
  }
6421
6421
  /**
6422
6422
  * Generate Zod schema for a property
6423
+ * @param schema - The OpenAPI schema to generate
6424
+ * @param currentSchema - The name of the current schema being processed (for circular ref detection)
6425
+ * @param isTopLevel - Whether this is a top-level schema definition
6426
+ * @param suppressDefaultNullable - When true, don't apply defaultNullable (used when outer schema has explicit nullable: false)
6423
6427
  */
6424
- generatePropertySchema(schema, currentSchema, isTopLevel = false) {
6428
+ generatePropertySchema(schema, currentSchema, isTopLevel = false, suppressDefaultNullable = false) {
6425
6429
  var _a, _b, _c, _d, _e;
6426
6430
  const isCacheable = !schema.$ref && !schema.allOf && !schema.oneOf && !schema.anyOf && !currentSchema;
6427
6431
  if (isCacheable) {
6428
- const cacheKey = JSON.stringify({ schema, type: this.context.schemaType, mode: this.context.mode });
6432
+ const cacheKey = JSON.stringify({
6433
+ schema,
6434
+ type: this.context.schemaType,
6435
+ mode: this.context.mode,
6436
+ suppressDefaultNullable
6437
+ });
6429
6438
  const cached = this.schemaCache.get(cacheKey);
6430
6439
  if (cached) {
6431
6440
  return cached;
@@ -6434,10 +6443,9 @@ var _PropertyGenerator = class _PropertyGenerator {
6434
6443
  if ((this.context.schemaType === "request" || this.context.schemaType === "response") && schema.properties) {
6435
6444
  schema = this.filterNestedProperties(schema);
6436
6445
  }
6437
- const isSchemaRef = !!schema.$ref;
6438
6446
  const isEnum = !!schema.enum;
6439
6447
  const isConst = schema.const !== void 0;
6440
- const shouldApplyDefaultNullable = !isTopLevel && !isSchemaRef && !isEnum && !isConst;
6448
+ const shouldApplyDefaultNullable = !isTopLevel && !isEnum && !isConst && !suppressDefaultNullable;
6441
6449
  const effectiveDefaultNullable = shouldApplyDefaultNullable ? this.context.defaultNullable : false;
6442
6450
  const nullable = isNullable(schema, effectiveDefaultNullable);
6443
6451
  if (hasMultipleTypes(schema)) {
@@ -6488,9 +6496,10 @@ var _PropertyGenerator = class _PropertyGenerator {
6488
6496
  return wrapNullable(zodUnion, nullable);
6489
6497
  }
6490
6498
  if (schema.allOf) {
6499
+ const compositionNullable = isNullable(schema, false);
6491
6500
  let composition = generateAllOf(
6492
6501
  schema.allOf,
6493
- nullable,
6502
+ compositionNullable,
6494
6503
  {
6495
6504
  generatePropertySchema: this.generatePropertySchema.bind(this),
6496
6505
  generateInlineObjectShape: this.generateInlineObjectShape.bind(this),
@@ -6504,11 +6513,12 @@ var _PropertyGenerator = class _PropertyGenerator {
6504
6513
  return composition;
6505
6514
  }
6506
6515
  if (schema.oneOf) {
6516
+ const compositionNullable = isNullable(schema, false);
6507
6517
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
6508
6518
  let composition = generateUnion(
6509
6519
  schema.oneOf,
6510
6520
  (_b = schema.discriminator) == null ? void 0 : _b.propertyName,
6511
- nullable,
6521
+ compositionNullable,
6512
6522
  {
6513
6523
  generatePropertySchema: this.generatePropertySchema.bind(this),
6514
6524
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -6526,11 +6536,12 @@ var _PropertyGenerator = class _PropertyGenerator {
6526
6536
  return composition;
6527
6537
  }
6528
6538
  if (schema.anyOf) {
6539
+ const compositionNullable = isNullable(schema, false);
6529
6540
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
6530
6541
  let composition = generateUnion(
6531
6542
  schema.anyOf,
6532
6543
  (_d = schema.discriminator) == null ? void 0 : _d.propertyName,
6533
- nullable,
6544
+ compositionNullable,
6534
6545
  {
6535
6546
  generatePropertySchema: this.generatePropertySchema.bind(this),
6536
6547
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -7032,12 +7043,6 @@ var OpenApiGenerator = class {
7032
7043
  * Generate the complete output file
7033
7044
  */
7034
7045
  generate() {
7035
- if (!this.options.output) {
7036
- throw new ConfigurationError(
7037
- "Output path is required when calling generate(). Either provide an 'output' option or use generateString() to get the result as a string.",
7038
- { hasOutput: false }
7039
- );
7040
- }
7041
7046
  const output = this.generateString();
7042
7047
  const normalizedOutput = (0, import_node_path.normalize)(this.options.output);
7043
7048
  this.ensureDirectoryExists(normalizedOutput);
@@ -7765,7 +7770,8 @@ var RequestResponseOptionsSchema = import_zod.z.strictObject({
7765
7770
  mode: import_zod.z.enum(["strict", "normal", "loose"]).optional(),
7766
7771
  useDescribe: import_zod.z.boolean().optional(),
7767
7772
  includeDescriptions: import_zod.z.boolean().optional(),
7768
- defaultNullable: import_zod.z.boolean().optional()
7773
+ defaultNullable: import_zod.z.boolean().optional(),
7774
+ emptyObjectBehavior: import_zod.z.enum(["strict", "loose", "record"]).optional()
7769
7775
  });
7770
7776
  var OperationFiltersSchema = import_zod.z.strictObject({
7771
7777
  includeTags: import_zod.z.array(import_zod.z.string()).optional(),
@@ -7849,6 +7855,7 @@ var OpenApiGeneratorOptionsSchema = import_zod2.z.strictObject({
7849
7855
  includeDescriptions: import_zod2.z.boolean().optional(),
7850
7856
  useDescribe: import_zod2.z.boolean().optional(),
7851
7857
  defaultNullable: import_zod2.z.boolean().optional(),
7858
+ emptyObjectBehavior: import_zod2.z.enum(["strict", "loose", "record"]).optional(),
7852
7859
  schemaType: import_zod2.z.enum(["all", "request", "response"]).optional(),
7853
7860
  prefix: import_zod2.z.string().optional(),
7854
7861
  suffix: import_zod2.z.string().optional(),
@@ -7881,6 +7888,7 @@ var ConfigFileSchema = import_zod2.z.strictObject({
7881
7888
  includeDescriptions: import_zod2.z.boolean().optional(),
7882
7889
  useDescribe: import_zod2.z.boolean().optional(),
7883
7890
  defaultNullable: import_zod2.z.boolean().optional(),
7891
+ emptyObjectBehavior: import_zod2.z.enum(["strict", "loose", "record"]).optional(),
7884
7892
  schemaType: import_zod2.z.enum(["all", "request", "response"]).optional(),
7885
7893
  prefix: import_zod2.z.string().optional(),
7886
7894
  suffix: import_zod2.z.string().optional(),
@@ -7954,6 +7962,7 @@ function mergeConfigWithDefaults(config) {
7954
7962
  includeDescriptions: defaults.includeDescriptions,
7955
7963
  useDescribe: defaults.useDescribe,
7956
7964
  defaultNullable: defaults.defaultNullable,
7965
+ emptyObjectBehavior: defaults.emptyObjectBehavior,
7957
7966
  schemaType: defaults.schemaType,
7958
7967
  prefix: defaults.prefix,
7959
7968
  suffix: defaults.suffix,