@cerios/openapi-to-zod 1.2.0 → 1.3.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.
@@ -1,4 +1,4 @@
1
- import { E as ExecutionMode, d as OperationFilters } from './types--r0d47sd.mjs';
1
+ import { E as ExecutionMode, g as OperationFilters, f as OpenAPISpec, b as OpenAPIParameter, c as OpenAPIRequestBody, d as OpenAPIResponse, e as OpenAPISchema } from './types-DZ4Bw-D5.mjs';
2
2
  import { z } from 'zod';
3
3
  import { Loader } from 'cosmiconfig';
4
4
 
@@ -60,6 +60,11 @@ declare const RequestResponseOptionsSchema: z.ZodObject<{
60
60
  useDescribe: z.ZodOptional<z.ZodBoolean>;
61
61
  includeDescriptions: z.ZodOptional<z.ZodBoolean>;
62
62
  defaultNullable: z.ZodOptional<z.ZodBoolean>;
63
+ emptyObjectBehavior: z.ZodOptional<z.ZodEnum<{
64
+ strict: "strict";
65
+ loose: "loose";
66
+ record: "record";
67
+ }>>;
63
68
  }, z.core.$strict>;
64
69
  /**
65
70
  * @shared Base Zod schema for operation filters (without status codes)
@@ -99,6 +104,43 @@ type BaseOperationFilters = z.infer<typeof OperationFiltersSchema>;
99
104
  */
100
105
  declare function formatConfigValidationError(error: z.ZodError, filepath: string | undefined, configPath: string | undefined, additionalNotes?: string[]): string;
101
106
 
107
+ /**
108
+ * Content type utilities for determining response parsing methods
109
+ */
110
+ /**
111
+ * Result of content type analysis
112
+ */
113
+ interface ContentTypeParseResult {
114
+ /**
115
+ * The recommended parsing method
116
+ * - "json": Use response.json() for JSON content types
117
+ * - "text": Use response.text() for text-based content types
118
+ * - "body": Use response.body() for binary content types
119
+ */
120
+ method: "json" | "text" | "body";
121
+ /**
122
+ * Whether the content type was unknown and fallback was used
123
+ */
124
+ isUnknown: boolean;
125
+ }
126
+ /**
127
+ * Fallback parsing method for unknown content types
128
+ */
129
+ type FallbackContentTypeParsing = "json" | "text" | "body";
130
+ /**
131
+ * Determines the appropriate response parsing method based on content type
132
+ *
133
+ * Categories:
134
+ * - JSON: application/json, text/json, *+json suffix
135
+ * - Text: text/* (except text/json), application/xml, *+xml suffix, application/javascript
136
+ * - Binary: image/*, audio/*, video/*, font/*, application/octet-stream, application/pdf, etc.
137
+ *
138
+ * @param contentType - The content type to analyze (e.g., "application/json; charset=utf-8")
139
+ * @param fallback - The method to use for unknown content types (default: "text" for safety)
140
+ * @returns The recommended parsing method and whether the content type was unknown
141
+ */
142
+ declare function getResponseParseMethod(contentType: string | undefined, fallback?: FallbackContentTypeParsing): ContentTypeParseResult;
143
+
102
144
  /**
103
145
  * @shared Simple LRU Cache implementation for performance optimization
104
146
  * @since 1.0.0
@@ -226,6 +268,55 @@ declare function stripPrefix(input: string, pattern: string | undefined, ensureL
226
268
  */
227
269
  declare function stripPathPrefix(path: string, pattern: string | undefined): string;
228
270
 
271
+ /**
272
+ * OpenAPI $ref resolution utilities
273
+ *
274
+ * Provides functions to resolve $ref references to component definitions
275
+ * Supports: parameters, requestBodies, responses, schemas
276
+ *
277
+ * @internal Used by core and playwright packages
278
+ */
279
+
280
+ /**
281
+ * Type for any resolvable component
282
+ */
283
+ type ResolvableComponent = OpenAPIParameter | OpenAPIRequestBody | OpenAPIResponse | OpenAPISchema | any;
284
+ /**
285
+ * Resolve a $ref to a component definition
286
+ * Handles nested $refs by recursively resolving until no more refs found
287
+ *
288
+ * @param obj - Object that may contain a $ref
289
+ * @param spec - The OpenAPI specification
290
+ * @param maxDepth - Maximum recursion depth to prevent infinite loops (default: 10)
291
+ * @returns The resolved component, or the original object if not a reference
292
+ */
293
+ declare function resolveRef<T extends ResolvableComponent>(obj: T | any, spec: OpenAPISpec, maxDepth?: number): T;
294
+ /**
295
+ * Resolve a parameter reference
296
+ * Convenience wrapper for resolveRef with parameter type
297
+ */
298
+ declare function resolveParameterRef(param: any, spec: OpenAPISpec): OpenAPIParameter | any;
299
+ /**
300
+ * Resolve a request body reference
301
+ * Convenience wrapper for resolveRef with request body type
302
+ */
303
+ declare function resolveRequestBodyRef(requestBody: any, spec: OpenAPISpec): OpenAPIRequestBody | any;
304
+ /**
305
+ * Resolve a response reference
306
+ * Convenience wrapper for resolveRef with response type
307
+ */
308
+ declare function resolveResponseRef(response: any, spec: OpenAPISpec): OpenAPIResponse | any;
309
+ /**
310
+ * Merge path-level parameters with operation-level parameters
311
+ * Operation parameters override path-level parameters with the same name and location
312
+ *
313
+ * @param pathParams - Parameters defined at the path level
314
+ * @param operationParams - Parameters defined at the operation level
315
+ * @param spec - The OpenAPI specification for resolving $refs
316
+ * @returns Merged array of resolved parameters
317
+ */
318
+ declare function mergeParameters(pathParams: any[] | undefined, operationParams: any[] | undefined, spec: OpenAPISpec): any[];
319
+
229
320
  /**
230
321
  * String utility functions for escaping and formatting
231
322
  */
@@ -269,4 +360,4 @@ declare function configureDateTimeFormat(pattern?: string | RegExp): void;
269
360
  */
270
361
  declare function resetFormatMap(): void;
271
362
 
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 };
363
+ export { type BaseOperationFilters, type ContentTypeParseResult, type FallbackContentTypeParsing, type FilterStatistics, type Generator, LRUCache, OperationFiltersSchema, type RequestResponseOptions, RequestResponseOptionsSchema, configureDateTimeFormat, createFilterStatistics, createTypeScriptLoader, escapeJSDoc, executeBatch, formatConfigValidationError, formatFilterStatistics, getBatchExitCode, getResponseParseMethod, mergeParameters, resetFormatMap, resolveParameterRef, resolveRef, resolveRequestBodyRef, resolveResponseRef, shouldIncludeOperation, stripPathPrefix, stripPrefix, toCamelCase, toPascalCase, validateFilters };
@@ -1,4 +1,4 @@
1
- import { E as ExecutionMode, d as OperationFilters } from './types--r0d47sd.js';
1
+ import { E as ExecutionMode, g as OperationFilters, f as OpenAPISpec, b as OpenAPIParameter, c as OpenAPIRequestBody, d as OpenAPIResponse, e as OpenAPISchema } from './types-DZ4Bw-D5.js';
2
2
  import { z } from 'zod';
3
3
  import { Loader } from 'cosmiconfig';
4
4
 
@@ -60,6 +60,11 @@ declare const RequestResponseOptionsSchema: z.ZodObject<{
60
60
  useDescribe: z.ZodOptional<z.ZodBoolean>;
61
61
  includeDescriptions: z.ZodOptional<z.ZodBoolean>;
62
62
  defaultNullable: z.ZodOptional<z.ZodBoolean>;
63
+ emptyObjectBehavior: z.ZodOptional<z.ZodEnum<{
64
+ strict: "strict";
65
+ loose: "loose";
66
+ record: "record";
67
+ }>>;
63
68
  }, z.core.$strict>;
64
69
  /**
65
70
  * @shared Base Zod schema for operation filters (without status codes)
@@ -99,6 +104,43 @@ type BaseOperationFilters = z.infer<typeof OperationFiltersSchema>;
99
104
  */
100
105
  declare function formatConfigValidationError(error: z.ZodError, filepath: string | undefined, configPath: string | undefined, additionalNotes?: string[]): string;
101
106
 
107
+ /**
108
+ * Content type utilities for determining response parsing methods
109
+ */
110
+ /**
111
+ * Result of content type analysis
112
+ */
113
+ interface ContentTypeParseResult {
114
+ /**
115
+ * The recommended parsing method
116
+ * - "json": Use response.json() for JSON content types
117
+ * - "text": Use response.text() for text-based content types
118
+ * - "body": Use response.body() for binary content types
119
+ */
120
+ method: "json" | "text" | "body";
121
+ /**
122
+ * Whether the content type was unknown and fallback was used
123
+ */
124
+ isUnknown: boolean;
125
+ }
126
+ /**
127
+ * Fallback parsing method for unknown content types
128
+ */
129
+ type FallbackContentTypeParsing = "json" | "text" | "body";
130
+ /**
131
+ * Determines the appropriate response parsing method based on content type
132
+ *
133
+ * Categories:
134
+ * - JSON: application/json, text/json, *+json suffix
135
+ * - Text: text/* (except text/json), application/xml, *+xml suffix, application/javascript
136
+ * - Binary: image/*, audio/*, video/*, font/*, application/octet-stream, application/pdf, etc.
137
+ *
138
+ * @param contentType - The content type to analyze (e.g., "application/json; charset=utf-8")
139
+ * @param fallback - The method to use for unknown content types (default: "text" for safety)
140
+ * @returns The recommended parsing method and whether the content type was unknown
141
+ */
142
+ declare function getResponseParseMethod(contentType: string | undefined, fallback?: FallbackContentTypeParsing): ContentTypeParseResult;
143
+
102
144
  /**
103
145
  * @shared Simple LRU Cache implementation for performance optimization
104
146
  * @since 1.0.0
@@ -226,6 +268,55 @@ declare function stripPrefix(input: string, pattern: string | undefined, ensureL
226
268
  */
227
269
  declare function stripPathPrefix(path: string, pattern: string | undefined): string;
228
270
 
271
+ /**
272
+ * OpenAPI $ref resolution utilities
273
+ *
274
+ * Provides functions to resolve $ref references to component definitions
275
+ * Supports: parameters, requestBodies, responses, schemas
276
+ *
277
+ * @internal Used by core and playwright packages
278
+ */
279
+
280
+ /**
281
+ * Type for any resolvable component
282
+ */
283
+ type ResolvableComponent = OpenAPIParameter | OpenAPIRequestBody | OpenAPIResponse | OpenAPISchema | any;
284
+ /**
285
+ * Resolve a $ref to a component definition
286
+ * Handles nested $refs by recursively resolving until no more refs found
287
+ *
288
+ * @param obj - Object that may contain a $ref
289
+ * @param spec - The OpenAPI specification
290
+ * @param maxDepth - Maximum recursion depth to prevent infinite loops (default: 10)
291
+ * @returns The resolved component, or the original object if not a reference
292
+ */
293
+ declare function resolveRef<T extends ResolvableComponent>(obj: T | any, spec: OpenAPISpec, maxDepth?: number): T;
294
+ /**
295
+ * Resolve a parameter reference
296
+ * Convenience wrapper for resolveRef with parameter type
297
+ */
298
+ declare function resolveParameterRef(param: any, spec: OpenAPISpec): OpenAPIParameter | any;
299
+ /**
300
+ * Resolve a request body reference
301
+ * Convenience wrapper for resolveRef with request body type
302
+ */
303
+ declare function resolveRequestBodyRef(requestBody: any, spec: OpenAPISpec): OpenAPIRequestBody | any;
304
+ /**
305
+ * Resolve a response reference
306
+ * Convenience wrapper for resolveRef with response type
307
+ */
308
+ declare function resolveResponseRef(response: any, spec: OpenAPISpec): OpenAPIResponse | any;
309
+ /**
310
+ * Merge path-level parameters with operation-level parameters
311
+ * Operation parameters override path-level parameters with the same name and location
312
+ *
313
+ * @param pathParams - Parameters defined at the path level
314
+ * @param operationParams - Parameters defined at the operation level
315
+ * @param spec - The OpenAPI specification for resolving $refs
316
+ * @returns Merged array of resolved parameters
317
+ */
318
+ declare function mergeParameters(pathParams: any[] | undefined, operationParams: any[] | undefined, spec: OpenAPISpec): any[];
319
+
229
320
  /**
230
321
  * String utility functions for escaping and formatting
231
322
  */
@@ -269,4 +360,4 @@ declare function configureDateTimeFormat(pattern?: string | RegExp): void;
269
360
  */
270
361
  declare function resetFormatMap(): void;
271
362
 
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 };
363
+ export { type BaseOperationFilters, type ContentTypeParseResult, type FallbackContentTypeParsing, type FilterStatistics, type Generator, LRUCache, OperationFiltersSchema, type RequestResponseOptions, RequestResponseOptionsSchema, configureDateTimeFormat, createFilterStatistics, createTypeScriptLoader, escapeJSDoc, executeBatch, formatConfigValidationError, formatFilterStatistics, getBatchExitCode, getResponseParseMethod, mergeParameters, resetFormatMap, resolveParameterRef, resolveRef, resolveRequestBodyRef, resolveResponseRef, shouldIncludeOperation, stripPathPrefix, stripPrefix, toCamelCase, toPascalCase, validateFilters };
package/dist/internal.js CHANGED
@@ -41,7 +41,13 @@ __export(internal_exports, {
41
41
  formatConfigValidationError: () => formatConfigValidationError,
42
42
  formatFilterStatistics: () => formatFilterStatistics,
43
43
  getBatchExitCode: () => getBatchExitCode,
44
+ getResponseParseMethod: () => getResponseParseMethod,
45
+ mergeParameters: () => mergeParameters,
44
46
  resetFormatMap: () => resetFormatMap,
47
+ resolveParameterRef: () => resolveParameterRef,
48
+ resolveRef: () => resolveRef,
49
+ resolveRequestBodyRef: () => resolveRequestBodyRef,
50
+ resolveResponseRef: () => resolveResponseRef,
45
51
  shouldIncludeOperation: () => shouldIncludeOperation,
46
52
  stripPathPrefix: () => stripPathPrefix,
47
53
  stripPrefix: () => stripPrefix,
@@ -187,7 +193,8 @@ var RequestResponseOptionsSchema = import_zod.z.strictObject({
187
193
  mode: import_zod.z.enum(["strict", "normal", "loose"]).optional(),
188
194
  useDescribe: import_zod.z.boolean().optional(),
189
195
  includeDescriptions: import_zod.z.boolean().optional(),
190
- defaultNullable: import_zod.z.boolean().optional()
196
+ defaultNullable: import_zod.z.boolean().optional(),
197
+ emptyObjectBehavior: import_zod.z.enum(["strict", "loose", "record"]).optional()
191
198
  });
192
199
  var OperationFiltersSchema = import_zod.z.strictObject({
193
200
  includeTags: import_zod.z.array(import_zod.z.string()).optional(),
@@ -227,6 +234,45 @@ function formatConfigValidationError(error, filepath, configPath, additionalNote
227
234
  return lines.join("\n");
228
235
  }
229
236
 
237
+ // src/utils/content-type-utils.ts
238
+ function getResponseParseMethod(contentType, fallback = "text") {
239
+ if (!contentType) {
240
+ return { method: fallback, isUnknown: true };
241
+ }
242
+ const normalized = contentType.toLowerCase().split(";")[0].trim();
243
+ if (!normalized) {
244
+ return { method: fallback, isUnknown: true };
245
+ }
246
+ if (normalized === "application/json" || normalized === "text/json" || normalized.endsWith("+json")) {
247
+ return { method: "json", isUnknown: false };
248
+ }
249
+ if (normalized.startsWith("text/")) {
250
+ return { method: "text", isUnknown: false };
251
+ }
252
+ if (normalized === "application/xml" || normalized.endsWith("+xml")) {
253
+ return { method: "text", isUnknown: false };
254
+ }
255
+ if (normalized === "application/javascript" || normalized === "application/x-javascript" || normalized === "application/ecmascript") {
256
+ return { method: "text", isUnknown: false };
257
+ }
258
+ if (normalized.startsWith("image/")) {
259
+ return { method: "body", isUnknown: false };
260
+ }
261
+ if (normalized.startsWith("audio/")) {
262
+ return { method: "body", isUnknown: false };
263
+ }
264
+ if (normalized.startsWith("video/")) {
265
+ return { method: "body", isUnknown: false };
266
+ }
267
+ if (normalized.startsWith("font/")) {
268
+ return { method: "body", isUnknown: false };
269
+ }
270
+ if (normalized === "application/octet-stream" || normalized === "application/pdf" || normalized === "application/zip" || normalized === "application/gzip" || normalized === "application/x-tar" || normalized === "application/x-7z-compressed" || normalized === "application/x-rar-compressed" || normalized === "application/wasm" || normalized === "application/x-protobuf") {
271
+ return { method: "body", isUnknown: false };
272
+ }
273
+ return { method: fallback, isUnknown: true };
274
+ }
275
+
230
276
  // src/utils/lru-cache.ts
231
277
  var LRUCache = class {
232
278
  constructor(maxSize) {
@@ -282,12 +328,12 @@ function toCamelCase(str, options) {
282
328
  name = words[0].charAt(0).toLowerCase() + words[0].slice(1) + words.slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
283
329
  }
284
330
  if (options == null ? void 0 : options.prefix) {
285
- const prefix = options.prefix.toLowerCase();
331
+ const prefix = options.prefix.charAt(0).toLowerCase() + options.prefix.slice(1);
286
332
  name = prefix + name.charAt(0).toUpperCase() + name.slice(1);
287
333
  }
288
334
  if (options == null ? void 0 : options.suffix) {
289
- const suffix = options.suffix;
290
- name = name + suffix.charAt(0).toUpperCase() + suffix.slice(1).toLowerCase();
335
+ const suffix = options.suffix.charAt(0).toUpperCase() + options.suffix.slice(1);
336
+ name = name + suffix;
291
337
  }
292
338
  return name;
293
339
  }
@@ -522,6 +568,65 @@ function stripPathPrefix(path, pattern) {
522
568
  return stripPrefix(path, pattern, "/");
523
569
  }
524
570
 
571
+ // src/utils/ref-resolver.ts
572
+ function resolveRef(obj, spec, maxDepth = 10) {
573
+ var _a, _b, _c, _d;
574
+ if (!obj || typeof obj !== "object" || maxDepth <= 0) return obj;
575
+ if (!obj.$ref) return obj;
576
+ const ref = obj.$ref;
577
+ let resolved = null;
578
+ const paramMatch = ref.match(/^#\/components\/parameters\/(.+)$/);
579
+ const requestBodyMatch = ref.match(/^#\/components\/requestBodies\/(.+)$/);
580
+ const responseMatch = ref.match(/^#\/components\/responses\/(.+)$/);
581
+ const schemaMatch = ref.match(/^#\/components\/schemas\/(.+)$/);
582
+ if (paramMatch && ((_a = spec.components) == null ? void 0 : _a.parameters)) {
583
+ const name = paramMatch[1];
584
+ resolved = spec.components.parameters[name];
585
+ } else if (requestBodyMatch && ((_b = spec.components) == null ? void 0 : _b.requestBodies)) {
586
+ const name = requestBodyMatch[1];
587
+ resolved = spec.components.requestBodies[name];
588
+ } else if (responseMatch && ((_c = spec.components) == null ? void 0 : _c.responses)) {
589
+ const name = responseMatch[1];
590
+ resolved = spec.components.responses[name];
591
+ } else if (schemaMatch && ((_d = spec.components) == null ? void 0 : _d.schemas)) {
592
+ const name = schemaMatch[1];
593
+ resolved = spec.components.schemas[name];
594
+ }
595
+ if (resolved) {
596
+ if (resolved.$ref) {
597
+ return resolveRef(resolved, spec, maxDepth - 1);
598
+ }
599
+ return resolved;
600
+ }
601
+ return obj;
602
+ }
603
+ function resolveParameterRef(param, spec) {
604
+ return resolveRef(param, spec);
605
+ }
606
+ function resolveRequestBodyRef(requestBody, spec) {
607
+ return resolveRef(requestBody, spec);
608
+ }
609
+ function resolveResponseRef(response, spec) {
610
+ return resolveRef(response, spec);
611
+ }
612
+ function mergeParameters(pathParams, operationParams, spec) {
613
+ const resolvedPathParams = (pathParams || []).map((p) => resolveParameterRef(p, spec));
614
+ const resolvedOperationParams = (operationParams || []).map((p) => resolveParameterRef(p, spec));
615
+ const merged = [...resolvedPathParams];
616
+ for (const opParam of resolvedOperationParams) {
617
+ if (!opParam || typeof opParam !== "object") continue;
618
+ const existingIndex = merged.findIndex(
619
+ (p) => p && typeof p === "object" && p.name === opParam.name && p.in === opParam.in
620
+ );
621
+ if (existingIndex >= 0) {
622
+ merged[existingIndex] = opParam;
623
+ } else {
624
+ merged.push(opParam);
625
+ }
626
+ }
627
+ return merged;
628
+ }
629
+
525
630
  // src/utils/string-utils.ts
526
631
  function escapePattern(str) {
527
632
  return str.replace(/\//g, "\\/");
@@ -637,7 +742,13 @@ function resetFormatMap() {
637
742
  formatConfigValidationError,
638
743
  formatFilterStatistics,
639
744
  getBatchExitCode,
745
+ getResponseParseMethod,
746
+ mergeParameters,
640
747
  resetFormatMap,
748
+ resolveParameterRef,
749
+ resolveRef,
750
+ resolveRequestBodyRef,
751
+ resolveResponseRef,
641
752
  shouldIncludeOperation,
642
753
  stripPathPrefix,
643
754
  stripPrefix,