@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/index.mjs CHANGED
@@ -86,12 +86,12 @@ function toCamelCase(str, options) {
86
86
  name = words[0].charAt(0).toLowerCase() + words[0].slice(1) + words.slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
87
87
  }
88
88
  if (options == null ? void 0 : options.prefix) {
89
- const prefix = options.prefix.toLowerCase();
89
+ const prefix = options.prefix.charAt(0).toLowerCase() + options.prefix.slice(1);
90
90
  name = prefix + name.charAt(0).toUpperCase() + name.slice(1);
91
91
  }
92
92
  if (options == null ? void 0 : options.suffix) {
93
- const suffix = options.suffix;
94
- name = name + suffix.charAt(0).toUpperCase() + suffix.slice(1).toLowerCase();
93
+ const suffix = options.suffix.charAt(0).toUpperCase() + options.suffix.slice(1);
94
+ name = name + suffix;
95
95
  }
96
96
  return name;
97
97
  }
@@ -429,7 +429,7 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
429
429
  );
430
430
  }
431
431
  if (schemas.length === 1) {
432
- let singleSchema = context.generatePropertySchema(schemas[0], currentSchema);
432
+ let singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
433
433
  if ((options == null ? void 0 : options.passthrough) && !singleSchema.includes(".catchall(")) {
434
434
  singleSchema = `${singleSchema}.catchall(z.unknown())`;
435
435
  }
@@ -445,7 +445,7 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
445
445
  console.warn(
446
446
  `[openapi-to-zod] Warning: Discriminator "${discriminator}" is not required in schemas: ${discriminatorCheck.invalidSchemas.join(", ")}. Falling back to z.union() instead of z.discriminatedUnion().`
447
447
  );
448
- let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
448
+ let schemaStrings3 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
449
449
  if (options == null ? void 0 : options.passthrough) {
450
450
  schemaStrings3 = schemaStrings3.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
451
451
  }
@@ -453,14 +453,14 @@ function generateUnion(schemas, discriminator, isNullable2, context, options, cu
453
453
  const union3 = `z.union([${schemaStrings3.join(", ")}]).describe("${fallbackDescription}")`;
454
454
  return wrapNullable(union3, isNullable2);
455
455
  }
456
- let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema));
456
+ let schemaStrings2 = resolvedSchemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
457
457
  if (options == null ? void 0 : options.passthrough) {
458
458
  schemaStrings2 = schemaStrings2.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
459
459
  }
460
460
  const union2 = `z.discriminatedUnion("${discriminator}", [${schemaStrings2.join(", ")}])`;
461
461
  return wrapNullable(union2, isNullable2);
462
462
  }
463
- let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema));
463
+ let schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
464
464
  if (options == null ? void 0 : options.passthrough) {
465
465
  schemaStrings = schemaStrings.map((s) => s.includes(".catchall(") ? s : `${s}.catchall(z.unknown())`);
466
466
  }
@@ -522,7 +522,7 @@ function detectConflictingProperties(schemas, context) {
522
522
  }
523
523
  function generateAllOf(schemas, isNullable2, context, currentSchema) {
524
524
  if (schemas.length === 1) {
525
- const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false);
525
+ const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, true);
526
526
  return wrapNullable(singleSchema, isNullable2);
527
527
  }
528
528
  const conflicts = detectConflictingProperties(schemas, context);
@@ -536,23 +536,23 @@ function generateAllOf(schemas, isNullable2, context, currentSchema) {
536
536
  const allObjects = schemas.every((s) => s.type === "object" || s.properties || s.$ref || s.allOf);
537
537
  let result;
538
538
  if (allObjects) {
539
- let merged = context.generatePropertySchema(schemas[0], currentSchema, false);
539
+ let merged = context.generatePropertySchema(schemas[0], currentSchema, false, true);
540
540
  for (let i = 1; i < schemas.length; i++) {
541
541
  const schema = schemas[i];
542
542
  if (schema.$ref) {
543
- const refSchema = context.generatePropertySchema(schema, currentSchema, false);
543
+ const refSchema = context.generatePropertySchema(schema, currentSchema, false, true);
544
544
  merged = `${merged}.extend(${refSchema}.shape)`;
545
545
  } else if (context.generateInlineObjectShape && (schema.properties || schema.type === "object")) {
546
546
  const inlineShape = context.generateInlineObjectShape(schema, currentSchema);
547
547
  merged = `${merged}.extend(${inlineShape})`;
548
548
  } else {
549
- const schemaString = context.generatePropertySchema(schema, currentSchema, false);
549
+ const schemaString = context.generatePropertySchema(schema, currentSchema, false, true);
550
550
  merged = `${merged}.extend(${schemaString}.shape)`;
551
551
  }
552
552
  }
553
553
  result = merged;
554
554
  } else {
555
- const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false));
555
+ const schemaStrings = schemas.map((s) => context.generatePropertySchema(s, currentSchema, false, true));
556
556
  let merged = schemaStrings[0];
557
557
  for (let i = 1; i < schemaStrings.length; i++) {
558
558
  merged = `${merged}.and(${schemaStrings[i]})`;
@@ -1337,12 +1337,21 @@ var _PropertyGenerator = class _PropertyGenerator {
1337
1337
  }
1338
1338
  /**
1339
1339
  * Generate Zod schema for a property
1340
+ * @param schema - The OpenAPI schema to generate
1341
+ * @param currentSchema - The name of the current schema being processed (for circular ref detection)
1342
+ * @param isTopLevel - Whether this is a top-level schema definition
1343
+ * @param suppressDefaultNullable - When true, don't apply defaultNullable (used when outer schema has explicit nullable: false)
1340
1344
  */
1341
- generatePropertySchema(schema, currentSchema, isTopLevel = false) {
1345
+ generatePropertySchema(schema, currentSchema, isTopLevel = false, suppressDefaultNullable = false) {
1342
1346
  var _a, _b, _c, _d, _e;
1343
1347
  const isCacheable = !schema.$ref && !schema.allOf && !schema.oneOf && !schema.anyOf && !currentSchema;
1344
1348
  if (isCacheable) {
1345
- const cacheKey = JSON.stringify({ schema, type: this.context.schemaType, mode: this.context.mode });
1349
+ const cacheKey = JSON.stringify({
1350
+ schema,
1351
+ type: this.context.schemaType,
1352
+ mode: this.context.mode,
1353
+ suppressDefaultNullable
1354
+ });
1346
1355
  const cached = this.schemaCache.get(cacheKey);
1347
1356
  if (cached) {
1348
1357
  return cached;
@@ -1351,10 +1360,9 @@ var _PropertyGenerator = class _PropertyGenerator {
1351
1360
  if ((this.context.schemaType === "request" || this.context.schemaType === "response") && schema.properties) {
1352
1361
  schema = this.filterNestedProperties(schema);
1353
1362
  }
1354
- const isSchemaRef = !!schema.$ref;
1355
1363
  const isEnum = !!schema.enum;
1356
1364
  const isConst = schema.const !== void 0;
1357
- const shouldApplyDefaultNullable = !isTopLevel && !isSchemaRef && !isEnum && !isConst;
1365
+ const shouldApplyDefaultNullable = !isTopLevel && !isEnum && !isConst && !suppressDefaultNullable;
1358
1366
  const effectiveDefaultNullable = shouldApplyDefaultNullable ? this.context.defaultNullable : false;
1359
1367
  const nullable = isNullable(schema, effectiveDefaultNullable);
1360
1368
  if (hasMultipleTypes(schema)) {
@@ -1405,9 +1413,10 @@ var _PropertyGenerator = class _PropertyGenerator {
1405
1413
  return wrapNullable(zodUnion, nullable);
1406
1414
  }
1407
1415
  if (schema.allOf) {
1416
+ const compositionNullable = isNullable(schema, false);
1408
1417
  let composition = generateAllOf(
1409
1418
  schema.allOf,
1410
- nullable,
1419
+ compositionNullable,
1411
1420
  {
1412
1421
  generatePropertySchema: this.generatePropertySchema.bind(this),
1413
1422
  generateInlineObjectShape: this.generateInlineObjectShape.bind(this),
@@ -1421,11 +1430,12 @@ var _PropertyGenerator = class _PropertyGenerator {
1421
1430
  return composition;
1422
1431
  }
1423
1432
  if (schema.oneOf) {
1433
+ const compositionNullable = isNullable(schema, false);
1424
1434
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
1425
1435
  let composition = generateUnion(
1426
1436
  schema.oneOf,
1427
1437
  (_b = schema.discriminator) == null ? void 0 : _b.propertyName,
1428
- nullable,
1438
+ compositionNullable,
1429
1439
  {
1430
1440
  generatePropertySchema: this.generatePropertySchema.bind(this),
1431
1441
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -1443,11 +1453,12 @@ var _PropertyGenerator = class _PropertyGenerator {
1443
1453
  return composition;
1444
1454
  }
1445
1455
  if (schema.anyOf) {
1456
+ const compositionNullable = isNullable(schema, false);
1446
1457
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
1447
1458
  let composition = generateUnion(
1448
1459
  schema.anyOf,
1449
1460
  (_d = schema.discriminator) == null ? void 0 : _d.propertyName,
1450
- nullable,
1461
+ compositionNullable,
1451
1462
  {
1452
1463
  generatePropertySchema: this.generatePropertySchema.bind(this),
1453
1464
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -1947,12 +1958,6 @@ var OpenApiGenerator = class {
1947
1958
  * Generate the complete output file
1948
1959
  */
1949
1960
  generate() {
1950
- if (!this.options.output) {
1951
- throw new ConfigurationError(
1952
- "Output path is required when calling generate(). Either provide an 'output' option or use generateString() to get the result as a string.",
1953
- { hasOutput: false }
1954
- );
1955
- }
1956
1961
  const output = this.generateString();
1957
1962
  const normalizedOutput = normalize(this.options.output);
1958
1963
  this.ensureDirectoryExists(normalizedOutput);