@cerios/openapi-to-zod 1.1.0 → 1.1.1

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
@@ -67,7 +67,7 @@ var ConfigurationError = class extends GeneratorError {
67
67
  // src/openapi-generator.ts
68
68
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
69
69
  import { dirname, normalize } from "path";
70
- import { minimatch as minimatch2 } from "minimatch";
70
+ import { minimatch as minimatch3 } from "minimatch";
71
71
  import { parse } from "yaml";
72
72
 
73
73
  // src/utils/name-utils.ts
@@ -126,8 +126,26 @@ function resolveRef(ref) {
126
126
  function generateEnum(name, values, options) {
127
127
  const schemaName = `${toCamelCase(name, options)}Schema`;
128
128
  const typeName = toPascalCase(name);
129
- const enumValues = values.map((v) => `"${v}"`).join(", ");
130
- const schemaCode = `export const ${schemaName} = z.enum([${enumValues}]);`;
129
+ const allBooleans = values.every((v) => typeof v === "boolean");
130
+ if (allBooleans) {
131
+ const schemaCode2 = `export const ${schemaName} = z.boolean();`;
132
+ const typeCode2 = `export type ${typeName} = z.infer<typeof ${schemaName}>;`;
133
+ return { schemaCode: schemaCode2, typeCode: typeCode2 };
134
+ }
135
+ const allStrings = values.every((v) => typeof v === "string");
136
+ if (allStrings) {
137
+ const enumValues = values.map((v) => `"${v}"`).join(", ");
138
+ const schemaCode2 = `export const ${schemaName} = z.enum([${enumValues}]);`;
139
+ const typeCode2 = `export type ${typeName} = z.infer<typeof ${schemaName}>;`;
140
+ return { schemaCode: schemaCode2, typeCode: typeCode2 };
141
+ }
142
+ const literalValues = values.map((v) => {
143
+ if (typeof v === "string") {
144
+ return `z.literal("${v}")`;
145
+ }
146
+ return `z.literal(${v})`;
147
+ }).join(", ");
148
+ const schemaCode = `export const ${schemaName} = z.union([${literalValues}]);`;
131
149
  const typeCode = `export type ${typeName} = z.infer<typeof ${schemaName}>;`;
132
150
  return { schemaCode, typeCode };
133
151
  }
@@ -137,7 +155,7 @@ function escapeDescription(str) {
137
155
  return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
138
156
  }
139
157
  function escapePattern(str) {
140
- return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
158
+ return str.replace(/\//g, "\\/");
141
159
  }
142
160
  function escapeJSDoc(str) {
143
161
  return str.replace(/\*\//g, "*\\/");
@@ -262,61 +280,36 @@ var LRUCache = class {
262
280
  };
263
281
 
264
282
  // src/utils/pattern-utils.ts
265
- function isRegexPattern(pattern) {
266
- if (pattern.startsWith("^") || pattern.endsWith("$")) {
267
- return true;
268
- }
269
- if (/\\[dDwWsS]/.test(pattern)) {
270
- return true;
271
- }
272
- if (/\.\*|\.\+/.test(pattern)) {
273
- return true;
274
- }
275
- if (/[[\]()]/.test(pattern)) {
276
- return true;
277
- }
278
- if (/[^/][+?*]\{/.test(pattern)) {
283
+ import { minimatch } from "minimatch";
284
+ function isValidGlobPattern(pattern) {
285
+ try {
286
+ new minimatch.Minimatch(pattern);
279
287
  return true;
288
+ } catch {
289
+ return false;
280
290
  }
281
- return false;
282
291
  }
283
- function patternToRegex(pattern) {
284
- if (pattern instanceof RegExp) {
285
- return pattern;
286
- }
287
- if (isRegexPattern(pattern)) {
288
- try {
289
- return new RegExp(pattern);
290
- } catch (error) {
291
- console.warn(`\u26A0\uFE0F Invalid regex pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`);
292
- return null;
293
- }
294
- }
295
- return null;
292
+ function isGlobPattern(pattern) {
293
+ return /[*?[\]{}!]/.test(pattern);
296
294
  }
297
295
  function stripPrefix(input, pattern, ensureLeadingChar) {
298
296
  if (!pattern) {
299
297
  return input;
300
298
  }
301
- const regex = patternToRegex(pattern);
302
- if (regex) {
303
- const match = input.match(regex);
304
- if (match && match.index === 0) {
305
- const stripped = input.substring(match[0].length);
306
- if (ensureLeadingChar) {
307
- if (stripped === "") {
308
- return ensureLeadingChar;
309
- }
310
- if (!stripped.startsWith(ensureLeadingChar)) {
311
- return `${ensureLeadingChar}${stripped}`;
312
- }
299
+ if (isGlobPattern(pattern) && !isValidGlobPattern(pattern)) {
300
+ console.warn(`\u26A0\uFE0F Invalid glob pattern "${pattern}": Pattern is malformed`);
301
+ return input;
302
+ }
303
+ if (isGlobPattern(pattern)) {
304
+ let longestMatch = -1;
305
+ for (let i = 1; i <= input.length; i++) {
306
+ const testPrefix = input.substring(0, i);
307
+ if (minimatch(testPrefix, pattern)) {
308
+ longestMatch = i;
313
309
  }
314
- return stripped;
315
310
  }
316
- } else {
317
- const stringPattern = pattern;
318
- if (input.startsWith(stringPattern)) {
319
- const stripped = input.substring(stringPattern.length);
311
+ if (longestMatch > 0) {
312
+ const stripped = input.substring(longestMatch);
320
313
  if (ensureLeadingChar) {
321
314
  if (stripped === "") {
322
315
  return ensureLeadingChar;
@@ -325,8 +318,21 @@ function stripPrefix(input, pattern, ensureLeadingChar) {
325
318
  return `${ensureLeadingChar}${stripped}`;
326
319
  }
327
320
  }
328
- return stripped;
321
+ return stripped === "" && !ensureLeadingChar ? input : stripped;
322
+ }
323
+ return input;
324
+ }
325
+ if (input.startsWith(pattern)) {
326
+ const stripped = input.substring(pattern.length);
327
+ if (ensureLeadingChar) {
328
+ if (stripped === "") {
329
+ return ensureLeadingChar;
330
+ }
331
+ if (!stripped.startsWith(ensureLeadingChar)) {
332
+ return `${ensureLeadingChar}${stripped}`;
333
+ }
329
334
  }
335
+ return stripped;
330
336
  }
331
337
  return input;
332
338
  }
@@ -1201,9 +1207,25 @@ var _PropertyGenerator = class _PropertyGenerator {
1201
1207
  return wrapNullable(zodLiteral, nullable);
1202
1208
  }
1203
1209
  if (schema.enum) {
1204
- const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
1205
- const zodEnum = `z.enum([${enumValues}])`;
1206
- return wrapNullable(zodEnum, nullable);
1210
+ const allBooleans = schema.enum.every((v) => typeof v === "boolean");
1211
+ if (allBooleans) {
1212
+ const zodBoolean = "z.boolean()";
1213
+ return wrapNullable(zodBoolean, nullable);
1214
+ }
1215
+ const allStrings = schema.enum.every((v) => typeof v === "string");
1216
+ if (allStrings) {
1217
+ const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
1218
+ const zodEnum = `z.enum([${enumValues}])`;
1219
+ return wrapNullable(zodEnum, nullable);
1220
+ }
1221
+ const literalValues = schema.enum.map((v) => {
1222
+ if (typeof v === "string") {
1223
+ return `z.literal("${v}")`;
1224
+ }
1225
+ return `z.literal(${v})`;
1226
+ }).join(", ");
1227
+ const zodUnion = `z.union([${literalValues}])`;
1228
+ return wrapNullable(zodUnion, nullable);
1207
1229
  }
1208
1230
  if (schema.allOf) {
1209
1231
  let composition = generateAllOf(
@@ -1334,7 +1356,7 @@ _PropertyGenerator.INCLUSION_RULES = {
1334
1356
  var PropertyGenerator = _PropertyGenerator;
1335
1357
 
1336
1358
  // src/utils/operation-filters.ts
1337
- import { minimatch } from "minimatch";
1359
+ import { minimatch as minimatch2 } from "minimatch";
1338
1360
  function createFilterStatistics() {
1339
1361
  return {
1340
1362
  totalOperations: 0,
@@ -1353,7 +1375,7 @@ function matchesAnyPattern(value, patterns) {
1353
1375
  if (!value) {
1354
1376
  return false;
1355
1377
  }
1356
- return patterns.some((pattern) => minimatch(value, pattern));
1378
+ return patterns.some((pattern) => minimatch2(value, pattern));
1357
1379
  }
1358
1380
  function containsAny(arr, values) {
1359
1381
  if (!values || values.length === 0) {
@@ -1580,6 +1602,9 @@ var OpenApiGenerator = class {
1580
1602
  throw new SpecValidationError("No schemas found in OpenAPI spec", { filePath: this.options.input });
1581
1603
  }
1582
1604
  for (const [name, schema] of Object.entries(this.spec.components.schemas)) {
1605
+ if (this.options.operationFilters && this.schemaUsageMap.size > 0 && !this.schemaUsageMap.has(name)) {
1606
+ continue;
1607
+ }
1583
1608
  this.generateComponentSchema(name, schema);
1584
1609
  }
1585
1610
  this.generateQueryParameterSchemas();
@@ -2068,7 +2093,7 @@ ${propsCode}
2068
2093
  const headerLower = headerName.toLowerCase();
2069
2094
  return ignorePatterns.some((pattern) => {
2070
2095
  const patternLower = pattern.toLowerCase();
2071
- return minimatch2(headerLower, patternLower);
2096
+ return minimatch3(headerLower, patternLower);
2072
2097
  });
2073
2098
  }
2074
2099
  /**
@@ -2156,8 +2181,22 @@ ${propsCode}
2156
2181
  return `${schemaName}Schema`;
2157
2182
  }
2158
2183
  if (schema.enum) {
2159
- const enumValues = schema.enum.map((v) => typeof v === "string" ? `"${v}"` : v).join(", ");
2160
- return `z.enum([${enumValues}])`;
2184
+ const allBooleans = schema.enum.every((v) => typeof v === "boolean");
2185
+ if (allBooleans) {
2186
+ return "z.boolean()";
2187
+ }
2188
+ const allStrings = schema.enum.every((v) => typeof v === "string");
2189
+ if (allStrings) {
2190
+ const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
2191
+ return `z.enum([${enumValues}])`;
2192
+ }
2193
+ const literalValues = schema.enum.map((v) => {
2194
+ if (typeof v === "string") {
2195
+ return `z.literal("${v}")`;
2196
+ }
2197
+ return `z.literal(${v})`;
2198
+ }).join(", ");
2199
+ return `z.union([${literalValues}])`;
2161
2200
  }
2162
2201
  const type = schema.type;
2163
2202
  if (type === "string") {