@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.mjs CHANGED
@@ -5151,12 +5151,12 @@ function toCamelCase(str, options) {
5151
5151
  name = words[0].charAt(0).toLowerCase() + words[0].slice(1) + words.slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
5152
5152
  }
5153
5153
  if (options == null ? void 0 : options.prefix) {
5154
- const prefix = options.prefix.toLowerCase();
5154
+ const prefix = options.prefix.charAt(0).toLowerCase() + options.prefix.slice(1);
5155
5155
  name = prefix + name.charAt(0).toUpperCase() + name.slice(1);
5156
5156
  }
5157
5157
  if (options == null ? void 0 : options.suffix) {
5158
- const suffix = options.suffix;
5159
- name = name + suffix.charAt(0).toUpperCase() + suffix.slice(1).toLowerCase();
5158
+ const suffix = options.suffix.charAt(0).toUpperCase() + options.suffix.slice(1);
5159
+ name = name + suffix;
5160
5160
  }
5161
5161
  return name;
5162
5162
  }
@@ -5540,7 +5540,7 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5540
5540
  );
5541
5541
  }
5542
5542
  if (schemas.length === 1) {
5543
- let singleSchema = context.generatePropertySchema(schemas[0], currentSchema);
5543
+ let singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
5544
5544
  if ((options == null ? void 0 : options.passthrough) && !singleSchema.includes(".catchall(")) {
5545
5545
  singleSchema = `${singleSchema}.catchall(z.unknown())`;
5546
5546
  }
@@ -5556,7 +5556,7 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5556
5556
  console.warn(
5557
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
5558
  );
5559
- let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
5559
+ let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5560
5560
  if (options == null ? void 0 : options.passthrough) {
5561
5561
  schemaStrings3 = schemaStrings3.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
5562
5562
  }
@@ -5564,14 +5564,14 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
5564
5564
  const union3 = `z.union([${schemaStrings3.join(", ")}]).describe("${fallbackDescription}")`;
5565
5565
  return wrapNullable(union3, isNullable2);
5566
5566
  }
5567
- let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
5567
+ let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5568
5568
  if (options == null ? void 0 : options.passthrough) {
5569
5569
  schemaStrings2 = schemaStrings2.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
5570
5570
  }
5571
5571
  const union2 = `z.discriminatedUnion("${discriminator}", [${schemaStrings2.join(", ")}])`;
5572
5572
  return wrapNullable(union2, isNullable2);
5573
5573
  }
5574
- let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema));
5574
+ let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5575
5575
  if (options == null ? void 0 : options.passthrough) {
5576
5576
  schemaStrings = schemaStrings.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
5577
5577
  }
@@ -5633,7 +5633,7 @@ function detectConflictingProperties(schemas, context) {
5633
5633
  }
5634
5634
  function generateAllOf(schemas, isNullable2, context, currentSchema) {
5635
5635
  if (schemas.length === 1) {
5636
- const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false);
5636
+ const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
5637
5637
  return wrapNullable(singleSchema, isNullable2);
5638
5638
  }
5639
5639
  const conflicts = detectConflictingProperties(schemas, context);
@@ -5647,23 +5647,23 @@ function generateAllOf(schemas, isNullable2, context, currentSchema) {
5647
5647
  const allObjects = schemas.every((s) => s.type === "object" || s.properties || s.$ref || s.allOf);
5648
5648
  let result;
5649
5649
  if (allObjects) {
5650
- let merged = context.generatePropertySchema(schemas[0], currentSchema, false);
5650
+ let merged = context.generatePropertySchema(schemas[0], currentSchema, false, true);
5651
5651
  for (let i = 1; i < schemas.length; i++) {
5652
5652
  const schema = schemas[i];
5653
5653
  if (schema.$ref) {
5654
- const refSchema = context.generatePropertySchema(schema, currentSchema, false);
5654
+ const refSchema = context.generatePropertySchema(schema, currentSchema, false, true);
5655
5655
  merged = `${merged}.extend(${refSchema}.shape)`;
5656
5656
  } else if (context.generateInlineObjectShape && (schema.properties || schema.type === "object")) {
5657
5657
  const inlineShape = context.generateInlineObjectShape(schema, currentSchema);
5658
5658
  merged = `${merged}.extend(${inlineShape})`;
5659
5659
  } else {
5660
- const schemaString = context.generatePropertySchema(schema, currentSchema, false);
5660
+ const schemaString = context.generatePropertySchema(schema, currentSchema, false, true);
5661
5661
  merged = `${merged}.extend(${schemaString}.shape)`;
5662
5662
  }
5663
5663
  }
5664
5664
  result = merged;
5665
5665
  } else {
5666
- const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false));
5666
+ const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
5667
5667
  let merged = schemaStrings[0];
5668
5668
  for (let i = 1; i < schemaStrings.length; i++) {
5669
5669
  merged = `${merged}.and(${schemaStrings[i]})`;
@@ -6499,12 +6499,21 @@ var init_property_generator = __esm({
6499
6499
  }
6500
6500
  /**
6501
6501
  * Generate Zod schema for a property
6502
+ * @param schema - The OpenAPI schema to generate
6503
+ * @param currentSchema - The name of the current schema being processed (for circular ref detection)
6504
+ * @param isTopLevel - Whether this is a top-level schema definition
6505
+ * @param suppressDefaultNullable - When true, don't apply defaultNullable (used when outer schema has explicit nullable: false)
6502
6506
  */
6503
- generatePropertySchema(schema, currentSchema, isTopLevel = false) {
6507
+ generatePropertySchema(schema, currentSchema, isTopLevel = false, suppressDefaultNullable = false) {
6504
6508
  var _a, _b, _c, _d, _e;
6505
6509
  const isCacheable = !schema.$ref && !schema.allOf && !schema.oneOf && !schema.anyOf && !currentSchema;
6506
6510
  if (isCacheable) {
6507
- const cacheKey = JSON.stringify({ schema, type: this.context.schemaType, mode: this.context.mode });
6511
+ const cacheKey = JSON.stringify({
6512
+ schema,
6513
+ type: this.context.schemaType,
6514
+ mode: this.context.mode,
6515
+ suppressDefaultNullable
6516
+ });
6508
6517
  const cached = this.schemaCache.get(cacheKey);
6509
6518
  if (cached) {
6510
6519
  return cached;
@@ -6513,10 +6522,9 @@ var init_property_generator = __esm({
6513
6522
  if ((this.context.schemaType === "request" || this.context.schemaType === "response") && schema.properties) {
6514
6523
  schema = this.filterNestedProperties(schema);
6515
6524
  }
6516
- const isSchemaRef = !!schema.$ref;
6517
6525
  const isEnum = !!schema.enum;
6518
6526
  const isConst = schema.const !== void 0;
6519
- const shouldApplyDefaultNullable = !isTopLevel && !isSchemaRef && !isEnum && !isConst;
6527
+ const shouldApplyDefaultNullable = !isTopLevel && !isEnum && !isConst && !suppressDefaultNullable;
6520
6528
  const effectiveDefaultNullable = shouldApplyDefaultNullable ? this.context.defaultNullable : false;
6521
6529
  const nullable = isNullable(schema, effectiveDefaultNullable);
6522
6530
  if (hasMultipleTypes(schema)) {
@@ -6567,9 +6575,10 @@ var init_property_generator = __esm({
6567
6575
  return wrapNullable(zodUnion, nullable);
6568
6576
  }
6569
6577
  if (schema.allOf) {
6578
+ const compositionNullable = isNullable(schema, false);
6570
6579
  let composition = generateAllOf(
6571
6580
  schema.allOf,
6572
- nullable,
6581
+ compositionNullable,
6573
6582
  {
6574
6583
  generatePropertySchema: this.generatePropertySchema.bind(this),
6575
6584
  generateInlineObjectShape: this.generateInlineObjectShape.bind(this),
@@ -6583,11 +6592,12 @@ var init_property_generator = __esm({
6583
6592
  return composition;
6584
6593
  }
6585
6594
  if (schema.oneOf) {
6595
+ const compositionNullable = isNullable(schema, false);
6586
6596
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
6587
6597
  let composition = generateUnion(
6588
6598
  schema.oneOf,
6589
6599
  (_b = schema.discriminator) == null ? void 0 : _b.propertyName,
6590
- nullable,
6600
+ compositionNullable,
6591
6601
  {
6592
6602
  generatePropertySchema: this.generatePropertySchema.bind(this),
6593
6603
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -6605,11 +6615,12 @@ var init_property_generator = __esm({
6605
6615
  return composition;
6606
6616
  }
6607
6617
  if (schema.anyOf) {
6618
+ const compositionNullable = isNullable(schema, false);
6608
6619
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
6609
6620
  let composition = generateUnion(
6610
6621
  schema.anyOf,
6611
6622
  (_d = schema.discriminator) == null ? void 0 : _d.propertyName,
6612
- nullable,
6623
+ compositionNullable,
6613
6624
  {
6614
6625
  generatePropertySchema: this.generatePropertySchema.bind(this),
6615
6626
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -7141,12 +7152,6 @@ var init_openapi_generator = __esm({
7141
7152
  * Generate the complete output file
7142
7153
  */
7143
7154
  generate() {
7144
- if (!this.options.output) {
7145
- throw new ConfigurationError(
7146
- "Output path is required when calling generate(). Either provide an 'output' option or use generateString() to get the result as a string.",
7147
- { hasOutput: false }
7148
- );
7149
- }
7150
7155
  const output = this.generateString();
7151
7156
  const normalizedOutput = normalize(this.options.output);
7152
7157
  this.ensureDirectoryExists(normalizedOutput);
@@ -7875,7 +7880,8 @@ var init_config_schemas = __esm({
7875
7880
  mode: z.enum(["strict", "normal", "loose"]).optional(),
7876
7881
  useDescribe: z.boolean().optional(),
7877
7882
  includeDescriptions: z.boolean().optional(),
7878
- defaultNullable: z.boolean().optional()
7883
+ defaultNullable: z.boolean().optional(),
7884
+ emptyObjectBehavior: z.enum(["strict", "loose", "record"]).optional()
7879
7885
  });
7880
7886
  OperationFiltersSchema = z.strictObject({
7881
7887
  includeTags: z.array(z.string()).optional(),
@@ -8007,6 +8013,7 @@ function mergeConfigWithDefaults(config) {
8007
8013
  includeDescriptions: defaults.includeDescriptions,
8008
8014
  useDescribe: defaults.useDescribe,
8009
8015
  defaultNullable: defaults.defaultNullable,
8016
+ emptyObjectBehavior: defaults.emptyObjectBehavior,
8010
8017
  schemaType: defaults.schemaType,
8011
8018
  prefix: defaults.prefix,
8012
8019
  suffix: defaults.suffix,
@@ -8033,6 +8040,7 @@ var init_config_loader = __esm({
8033
8040
  includeDescriptions: z2.boolean().optional(),
8034
8041
  useDescribe: z2.boolean().optional(),
8035
8042
  defaultNullable: z2.boolean().optional(),
8043
+ emptyObjectBehavior: z2.enum(["strict", "loose", "record"]).optional(),
8036
8044
  schemaType: z2.enum(["all", "request", "response"]).optional(),
8037
8045
  prefix: z2.string().optional(),
8038
8046
  suffix: z2.string().optional(),
@@ -8065,6 +8073,7 @@ var init_config_loader = __esm({
8065
8073
  includeDescriptions: z2.boolean().optional(),
8066
8074
  useDescribe: z2.boolean().optional(),
8067
8075
  defaultNullable: z2.boolean().optional(),
8076
+ emptyObjectBehavior: z2.enum(["strict", "loose", "record"]).optional(),
8068
8077
  schemaType: z2.enum(["all", "request", "response"]).optional(),
8069
8078
  prefix: z2.string().optional(),
8070
8079
  suffix: z2.string().optional(),