@cerios/openapi-to-zod 1.1.0 → 1.2.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.
@@ -1,4 +1,4 @@
1
- import { E as ExecutionMode, d as OperationFilters } from './types-B7ePTDjr.mjs';
1
+ import { E as ExecutionMode, d as OperationFilters } from './types--r0d47sd.mjs';
2
2
  import { z } from 'zod';
3
3
  import { Loader } from 'cosmiconfig';
4
4
 
@@ -59,6 +59,7 @@ declare const RequestResponseOptionsSchema: z.ZodObject<{
59
59
  }>>;
60
60
  useDescribe: z.ZodOptional<z.ZodBoolean>;
61
61
  includeDescriptions: z.ZodOptional<z.ZodBoolean>;
62
+ defaultNullable: z.ZodOptional<z.ZodBoolean>;
62
63
  }, z.core.$strict>;
63
64
  /**
64
65
  * @shared Base Zod schema for operation filters (without status codes)
@@ -188,20 +189,12 @@ declare function validateFilters(stats: FilterStatistics, filters?: OperationFil
188
189
  declare function formatFilterStatistics(stats: FilterStatistics): string;
189
190
 
190
191
  /**
191
- * Pattern matching utilities for prefix stripping
192
- *
193
- * Shared utility used by core and playwright packages
194
- *
195
- * Supports both literal string matching and regex patterns for stripping
196
- * prefixes from strings (paths, schema names, etc.)
197
- */
198
- /**
199
- * @shared Strips a prefix from a string using either literal string matching or regex
192
+ * @shared Strips a prefix from a string using either literal string matching or glob patterns
200
193
  * @since 1.1.0
201
194
  * Shared utility used by core and playwright packages
202
195
  *
203
196
  * @param input - The full string to strip from
204
- * @param pattern - The pattern to strip (string or RegExp)
197
+ * @param pattern - The glob pattern to strip
205
198
  * @param ensureLeadingChar - Optional character to ensure at start (e.g., "/" for paths)
206
199
  * @returns The string with prefix removed, or original string if no match
207
200
  *
@@ -211,25 +204,27 @@ declare function formatFilterStatistics(stats: FilterStatistics): string;
211
204
  * stripPrefix("Company.Models.User", "Company.Models.") // => "User"
212
205
  *
213
206
  * @example
214
- * // Regex pattern matching
215
- * stripPrefix("/api/v1.0/users", "^/api/v\\d+\\.\\d+") // => "/users"
216
- * stripPrefix("api_v2_UserSchema", "^api_v\\d+_") // => "UserSchema"
207
+ * // Glob pattern matching
208
+ * stripPrefix("/api/v1.0/users", "/api/v*") // => matches and strips
209
+ * stripPrefix("Company.Models.User", "*.Models.") // => "User"
210
+ * stripPrefix("api_v2_UserSchema", "api_v[0-9]_") // => "UserSchema"
217
211
  */
218
- declare function stripPrefix(input: string, pattern: string | RegExp | undefined, ensureLeadingChar?: string): string;
212
+ declare function stripPrefix(input: string, pattern: string | undefined, ensureLeadingChar?: string): string;
219
213
  /**
220
214
  * @shared Strips a prefix from a path (ensures leading slash)
221
215
  * @since 1.1.0
222
216
  * Shared utility used by playwright package for path manipulation
223
217
  *
224
218
  * @param path - The full path to strip from
225
- * @param pattern - The pattern to strip (string or RegExp)
219
+ * @param pattern - The glob pattern to strip
226
220
  * @returns The path with prefix removed, or original path if no match
227
221
  *
228
222
  * @example
229
223
  * stripPathPrefix("/api/v1/users", "/api/v1") // => "/users"
230
- * stripPathPrefix("/api/v2/posts", "^/api/v\\d+") // => "/posts"
224
+ * stripPathPrefix("/api/v2/posts", "/api/v*") // => "/posts"
225
+ * stripPathPrefix("/api/v1.0/items", "/api/v[0-9].*") // => "/items"
231
226
  */
232
- declare function stripPathPrefix(path: string, pattern: string | RegExp | undefined): string;
227
+ declare function stripPathPrefix(path: string, pattern: string | undefined): string;
233
228
 
234
229
  /**
235
230
  * String utility functions for escaping and formatting
@@ -254,4 +249,24 @@ declare function escapeJSDoc(str: string): string;
254
249
  */
255
250
  declare function createTypeScriptLoader(): Loader;
256
251
 
257
- export { type BaseOperationFilters, type FilterStatistics, type Generator, LRUCache, OperationFiltersSchema, type RequestResponseOptions, RequestResponseOptionsSchema, createFilterStatistics, createTypeScriptLoader, escapeJSDoc, executeBatch, formatConfigValidationError, formatFilterStatistics, getBatchExitCode, shouldIncludeOperation, stripPathPrefix, stripPrefix, toCamelCase, toPascalCase, validateFilters };
252
+ /**
253
+ * Configure custom date-time format validation
254
+ * Overrides the default z.iso.datetime() with a custom regex pattern
255
+ *
256
+ * @param pattern - Regex pattern (string or RegExp) for date-time validation
257
+ * @throws {Error} If the provided pattern is not a valid regular expression
258
+ * @example
259
+ * // String pattern (required for JSON/YAML configs)
260
+ * configureDateTimeFormat('^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$')
261
+ *
262
+ * @example
263
+ * // RegExp literal (TypeScript configs only)
264
+ * configureDateTimeFormat(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/)
265
+ */
266
+ declare function configureDateTimeFormat(pattern?: string | RegExp): void;
267
+ /**
268
+ * Reset format map to defaults (useful for testing)
269
+ */
270
+ declare function resetFormatMap(): void;
271
+
272
+ export { type BaseOperationFilters, type FilterStatistics, type Generator, LRUCache, OperationFiltersSchema, type RequestResponseOptions, RequestResponseOptionsSchema, configureDateTimeFormat, createFilterStatistics, createTypeScriptLoader, escapeJSDoc, executeBatch, formatConfigValidationError, formatFilterStatistics, getBatchExitCode, resetFormatMap, shouldIncludeOperation, stripPathPrefix, stripPrefix, toCamelCase, toPascalCase, validateFilters };
@@ -1,4 +1,4 @@
1
- import { E as ExecutionMode, d as OperationFilters } from './types-B7ePTDjr.js';
1
+ import { E as ExecutionMode, d as OperationFilters } from './types--r0d47sd.js';
2
2
  import { z } from 'zod';
3
3
  import { Loader } from 'cosmiconfig';
4
4
 
@@ -59,6 +59,7 @@ declare const RequestResponseOptionsSchema: z.ZodObject<{
59
59
  }>>;
60
60
  useDescribe: z.ZodOptional<z.ZodBoolean>;
61
61
  includeDescriptions: z.ZodOptional<z.ZodBoolean>;
62
+ defaultNullable: z.ZodOptional<z.ZodBoolean>;
62
63
  }, z.core.$strict>;
63
64
  /**
64
65
  * @shared Base Zod schema for operation filters (without status codes)
@@ -188,20 +189,12 @@ declare function validateFilters(stats: FilterStatistics, filters?: OperationFil
188
189
  declare function formatFilterStatistics(stats: FilterStatistics): string;
189
190
 
190
191
  /**
191
- * Pattern matching utilities for prefix stripping
192
- *
193
- * Shared utility used by core and playwright packages
194
- *
195
- * Supports both literal string matching and regex patterns for stripping
196
- * prefixes from strings (paths, schema names, etc.)
197
- */
198
- /**
199
- * @shared Strips a prefix from a string using either literal string matching or regex
192
+ * @shared Strips a prefix from a string using either literal string matching or glob patterns
200
193
  * @since 1.1.0
201
194
  * Shared utility used by core and playwright packages
202
195
  *
203
196
  * @param input - The full string to strip from
204
- * @param pattern - The pattern to strip (string or RegExp)
197
+ * @param pattern - The glob pattern to strip
205
198
  * @param ensureLeadingChar - Optional character to ensure at start (e.g., "/" for paths)
206
199
  * @returns The string with prefix removed, or original string if no match
207
200
  *
@@ -211,25 +204,27 @@ declare function formatFilterStatistics(stats: FilterStatistics): string;
211
204
  * stripPrefix("Company.Models.User", "Company.Models.") // => "User"
212
205
  *
213
206
  * @example
214
- * // Regex pattern matching
215
- * stripPrefix("/api/v1.0/users", "^/api/v\\d+\\.\\d+") // => "/users"
216
- * stripPrefix("api_v2_UserSchema", "^api_v\\d+_") // => "UserSchema"
207
+ * // Glob pattern matching
208
+ * stripPrefix("/api/v1.0/users", "/api/v*") // => matches and strips
209
+ * stripPrefix("Company.Models.User", "*.Models.") // => "User"
210
+ * stripPrefix("api_v2_UserSchema", "api_v[0-9]_") // => "UserSchema"
217
211
  */
218
- declare function stripPrefix(input: string, pattern: string | RegExp | undefined, ensureLeadingChar?: string): string;
212
+ declare function stripPrefix(input: string, pattern: string | undefined, ensureLeadingChar?: string): string;
219
213
  /**
220
214
  * @shared Strips a prefix from a path (ensures leading slash)
221
215
  * @since 1.1.0
222
216
  * Shared utility used by playwright package for path manipulation
223
217
  *
224
218
  * @param path - The full path to strip from
225
- * @param pattern - The pattern to strip (string or RegExp)
219
+ * @param pattern - The glob pattern to strip
226
220
  * @returns The path with prefix removed, or original path if no match
227
221
  *
228
222
  * @example
229
223
  * stripPathPrefix("/api/v1/users", "/api/v1") // => "/users"
230
- * stripPathPrefix("/api/v2/posts", "^/api/v\\d+") // => "/posts"
224
+ * stripPathPrefix("/api/v2/posts", "/api/v*") // => "/posts"
225
+ * stripPathPrefix("/api/v1.0/items", "/api/v[0-9].*") // => "/items"
231
226
  */
232
- declare function stripPathPrefix(path: string, pattern: string | RegExp | undefined): string;
227
+ declare function stripPathPrefix(path: string, pattern: string | undefined): string;
233
228
 
234
229
  /**
235
230
  * String utility functions for escaping and formatting
@@ -254,4 +249,24 @@ declare function escapeJSDoc(str: string): string;
254
249
  */
255
250
  declare function createTypeScriptLoader(): Loader;
256
251
 
257
- export { type BaseOperationFilters, type FilterStatistics, type Generator, LRUCache, OperationFiltersSchema, type RequestResponseOptions, RequestResponseOptionsSchema, createFilterStatistics, createTypeScriptLoader, escapeJSDoc, executeBatch, formatConfigValidationError, formatFilterStatistics, getBatchExitCode, shouldIncludeOperation, stripPathPrefix, stripPrefix, toCamelCase, toPascalCase, validateFilters };
252
+ /**
253
+ * Configure custom date-time format validation
254
+ * Overrides the default z.iso.datetime() with a custom regex pattern
255
+ *
256
+ * @param pattern - Regex pattern (string or RegExp) for date-time validation
257
+ * @throws {Error} If the provided pattern is not a valid regular expression
258
+ * @example
259
+ * // String pattern (required for JSON/YAML configs)
260
+ * configureDateTimeFormat('^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$')
261
+ *
262
+ * @example
263
+ * // RegExp literal (TypeScript configs only)
264
+ * configureDateTimeFormat(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/)
265
+ */
266
+ declare function configureDateTimeFormat(pattern?: string | RegExp): void;
267
+ /**
268
+ * Reset format map to defaults (useful for testing)
269
+ */
270
+ declare function resetFormatMap(): void;
271
+
272
+ export { type BaseOperationFilters, type FilterStatistics, type Generator, LRUCache, OperationFiltersSchema, type RequestResponseOptions, RequestResponseOptionsSchema, configureDateTimeFormat, createFilterStatistics, createTypeScriptLoader, escapeJSDoc, executeBatch, formatConfigValidationError, formatFilterStatistics, getBatchExitCode, resetFormatMap, shouldIncludeOperation, stripPathPrefix, stripPrefix, toCamelCase, toPascalCase, validateFilters };
package/dist/internal.js CHANGED
@@ -33,6 +33,7 @@ __export(internal_exports, {
33
33
  LRUCache: () => LRUCache,
34
34
  OperationFiltersSchema: () => OperationFiltersSchema,
35
35
  RequestResponseOptionsSchema: () => RequestResponseOptionsSchema,
36
+ configureDateTimeFormat: () => configureDateTimeFormat,
36
37
  createFilterStatistics: () => createFilterStatistics,
37
38
  createTypeScriptLoader: () => createTypeScriptLoader,
38
39
  escapeJSDoc: () => escapeJSDoc,
@@ -40,6 +41,7 @@ __export(internal_exports, {
40
41
  formatConfigValidationError: () => formatConfigValidationError,
41
42
  formatFilterStatistics: () => formatFilterStatistics,
42
43
  getBatchExitCode: () => getBatchExitCode,
44
+ resetFormatMap: () => resetFormatMap,
43
45
  shouldIncludeOperation: () => shouldIncludeOperation,
44
46
  stripPathPrefix: () => stripPathPrefix,
45
47
  stripPrefix: () => stripPrefix,
@@ -184,7 +186,8 @@ var import_zod = require("zod");
184
186
  var RequestResponseOptionsSchema = import_zod.z.strictObject({
185
187
  mode: import_zod.z.enum(["strict", "normal", "loose"]).optional(),
186
188
  useDescribe: import_zod.z.boolean().optional(),
187
- includeDescriptions: import_zod.z.boolean().optional()
189
+ includeDescriptions: import_zod.z.boolean().optional(),
190
+ defaultNullable: import_zod.z.boolean().optional()
188
191
  });
189
192
  var OperationFiltersSchema = import_zod.z.strictObject({
190
193
  includeTags: import_zod.z.array(import_zod.z.string()).optional(),
@@ -446,61 +449,36 @@ function formatFilterStatistics(stats) {
446
449
  }
447
450
 
448
451
  // src/utils/pattern-utils.ts
449
- function isRegexPattern(pattern) {
450
- if (pattern.startsWith("^") || pattern.endsWith("$")) {
451
- return true;
452
- }
453
- if (/\\[dDwWsS]/.test(pattern)) {
454
- return true;
455
- }
456
- if (/\.\*|\.\+/.test(pattern)) {
457
- return true;
458
- }
459
- if (/[[\]()]/.test(pattern)) {
460
- return true;
461
- }
462
- if (/[^/][+?*]\{/.test(pattern)) {
452
+ var import_minimatch2 = require("minimatch");
453
+ function isValidGlobPattern(pattern) {
454
+ try {
455
+ new import_minimatch2.minimatch.Minimatch(pattern);
463
456
  return true;
457
+ } catch {
458
+ return false;
464
459
  }
465
- return false;
466
460
  }
467
- function patternToRegex(pattern) {
468
- if (pattern instanceof RegExp) {
469
- return pattern;
470
- }
471
- if (isRegexPattern(pattern)) {
472
- try {
473
- return new RegExp(pattern);
474
- } catch (error) {
475
- console.warn(`\u26A0\uFE0F Invalid regex pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`);
476
- return null;
477
- }
478
- }
479
- return null;
461
+ function isGlobPattern(pattern) {
462
+ return /[*?[\]{}!]/.test(pattern);
480
463
  }
481
464
  function stripPrefix(input, pattern, ensureLeadingChar) {
482
465
  if (!pattern) {
483
466
  return input;
484
467
  }
485
- const regex = patternToRegex(pattern);
486
- if (regex) {
487
- const match = input.match(regex);
488
- if (match && match.index === 0) {
489
- const stripped = input.substring(match[0].length);
490
- if (ensureLeadingChar) {
491
- if (stripped === "") {
492
- return ensureLeadingChar;
493
- }
494
- if (!stripped.startsWith(ensureLeadingChar)) {
495
- return `${ensureLeadingChar}${stripped}`;
496
- }
468
+ if (isGlobPattern(pattern) && !isValidGlobPattern(pattern)) {
469
+ console.warn(`\u26A0\uFE0F Invalid glob pattern "${pattern}": Pattern is malformed`);
470
+ return input;
471
+ }
472
+ if (isGlobPattern(pattern)) {
473
+ let longestMatch = -1;
474
+ for (let i = 1; i <= input.length; i++) {
475
+ const testPrefix = input.substring(0, i);
476
+ if ((0, import_minimatch2.minimatch)(testPrefix, pattern)) {
477
+ longestMatch = i;
497
478
  }
498
- return stripped;
499
479
  }
500
- } else {
501
- const stringPattern = pattern;
502
- if (input.startsWith(stringPattern)) {
503
- const stripped = input.substring(stringPattern.length);
480
+ if (longestMatch > 0) {
481
+ const stripped = input.substring(longestMatch);
504
482
  if (ensureLeadingChar) {
505
483
  if (stripped === "") {
506
484
  return ensureLeadingChar;
@@ -509,8 +487,21 @@ function stripPrefix(input, pattern, ensureLeadingChar) {
509
487
  return `${ensureLeadingChar}${stripped}`;
510
488
  }
511
489
  }
512
- return stripped;
490
+ return stripped === "" && !ensureLeadingChar ? input : stripped;
491
+ }
492
+ return input;
493
+ }
494
+ if (input.startsWith(pattern)) {
495
+ const stripped = input.substring(pattern.length);
496
+ if (ensureLeadingChar) {
497
+ if (stripped === "") {
498
+ return ensureLeadingChar;
499
+ }
500
+ if (!stripped.startsWith(ensureLeadingChar)) {
501
+ return `${ensureLeadingChar}${stripped}`;
502
+ }
513
503
  }
504
+ return stripped;
514
505
  }
515
506
  return input;
516
507
  }
@@ -518,8 +509,7 @@ function stripPathPrefix(path, pattern) {
518
509
  if (!pattern) {
519
510
  return path;
520
511
  }
521
- const regex = patternToRegex(pattern);
522
- if (!regex) {
512
+ if (!isGlobPattern(pattern)) {
523
513
  let normalizedPattern = pattern.trim();
524
514
  if (!normalizedPattern.startsWith("/")) {
525
515
  normalizedPattern = `/${normalizedPattern}`;
@@ -529,10 +519,13 @@ function stripPathPrefix(path, pattern) {
529
519
  }
530
520
  return stripPrefix(path, normalizedPattern, "/");
531
521
  }
532
- return stripPrefix(path, regex, "/");
522
+ return stripPrefix(path, pattern, "/");
533
523
  }
534
524
 
535
525
  // src/utils/string-utils.ts
526
+ function escapePattern(str) {
527
+ return str.replace(/\//g, "\\/");
528
+ }
536
529
  function escapeJSDoc(str) {
537
530
  return str.replace(/\*\//g, "*\\/");
538
531
  }
@@ -570,11 +563,73 @@ function createTypeScriptLoader() {
570
563
  }
571
564
  };
572
565
  }
566
+
567
+ // src/validators/string-validator.ts
568
+ var PATTERN_CACHE = new LRUCache(1e3);
569
+ var DEFAULT_FORMAT_MAP = {
570
+ uuid: "z.uuid()",
571
+ email: "z.email()",
572
+ uri: "z.url()",
573
+ url: "z.url()",
574
+ "uri-reference": 'z.string().refine((val) => !/\\s/.test(val), { message: "Must be a valid URI reference" })',
575
+ hostname: 'z.string().refine((val) => /^(?=.{1,253}$)(?:(?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)*(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/.test(val), { message: "Must be a valid hostname" })',
576
+ byte: "z.base64()",
577
+ binary: "z.string()",
578
+ date: "z.iso.date()",
579
+ time: "z.iso.time()",
580
+ duration: 'z.string().refine((val) => /^P(?:(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?:\\d+H)?(?:\\d+M)?(?:\\d+(?:\\.\\d+)?S)?)?|\\d+W)$/.test(val) && !/^PT?$/.test(val), { message: "Must be a valid ISO 8601 duration" })',
581
+ ipv4: "z.ipv4()",
582
+ ipv6: "z.ipv6()",
583
+ emoji: "z.emoji()",
584
+ base64: "z.base64()",
585
+ base64url: "z.base64url()",
586
+ nanoid: "z.nanoid()",
587
+ cuid: "z.cuid()",
588
+ cuid2: "z.cuid2()",
589
+ ulid: "z.ulid()",
590
+ cidr: "z.cidrv4()",
591
+ // Default to v4
592
+ cidrv4: "z.cidrv4()",
593
+ cidrv6: "z.cidrv6()",
594
+ "json-pointer": 'z.string().refine((val) => val === "" || /^(\\/([^~/]|~0|~1)+)+$/.test(val), { message: "Must be a valid JSON Pointer (RFC 6901)" })',
595
+ "relative-json-pointer": 'z.string().refine((val) => /^(0|[1-9]\\d*)(#|(\\/([^~/]|~0|~1)+)*)$/.test(val), { message: "Must be a valid relative JSON Pointer" })'
596
+ };
597
+ var FORMAT_MAP = {
598
+ ...DEFAULT_FORMAT_MAP,
599
+ "date-time": "z.iso.datetime()"
600
+ };
601
+ function configureDateTimeFormat(pattern) {
602
+ if (!pattern) {
603
+ FORMAT_MAP["date-time"] = "z.iso.datetime()";
604
+ return;
605
+ }
606
+ const patternStr = pattern instanceof RegExp ? pattern.source : pattern;
607
+ if (patternStr === "") {
608
+ FORMAT_MAP["date-time"] = "z.iso.datetime()";
609
+ return;
610
+ }
611
+ try {
612
+ new RegExp(patternStr);
613
+ } catch (error) {
614
+ throw new Error(
615
+ `Invalid regular expression pattern for customDateTimeFormatRegex: ${patternStr}. ${error instanceof Error ? error.message : "Pattern is malformed"}`
616
+ );
617
+ }
618
+ const escapedPattern = escapePattern(patternStr);
619
+ FORMAT_MAP["date-time"] = `z.string().regex(/${escapedPattern}/)`;
620
+ }
621
+ function resetFormatMap() {
622
+ FORMAT_MAP = {
623
+ ...DEFAULT_FORMAT_MAP,
624
+ "date-time": "z.iso.datetime()"
625
+ };
626
+ }
573
627
  // Annotate the CommonJS export names for ESM import in node:
574
628
  0 && (module.exports = {
575
629
  LRUCache,
576
630
  OperationFiltersSchema,
577
631
  RequestResponseOptionsSchema,
632
+ configureDateTimeFormat,
578
633
  createFilterStatistics,
579
634
  createTypeScriptLoader,
580
635
  escapeJSDoc,
@@ -582,6 +637,7 @@ function createTypeScriptLoader() {
582
637
  formatConfigValidationError,
583
638
  formatFilterStatistics,
584
639
  getBatchExitCode,
640
+ resetFormatMap,
585
641
  shouldIncludeOperation,
586
642
  stripPathPrefix,
587
643
  stripPrefix,