@cerios/openapi-to-zod 1.3.1 → 1.4.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/index.mjs CHANGED
@@ -155,7 +155,7 @@ function escapeDescription(str) {
155
155
  return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
156
156
  }
157
157
  function escapePattern(str) {
158
- return str.replace(/\//g, "\\/");
158
+ return str.replace(/(?<!\\)\//g, "\\/");
159
159
  }
160
160
  function escapeJSDoc(str) {
161
161
  return str.replace(/\*\//g, "*\\/");
@@ -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
  }
@@ -520,9 +520,9 @@ function detectConflictingProperties(schemas, context) {
520
520
  }
521
521
  return conflicts;
522
522
  }
523
- function generateAllOf(schemas, isNullable2, context, currentSchema, explicitNullableFalse = false) {
523
+ function generateAllOf(schemas, isNullable2, context, currentSchema) {
524
524
  if (schemas.length === 1) {
525
- const singleSchema = context.generatePropertySchema(schemas[0], currentSchema, false, explicitNullableFalse);
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, explicitNul
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]})`;
@@ -995,12 +995,6 @@ ${properties.join(",\n")}
995
995
  }
996
996
 
997
997
  // src/validators/string-validator.ts
998
- var PATTERN_CACHE = new LRUCache(1e3);
999
- function configurePatternCache(size) {
1000
- if (size > 0 && size !== PATTERN_CACHE.capacity) {
1001
- PATTERN_CACHE = new LRUCache(size);
1002
- }
1003
- }
1004
998
  var DEFAULT_FORMAT_MAP = {
1005
999
  uuid: "z.uuid()",
1006
1000
  email: "z.email()",
@@ -1029,19 +1023,13 @@ var DEFAULT_FORMAT_MAP = {
1029
1023
  "json-pointer": 'z.string().refine((val) => val === "" || /^(\\/([^~/]|~0|~1)+)+$/.test(val), { message: "Must be a valid JSON Pointer (RFC 6901)" })',
1030
1024
  "relative-json-pointer": 'z.string().refine((val) => /^(0|[1-9]\\d*)(#|(\\/([^~/]|~0|~1)+)*)$/.test(val), { message: "Must be a valid relative JSON Pointer" })'
1031
1025
  };
1032
- var FORMAT_MAP = {
1033
- ...DEFAULT_FORMAT_MAP,
1034
- "date-time": "z.iso.datetime()"
1035
- };
1036
- function configureDateTimeFormat(pattern) {
1026
+ function buildDateTimeValidation(pattern) {
1037
1027
  if (!pattern) {
1038
- FORMAT_MAP["date-time"] = "z.iso.datetime()";
1039
- return;
1028
+ return "z.iso.datetime()";
1040
1029
  }
1041
1030
  const patternStr = pattern instanceof RegExp ? pattern.source : pattern;
1042
1031
  if (patternStr === "") {
1043
- FORMAT_MAP["date-time"] = "z.iso.datetime()";
1044
- return;
1032
+ return "z.iso.datetime()";
1045
1033
  }
1046
1034
  try {
1047
1035
  new RegExp(patternStr);
@@ -1051,10 +1039,16 @@ function configureDateTimeFormat(pattern) {
1051
1039
  );
1052
1040
  }
1053
1041
  const escapedPattern = escapePattern(patternStr);
1054
- FORMAT_MAP["date-time"] = `z.string().regex(/${escapedPattern}/)`;
1042
+ return `z.string().regex(/${escapedPattern}/)`;
1055
1043
  }
1056
- function generateStringValidation(schema, useDescribe) {
1057
- let validation = FORMAT_MAP[schema.format || ""] || "z.string()";
1044
+ function generateStringValidation(schema, useDescribe, context) {
1045
+ let validation;
1046
+ const format = schema.format || "";
1047
+ if (format === "date-time") {
1048
+ validation = context.dateTimeValidation;
1049
+ } else {
1050
+ validation = DEFAULT_FORMAT_MAP[format] || "z.string()";
1051
+ }
1058
1052
  if (schema.minLength !== void 0) {
1059
1053
  validation += `.min(${schema.minLength})`;
1060
1054
  }
@@ -1062,10 +1056,10 @@ function generateStringValidation(schema, useDescribe) {
1062
1056
  validation += `.max(${schema.maxLength})`;
1063
1057
  }
1064
1058
  if (schema.pattern) {
1065
- let escapedPattern = PATTERN_CACHE.get(schema.pattern);
1059
+ let escapedPattern = context.patternCache.get(schema.pattern);
1066
1060
  if (escapedPattern === void 0) {
1067
1061
  escapedPattern = escapePattern(schema.pattern);
1068
- PATTERN_CACHE.set(schema.pattern, escapedPattern);
1062
+ context.patternCache.set(schema.pattern, escapedPattern);
1069
1063
  }
1070
1064
  validation += `.regex(/${escapedPattern}/)`;
1071
1065
  }
@@ -1095,10 +1089,10 @@ function generateStringValidation(schema, useDescribe) {
1095
1089
  validation += `.max(${schema.maxLength})`;
1096
1090
  }
1097
1091
  if (schema.pattern) {
1098
- let escapedPattern = PATTERN_CACHE.get(schema.pattern);
1092
+ let escapedPattern = context.patternCache.get(schema.pattern);
1099
1093
  if (escapedPattern === void 0) {
1100
1094
  escapedPattern = escapePattern(schema.pattern);
1101
- PATTERN_CACHE.set(schema.pattern, escapedPattern);
1095
+ context.patternCache.set(schema.pattern, escapedPattern);
1102
1096
  }
1103
1097
  validation += `.regex(/${escapedPattern}/)`;
1104
1098
  }
@@ -1413,17 +1407,16 @@ var _PropertyGenerator = class _PropertyGenerator {
1413
1407
  return wrapNullable(zodUnion, nullable);
1414
1408
  }
1415
1409
  if (schema.allOf) {
1416
- const explicitNullableFalse = schema.nullable === false;
1410
+ const compositionNullable = isNullable(schema, false);
1417
1411
  let composition = generateAllOf(
1418
1412
  schema.allOf,
1419
- nullable,
1413
+ compositionNullable,
1420
1414
  {
1421
1415
  generatePropertySchema: this.generatePropertySchema.bind(this),
1422
1416
  generateInlineObjectShape: this.generateInlineObjectShape.bind(this),
1423
1417
  resolveSchemaRef: this.resolveSchemaRef.bind(this)
1424
1418
  },
1425
- currentSchema,
1426
- explicitNullableFalse
1419
+ currentSchema
1427
1420
  );
1428
1421
  if (schema.unevaluatedProperties !== void 0) {
1429
1422
  composition = this.applyUnevaluatedProperties(composition, schema);
@@ -1431,11 +1424,12 @@ var _PropertyGenerator = class _PropertyGenerator {
1431
1424
  return composition;
1432
1425
  }
1433
1426
  if (schema.oneOf) {
1427
+ const compositionNullable = isNullable(schema, false);
1434
1428
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
1435
1429
  let composition = generateUnion(
1436
1430
  schema.oneOf,
1437
1431
  (_b = schema.discriminator) == null ? void 0 : _b.propertyName,
1438
- nullable,
1432
+ compositionNullable,
1439
1433
  {
1440
1434
  generatePropertySchema: this.generatePropertySchema.bind(this),
1441
1435
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -1453,11 +1447,12 @@ var _PropertyGenerator = class _PropertyGenerator {
1453
1447
  return composition;
1454
1448
  }
1455
1449
  if (schema.anyOf) {
1450
+ const compositionNullable = isNullable(schema, false);
1456
1451
  const needsPassthrough = schema.unevaluatedProperties !== void 0;
1457
1452
  let composition = generateUnion(
1458
1453
  schema.anyOf,
1459
1454
  (_d = schema.discriminator) == null ? void 0 : _d.propertyName,
1460
- nullable,
1455
+ compositionNullable,
1461
1456
  {
1462
1457
  generatePropertySchema: this.generatePropertySchema.bind(this),
1463
1458
  resolveDiscriminatorMapping: this.resolveDiscriminatorMapping.bind(this),
@@ -1490,7 +1485,10 @@ var _PropertyGenerator = class _PropertyGenerator {
1490
1485
  const primaryType = getPrimaryType(schema);
1491
1486
  switch (primaryType) {
1492
1487
  case "string":
1493
- validation = generateStringValidation(schema, this.context.useDescribe);
1488
+ validation = generateStringValidation(schema, this.context.useDescribe, {
1489
+ dateTimeValidation: this.context.dateTimeValidation,
1490
+ patternCache: this.context.patternCache
1491
+ });
1494
1492
  break;
1495
1493
  case "number":
1496
1494
  validation = generateNumberValidation(schema, false, this.context.useDescribe);
@@ -1792,7 +1790,7 @@ var OpenApiGenerator = class {
1792
1790
  this.schemaUsageMap = /* @__PURE__ */ new Map();
1793
1791
  this.needsZodImport = true;
1794
1792
  this.filterStats = createFilterStatistics();
1795
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1793
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1796
1794
  if (!options.input) {
1797
1795
  throw new ConfigurationError("Input path is required", { providedOptions: options });
1798
1796
  }
@@ -1818,12 +1816,8 @@ var OpenApiGenerator = class {
1818
1816
  batchSize: (_g = options.batchSize) != null ? _g : 10,
1819
1817
  customDateTimeFormatRegex: options.customDateTimeFormatRegex
1820
1818
  };
1821
- if (this.options.cacheSize) {
1822
- configurePatternCache(this.options.cacheSize);
1823
- }
1824
- if (this.options.customDateTimeFormatRegex) {
1825
- configureDateTimeFormat(this.options.customDateTimeFormatRegex);
1826
- }
1819
+ this.patternCache = new LRUCache((_h = this.options.cacheSize) != null ? _h : 1e3);
1820
+ this.dateTimeValidation = buildDateTimeValidation(this.options.customDateTimeFormatRegex);
1827
1821
  try {
1828
1822
  const fs = __require("fs");
1829
1823
  if (!fs.existsSync(this.options.input)) {
@@ -1886,13 +1880,15 @@ var OpenApiGenerator = class {
1886
1880
  mode: this.requestOptions.mode,
1887
1881
  includeDescriptions: this.requestOptions.includeDescriptions,
1888
1882
  useDescribe: this.requestOptions.useDescribe,
1889
- defaultNullable: (_h = this.options.defaultNullable) != null ? _h : false,
1890
- emptyObjectBehavior: (_i = this.options.emptyObjectBehavior) != null ? _i : "loose",
1883
+ defaultNullable: (_i = this.options.defaultNullable) != null ? _i : false,
1884
+ emptyObjectBehavior: (_j = this.options.emptyObjectBehavior) != null ? _j : "loose",
1891
1885
  namingOptions: {
1892
1886
  prefix: this.options.prefix,
1893
1887
  suffix: this.options.suffix
1894
1888
  },
1895
- stripSchemaPrefix: this.options.stripSchemaPrefix
1889
+ stripSchemaPrefix: this.options.stripSchemaPrefix,
1890
+ dateTimeValidation: this.dateTimeValidation,
1891
+ patternCache: this.patternCache
1896
1892
  });
1897
1893
  }
1898
1894
  /**
@@ -2273,7 +2269,9 @@ ${typeCode}`;
2273
2269
  prefix: this.options.prefix,
2274
2270
  suffix: this.options.suffix
2275
2271
  },
2276
- stripSchemaPrefix: this.options.stripSchemaPrefix
2272
+ stripSchemaPrefix: this.options.stripSchemaPrefix,
2273
+ dateTimeValidation: this.dateTimeValidation,
2274
+ patternCache: this.patternCache
2277
2275
  });
2278
2276
  const zodSchema = this.propertyGenerator.generatePropertySchema(schema, name, true);
2279
2277
  const zodSchemaCode = `${jsdoc}export const ${schemaName} = ${zodSchema};`;