@cerios/openapi-to-zod 0.4.0 → 0.5.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/cli.js +268 -10
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +275 -11
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +150 -1
- package/dist/index.d.ts +150 -1
- package/dist/index.js +247 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +242 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -187,6 +187,98 @@ interface OpenApiGeneratorOptions {
|
|
|
187
187
|
* Always generates Zod schemas for runtime validation
|
|
188
188
|
*/
|
|
189
189
|
response?: ResponseOptions;
|
|
190
|
+
/**
|
|
191
|
+
* Filter which operations to include/exclude from generation
|
|
192
|
+
* Useful for generating separate schemas for different API subsets
|
|
193
|
+
*
|
|
194
|
+
* Filtering logic:
|
|
195
|
+
* 1. If no filters specified, all operations are included
|
|
196
|
+
* 2. Empty arrays are treated as "no constraint" (not as "exclude all")
|
|
197
|
+
* 3. Include filters are applied first (allowlist)
|
|
198
|
+
* 4. Exclude filters are applied second (blocklist)
|
|
199
|
+
* 5. Exclude rules always win over include rules
|
|
200
|
+
*
|
|
201
|
+
* Supports glob patterns for paths and operationIds (e.g., "/api/v1/**", "get*")
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* // Only generate schemas for user-related endpoints
|
|
205
|
+
* operationFilters: {
|
|
206
|
+
* includeTags: ["users"]
|
|
207
|
+
* }
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* // Generate only GET endpoints, excluding deprecated ones
|
|
211
|
+
* operationFilters: {
|
|
212
|
+
* includeMethods: ["get"],
|
|
213
|
+
* excludeDeprecated: true
|
|
214
|
+
* }
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* // Generate only v1 API endpoints
|
|
218
|
+
* operationFilters: {
|
|
219
|
+
* includePaths: ["/api/v1/**"]
|
|
220
|
+
* }
|
|
221
|
+
*/
|
|
222
|
+
operationFilters?: OperationFilters;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Operation filtering options
|
|
226
|
+
* Controls which operations from the OpenAPI spec are included in generation
|
|
227
|
+
*/
|
|
228
|
+
interface OperationFilters {
|
|
229
|
+
/**
|
|
230
|
+
* Include only operations with these tags
|
|
231
|
+
* If specified, only operations with at least one matching tag are included
|
|
232
|
+
* Empty array = no constraint
|
|
233
|
+
*/
|
|
234
|
+
includeTags?: string[];
|
|
235
|
+
/**
|
|
236
|
+
* Exclude operations with these tags
|
|
237
|
+
* Operations with any matching tag are excluded
|
|
238
|
+
* Empty array = no constraint
|
|
239
|
+
*/
|
|
240
|
+
excludeTags?: string[];
|
|
241
|
+
/**
|
|
242
|
+
* Include only operations matching these path patterns
|
|
243
|
+
* Supports glob patterns (e.g., "/users/**", "/api/v1/*")
|
|
244
|
+
* Empty array = no constraint
|
|
245
|
+
*/
|
|
246
|
+
includePaths?: string[];
|
|
247
|
+
/**
|
|
248
|
+
* Exclude operations matching these path patterns
|
|
249
|
+
* Supports glob patterns (e.g., "/internal/**", "/admin/*")
|
|
250
|
+
* Empty array = no constraint
|
|
251
|
+
*/
|
|
252
|
+
excludePaths?: string[];
|
|
253
|
+
/**
|
|
254
|
+
* Include only these HTTP methods
|
|
255
|
+
* Valid values: "get", "post", "put", "patch", "delete", "head", "options"
|
|
256
|
+
* Empty array = no constraint
|
|
257
|
+
*/
|
|
258
|
+
includeMethods?: string[];
|
|
259
|
+
/**
|
|
260
|
+
* Exclude these HTTP methods
|
|
261
|
+
* Valid values: "get", "post", "put", "patch", "delete", "head", "options"
|
|
262
|
+
* Empty array = no constraint
|
|
263
|
+
*/
|
|
264
|
+
excludeMethods?: string[];
|
|
265
|
+
/**
|
|
266
|
+
* Include only operations matching these operationId patterns
|
|
267
|
+
* Supports glob patterns (e.g., "getUser*", "*Admin")
|
|
268
|
+
* Empty array = no constraint
|
|
269
|
+
*/
|
|
270
|
+
includeOperationIds?: string[];
|
|
271
|
+
/**
|
|
272
|
+
* Exclude operations matching these operationId patterns
|
|
273
|
+
* Supports glob patterns (e.g., "deleteUser*", "*Internal")
|
|
274
|
+
* Empty array = no constraint
|
|
275
|
+
*/
|
|
276
|
+
excludeOperationIds?: string[];
|
|
277
|
+
/**
|
|
278
|
+
* Whether to exclude deprecated operations
|
|
279
|
+
* @default false
|
|
280
|
+
*/
|
|
281
|
+
excludeDeprecated?: boolean;
|
|
190
282
|
}
|
|
191
283
|
interface OpenAPISchema {
|
|
192
284
|
type?: string | string[];
|
|
@@ -311,6 +403,7 @@ declare class OpenApiGenerator {
|
|
|
311
403
|
private requestOptions;
|
|
312
404
|
private responseOptions;
|
|
313
405
|
private needsZodImport;
|
|
406
|
+
private filterStats;
|
|
314
407
|
constructor(options: OpenApiGeneratorOptions);
|
|
315
408
|
/**
|
|
316
409
|
* Generate schemas as a string (without writing to file)
|
|
@@ -377,6 +470,11 @@ declare class OpenApiGenerator {
|
|
|
377
470
|
* Generate query parameter schemas for each operation
|
|
378
471
|
*/
|
|
379
472
|
private generateQueryParameterSchemas;
|
|
473
|
+
/**
|
|
474
|
+
* Generate header parameter schemas for each operation
|
|
475
|
+
* Header parameters are always string type (HTTP header semantics)
|
|
476
|
+
*/
|
|
477
|
+
private generateHeaderParameterSchemas;
|
|
380
478
|
/**
|
|
381
479
|
* Generate Zod type for a query parameter schema
|
|
382
480
|
*/
|
|
@@ -412,4 +510,55 @@ declare class OpenApiGenerator {
|
|
|
412
510
|
private generateStats;
|
|
413
511
|
}
|
|
414
512
|
|
|
415
|
-
|
|
513
|
+
/**
|
|
514
|
+
* Filter statistics to track which operations were included/excluded
|
|
515
|
+
*/
|
|
516
|
+
interface FilterStatistics {
|
|
517
|
+
totalOperations: number;
|
|
518
|
+
includedOperations: number;
|
|
519
|
+
filteredByTags: number;
|
|
520
|
+
filteredByPaths: number;
|
|
521
|
+
filteredByMethods: number;
|
|
522
|
+
filteredByOperationIds: number;
|
|
523
|
+
filteredByDeprecated: number;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Create a new filter statistics object with all counters initialized to zero
|
|
527
|
+
*/
|
|
528
|
+
declare function createFilterStatistics(): FilterStatistics;
|
|
529
|
+
/**
|
|
530
|
+
* Determine if an operation should be included based on filter criteria
|
|
531
|
+
*
|
|
532
|
+
* Filter logic:
|
|
533
|
+
* 1. If no filters specified, include all operations
|
|
534
|
+
* 2. Empty arrays are treated as "no constraint" (not as "exclude all")
|
|
535
|
+
* 3. Include filters are applied first (allowlist)
|
|
536
|
+
* 4. Exclude filters are applied second (blocklist)
|
|
537
|
+
* 5. Exclude rules always win over include rules
|
|
538
|
+
*
|
|
539
|
+
* @param operation - The OpenAPI operation object
|
|
540
|
+
* @param path - The operation path (e.g., "/users/{id}")
|
|
541
|
+
* @param method - The HTTP method (e.g., "get", "post")
|
|
542
|
+
* @param filters - Optional filter configuration
|
|
543
|
+
* @param stats - Optional statistics object to track filtering reasons
|
|
544
|
+
* @returns true if the operation should be included, false otherwise
|
|
545
|
+
*/
|
|
546
|
+
declare function shouldIncludeOperation(operation: any, path: string, method: string, filters?: OperationFilters, stats?: FilterStatistics): boolean;
|
|
547
|
+
/**
|
|
548
|
+
* Validate filter statistics and emit warnings for filters that matched nothing
|
|
549
|
+
* Helps users debug filter configurations that might be too restrictive or contain typos
|
|
550
|
+
*
|
|
551
|
+
* @param stats - Filter statistics object
|
|
552
|
+
* @param filters - The filter configuration to validate
|
|
553
|
+
*/
|
|
554
|
+
declare function validateFilters(stats: FilterStatistics, filters?: OperationFilters): void;
|
|
555
|
+
/**
|
|
556
|
+
* Format filter statistics for display in generated output
|
|
557
|
+
* Returns a formatted string suitable for inclusion in comments
|
|
558
|
+
*
|
|
559
|
+
* @param stats - Filter statistics object
|
|
560
|
+
* @returns Formatted statistics string
|
|
561
|
+
*/
|
|
562
|
+
declare function formatFilterStatistics(stats: FilterStatistics): string;
|
|
563
|
+
|
|
564
|
+
export { CircularReferenceError, CliOptionsError, type ConfigFile, ConfigValidationError, type ExecutionMode, FileOperationError, type FilterStatistics, GeneratorError, type OpenAPISpec, OpenApiGenerator, type OpenApiGeneratorOptions, type OperationFilters, SchemaGenerationError, SpecValidationError, createFilterStatistics, defineConfig, formatFilterStatistics, shouldIncludeOperation, validateFilters };
|
package/dist/index.d.ts
CHANGED
|
@@ -187,6 +187,98 @@ interface OpenApiGeneratorOptions {
|
|
|
187
187
|
* Always generates Zod schemas for runtime validation
|
|
188
188
|
*/
|
|
189
189
|
response?: ResponseOptions;
|
|
190
|
+
/**
|
|
191
|
+
* Filter which operations to include/exclude from generation
|
|
192
|
+
* Useful for generating separate schemas for different API subsets
|
|
193
|
+
*
|
|
194
|
+
* Filtering logic:
|
|
195
|
+
* 1. If no filters specified, all operations are included
|
|
196
|
+
* 2. Empty arrays are treated as "no constraint" (not as "exclude all")
|
|
197
|
+
* 3. Include filters are applied first (allowlist)
|
|
198
|
+
* 4. Exclude filters are applied second (blocklist)
|
|
199
|
+
* 5. Exclude rules always win over include rules
|
|
200
|
+
*
|
|
201
|
+
* Supports glob patterns for paths and operationIds (e.g., "/api/v1/**", "get*")
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* // Only generate schemas for user-related endpoints
|
|
205
|
+
* operationFilters: {
|
|
206
|
+
* includeTags: ["users"]
|
|
207
|
+
* }
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* // Generate only GET endpoints, excluding deprecated ones
|
|
211
|
+
* operationFilters: {
|
|
212
|
+
* includeMethods: ["get"],
|
|
213
|
+
* excludeDeprecated: true
|
|
214
|
+
* }
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* // Generate only v1 API endpoints
|
|
218
|
+
* operationFilters: {
|
|
219
|
+
* includePaths: ["/api/v1/**"]
|
|
220
|
+
* }
|
|
221
|
+
*/
|
|
222
|
+
operationFilters?: OperationFilters;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Operation filtering options
|
|
226
|
+
* Controls which operations from the OpenAPI spec are included in generation
|
|
227
|
+
*/
|
|
228
|
+
interface OperationFilters {
|
|
229
|
+
/**
|
|
230
|
+
* Include only operations with these tags
|
|
231
|
+
* If specified, only operations with at least one matching tag are included
|
|
232
|
+
* Empty array = no constraint
|
|
233
|
+
*/
|
|
234
|
+
includeTags?: string[];
|
|
235
|
+
/**
|
|
236
|
+
* Exclude operations with these tags
|
|
237
|
+
* Operations with any matching tag are excluded
|
|
238
|
+
* Empty array = no constraint
|
|
239
|
+
*/
|
|
240
|
+
excludeTags?: string[];
|
|
241
|
+
/**
|
|
242
|
+
* Include only operations matching these path patterns
|
|
243
|
+
* Supports glob patterns (e.g., "/users/**", "/api/v1/*")
|
|
244
|
+
* Empty array = no constraint
|
|
245
|
+
*/
|
|
246
|
+
includePaths?: string[];
|
|
247
|
+
/**
|
|
248
|
+
* Exclude operations matching these path patterns
|
|
249
|
+
* Supports glob patterns (e.g., "/internal/**", "/admin/*")
|
|
250
|
+
* Empty array = no constraint
|
|
251
|
+
*/
|
|
252
|
+
excludePaths?: string[];
|
|
253
|
+
/**
|
|
254
|
+
* Include only these HTTP methods
|
|
255
|
+
* Valid values: "get", "post", "put", "patch", "delete", "head", "options"
|
|
256
|
+
* Empty array = no constraint
|
|
257
|
+
*/
|
|
258
|
+
includeMethods?: string[];
|
|
259
|
+
/**
|
|
260
|
+
* Exclude these HTTP methods
|
|
261
|
+
* Valid values: "get", "post", "put", "patch", "delete", "head", "options"
|
|
262
|
+
* Empty array = no constraint
|
|
263
|
+
*/
|
|
264
|
+
excludeMethods?: string[];
|
|
265
|
+
/**
|
|
266
|
+
* Include only operations matching these operationId patterns
|
|
267
|
+
* Supports glob patterns (e.g., "getUser*", "*Admin")
|
|
268
|
+
* Empty array = no constraint
|
|
269
|
+
*/
|
|
270
|
+
includeOperationIds?: string[];
|
|
271
|
+
/**
|
|
272
|
+
* Exclude operations matching these operationId patterns
|
|
273
|
+
* Supports glob patterns (e.g., "deleteUser*", "*Internal")
|
|
274
|
+
* Empty array = no constraint
|
|
275
|
+
*/
|
|
276
|
+
excludeOperationIds?: string[];
|
|
277
|
+
/**
|
|
278
|
+
* Whether to exclude deprecated operations
|
|
279
|
+
* @default false
|
|
280
|
+
*/
|
|
281
|
+
excludeDeprecated?: boolean;
|
|
190
282
|
}
|
|
191
283
|
interface OpenAPISchema {
|
|
192
284
|
type?: string | string[];
|
|
@@ -311,6 +403,7 @@ declare class OpenApiGenerator {
|
|
|
311
403
|
private requestOptions;
|
|
312
404
|
private responseOptions;
|
|
313
405
|
private needsZodImport;
|
|
406
|
+
private filterStats;
|
|
314
407
|
constructor(options: OpenApiGeneratorOptions);
|
|
315
408
|
/**
|
|
316
409
|
* Generate schemas as a string (without writing to file)
|
|
@@ -377,6 +470,11 @@ declare class OpenApiGenerator {
|
|
|
377
470
|
* Generate query parameter schemas for each operation
|
|
378
471
|
*/
|
|
379
472
|
private generateQueryParameterSchemas;
|
|
473
|
+
/**
|
|
474
|
+
* Generate header parameter schemas for each operation
|
|
475
|
+
* Header parameters are always string type (HTTP header semantics)
|
|
476
|
+
*/
|
|
477
|
+
private generateHeaderParameterSchemas;
|
|
380
478
|
/**
|
|
381
479
|
* Generate Zod type for a query parameter schema
|
|
382
480
|
*/
|
|
@@ -412,4 +510,55 @@ declare class OpenApiGenerator {
|
|
|
412
510
|
private generateStats;
|
|
413
511
|
}
|
|
414
512
|
|
|
415
|
-
|
|
513
|
+
/**
|
|
514
|
+
* Filter statistics to track which operations were included/excluded
|
|
515
|
+
*/
|
|
516
|
+
interface FilterStatistics {
|
|
517
|
+
totalOperations: number;
|
|
518
|
+
includedOperations: number;
|
|
519
|
+
filteredByTags: number;
|
|
520
|
+
filteredByPaths: number;
|
|
521
|
+
filteredByMethods: number;
|
|
522
|
+
filteredByOperationIds: number;
|
|
523
|
+
filteredByDeprecated: number;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Create a new filter statistics object with all counters initialized to zero
|
|
527
|
+
*/
|
|
528
|
+
declare function createFilterStatistics(): FilterStatistics;
|
|
529
|
+
/**
|
|
530
|
+
* Determine if an operation should be included based on filter criteria
|
|
531
|
+
*
|
|
532
|
+
* Filter logic:
|
|
533
|
+
* 1. If no filters specified, include all operations
|
|
534
|
+
* 2. Empty arrays are treated as "no constraint" (not as "exclude all")
|
|
535
|
+
* 3. Include filters are applied first (allowlist)
|
|
536
|
+
* 4. Exclude filters are applied second (blocklist)
|
|
537
|
+
* 5. Exclude rules always win over include rules
|
|
538
|
+
*
|
|
539
|
+
* @param operation - The OpenAPI operation object
|
|
540
|
+
* @param path - The operation path (e.g., "/users/{id}")
|
|
541
|
+
* @param method - The HTTP method (e.g., "get", "post")
|
|
542
|
+
* @param filters - Optional filter configuration
|
|
543
|
+
* @param stats - Optional statistics object to track filtering reasons
|
|
544
|
+
* @returns true if the operation should be included, false otherwise
|
|
545
|
+
*/
|
|
546
|
+
declare function shouldIncludeOperation(operation: any, path: string, method: string, filters?: OperationFilters, stats?: FilterStatistics): boolean;
|
|
547
|
+
/**
|
|
548
|
+
* Validate filter statistics and emit warnings for filters that matched nothing
|
|
549
|
+
* Helps users debug filter configurations that might be too restrictive or contain typos
|
|
550
|
+
*
|
|
551
|
+
* @param stats - Filter statistics object
|
|
552
|
+
* @param filters - The filter configuration to validate
|
|
553
|
+
*/
|
|
554
|
+
declare function validateFilters(stats: FilterStatistics, filters?: OperationFilters): void;
|
|
555
|
+
/**
|
|
556
|
+
* Format filter statistics for display in generated output
|
|
557
|
+
* Returns a formatted string suitable for inclusion in comments
|
|
558
|
+
*
|
|
559
|
+
* @param stats - Filter statistics object
|
|
560
|
+
* @returns Formatted statistics string
|
|
561
|
+
*/
|
|
562
|
+
declare function formatFilterStatistics(stats: FilterStatistics): string;
|
|
563
|
+
|
|
564
|
+
export { CircularReferenceError, CliOptionsError, type ConfigFile, ConfigValidationError, type ExecutionMode, FileOperationError, type FilterStatistics, GeneratorError, type OpenAPISpec, OpenApiGenerator, type OpenApiGeneratorOptions, type OperationFilters, SchemaGenerationError, SpecValidationError, createFilterStatistics, defineConfig, formatFilterStatistics, shouldIncludeOperation, validateFilters };
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,11 @@ __export(src_exports, {
|
|
|
28
28
|
OpenApiGenerator: () => OpenApiGenerator,
|
|
29
29
|
SchemaGenerationError: () => SchemaGenerationError,
|
|
30
30
|
SpecValidationError: () => SpecValidationError,
|
|
31
|
-
|
|
31
|
+
createFilterStatistics: () => createFilterStatistics,
|
|
32
|
+
defineConfig: () => defineConfig,
|
|
33
|
+
formatFilterStatistics: () => formatFilterStatistics,
|
|
34
|
+
shouldIncludeOperation: () => shouldIncludeOperation,
|
|
35
|
+
validateFilters: () => validateFilters
|
|
32
36
|
});
|
|
33
37
|
module.exports = __toCommonJS(src_exports);
|
|
34
38
|
|
|
@@ -1279,6 +1283,140 @@ _PropertyGenerator.INCLUSION_RULES = {
|
|
|
1279
1283
|
};
|
|
1280
1284
|
var PropertyGenerator = _PropertyGenerator;
|
|
1281
1285
|
|
|
1286
|
+
// src/utils/operation-filters.ts
|
|
1287
|
+
var import_minimatch = require("minimatch");
|
|
1288
|
+
function createFilterStatistics() {
|
|
1289
|
+
return {
|
|
1290
|
+
totalOperations: 0,
|
|
1291
|
+
includedOperations: 0,
|
|
1292
|
+
filteredByTags: 0,
|
|
1293
|
+
filteredByPaths: 0,
|
|
1294
|
+
filteredByMethods: 0,
|
|
1295
|
+
filteredByOperationIds: 0,
|
|
1296
|
+
filteredByDeprecated: 0
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
function matchesAnyPattern(value, patterns) {
|
|
1300
|
+
if (!patterns || patterns.length === 0) {
|
|
1301
|
+
return false;
|
|
1302
|
+
}
|
|
1303
|
+
if (!value) {
|
|
1304
|
+
return false;
|
|
1305
|
+
}
|
|
1306
|
+
return patterns.some((pattern) => (0, import_minimatch.minimatch)(value, pattern));
|
|
1307
|
+
}
|
|
1308
|
+
function containsAny(arr, values) {
|
|
1309
|
+
if (!values || values.length === 0) {
|
|
1310
|
+
return false;
|
|
1311
|
+
}
|
|
1312
|
+
if (!arr || arr.length === 0) {
|
|
1313
|
+
return false;
|
|
1314
|
+
}
|
|
1315
|
+
return values.some((value) => arr.includes(value));
|
|
1316
|
+
}
|
|
1317
|
+
function shouldIncludeOperation(operation, path, method, filters, stats) {
|
|
1318
|
+
if (!filters) {
|
|
1319
|
+
return true;
|
|
1320
|
+
}
|
|
1321
|
+
const methodLower = method.toLowerCase();
|
|
1322
|
+
const operationId = operation == null ? void 0 : operation.operationId;
|
|
1323
|
+
const tags = (operation == null ? void 0 : operation.tags) || [];
|
|
1324
|
+
const deprecated = (operation == null ? void 0 : operation.deprecated) === true;
|
|
1325
|
+
if (filters.includeTags && filters.includeTags.length > 0) {
|
|
1326
|
+
if (!containsAny(tags, filters.includeTags)) {
|
|
1327
|
+
if (stats) stats.filteredByTags++;
|
|
1328
|
+
return false;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
if (filters.includePaths && filters.includePaths.length > 0) {
|
|
1332
|
+
if (!matchesAnyPattern(path, filters.includePaths)) {
|
|
1333
|
+
if (stats) stats.filteredByPaths++;
|
|
1334
|
+
return false;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
if (filters.includeMethods && filters.includeMethods.length > 0) {
|
|
1338
|
+
const methodsLower = filters.includeMethods.map((m) => m.toLowerCase());
|
|
1339
|
+
if (!methodsLower.includes(methodLower)) {
|
|
1340
|
+
if (stats) stats.filteredByMethods++;
|
|
1341
|
+
return false;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
if (filters.includeOperationIds && filters.includeOperationIds.length > 0) {
|
|
1345
|
+
if (!matchesAnyPattern(operationId, filters.includeOperationIds)) {
|
|
1346
|
+
if (stats) stats.filteredByOperationIds++;
|
|
1347
|
+
return false;
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
if (filters.excludeDeprecated === true && deprecated) {
|
|
1351
|
+
if (stats) stats.filteredByDeprecated++;
|
|
1352
|
+
return false;
|
|
1353
|
+
}
|
|
1354
|
+
if (filters.excludeTags && filters.excludeTags.length > 0) {
|
|
1355
|
+
if (containsAny(tags, filters.excludeTags)) {
|
|
1356
|
+
if (stats) stats.filteredByTags++;
|
|
1357
|
+
return false;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
if (filters.excludePaths && filters.excludePaths.length > 0) {
|
|
1361
|
+
if (matchesAnyPattern(path, filters.excludePaths)) {
|
|
1362
|
+
if (stats) stats.filteredByPaths++;
|
|
1363
|
+
return false;
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
if (filters.excludeMethods && filters.excludeMethods.length > 0) {
|
|
1367
|
+
const methodsLower = filters.excludeMethods.map((m) => m.toLowerCase());
|
|
1368
|
+
if (methodsLower.includes(methodLower)) {
|
|
1369
|
+
if (stats) stats.filteredByMethods++;
|
|
1370
|
+
return false;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
if (filters.excludeOperationIds && filters.excludeOperationIds.length > 0) {
|
|
1374
|
+
if (matchesAnyPattern(operationId, filters.excludeOperationIds)) {
|
|
1375
|
+
if (stats) stats.filteredByOperationIds++;
|
|
1376
|
+
return false;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
return true;
|
|
1380
|
+
}
|
|
1381
|
+
function validateFilters(stats, filters) {
|
|
1382
|
+
if (!filters || stats.totalOperations === 0) {
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
if (stats.includedOperations === 0) {
|
|
1386
|
+
console.warn(
|
|
1387
|
+
`\u26A0\uFE0F Warning: All ${stats.totalOperations} operations were filtered out. Check your operationFilters configuration.`
|
|
1388
|
+
);
|
|
1389
|
+
const filterBreakdown = [];
|
|
1390
|
+
if (stats.filteredByTags > 0) filterBreakdown.push(`${stats.filteredByTags} by tags`);
|
|
1391
|
+
if (stats.filteredByPaths > 0) filterBreakdown.push(`${stats.filteredByPaths} by paths`);
|
|
1392
|
+
if (stats.filteredByMethods > 0) filterBreakdown.push(`${stats.filteredByMethods} by methods`);
|
|
1393
|
+
if (stats.filteredByOperationIds > 0) filterBreakdown.push(`${stats.filteredByOperationIds} by operationIds`);
|
|
1394
|
+
if (stats.filteredByDeprecated > 0) filterBreakdown.push(`${stats.filteredByDeprecated} by deprecated flag`);
|
|
1395
|
+
if (filterBreakdown.length > 0) {
|
|
1396
|
+
console.warn(` Filtered: ${filterBreakdown.join(", ")}`);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
function formatFilterStatistics(stats) {
|
|
1401
|
+
if (stats.totalOperations === 0) {
|
|
1402
|
+
return "";
|
|
1403
|
+
}
|
|
1404
|
+
const lines = [];
|
|
1405
|
+
lines.push("Operation Filtering:");
|
|
1406
|
+
lines.push(` Total operations: ${stats.totalOperations}`);
|
|
1407
|
+
lines.push(` Included operations: ${stats.includedOperations}`);
|
|
1408
|
+
const filteredCount = stats.filteredByTags + stats.filteredByPaths + stats.filteredByMethods + stats.filteredByOperationIds + stats.filteredByDeprecated;
|
|
1409
|
+
if (filteredCount > 0) {
|
|
1410
|
+
lines.push(` Filtered operations: ${filteredCount}`);
|
|
1411
|
+
if (stats.filteredByTags > 0) lines.push(` - By tags: ${stats.filteredByTags}`);
|
|
1412
|
+
if (stats.filteredByPaths > 0) lines.push(` - By paths: ${stats.filteredByPaths}`);
|
|
1413
|
+
if (stats.filteredByMethods > 0) lines.push(` - By methods: ${stats.filteredByMethods}`);
|
|
1414
|
+
if (stats.filteredByOperationIds > 0) lines.push(` - By operationIds: ${stats.filteredByOperationIds}`);
|
|
1415
|
+
if (stats.filteredByDeprecated > 0) lines.push(` - By deprecated: ${stats.filteredByDeprecated}`);
|
|
1416
|
+
}
|
|
1417
|
+
return lines.join("\n");
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1282
1420
|
// src/openapi-generator.ts
|
|
1283
1421
|
var OpenApiGenerator = class {
|
|
1284
1422
|
constructor(options) {
|
|
@@ -1290,6 +1428,7 @@ var OpenApiGenerator = class {
|
|
|
1290
1428
|
this.schemaUsageMap = /* @__PURE__ */ new Map();
|
|
1291
1429
|
this.schemaTypeModeMap = /* @__PURE__ */ new Map();
|
|
1292
1430
|
this.needsZodImport = false;
|
|
1431
|
+
this.filterStats = createFilterStatistics();
|
|
1293
1432
|
var _a, _b, _c;
|
|
1294
1433
|
if (!options.input) {
|
|
1295
1434
|
throw new ConfigurationError("Input path is required", { providedOptions: options });
|
|
@@ -1307,7 +1446,8 @@ var OpenApiGenerator = class {
|
|
|
1307
1446
|
showStats: (_c = options.showStats) != null ? _c : true,
|
|
1308
1447
|
nativeEnumType: options.nativeEnumType || "union",
|
|
1309
1448
|
request: options.request,
|
|
1310
|
-
response: options.response
|
|
1449
|
+
response: options.response,
|
|
1450
|
+
operationFilters: options.operationFilters
|
|
1311
1451
|
};
|
|
1312
1452
|
try {
|
|
1313
1453
|
const fs = require("fs");
|
|
@@ -1412,6 +1552,8 @@ var OpenApiGenerator = class {
|
|
|
1412
1552
|
this.generateComponentSchema(name, schema);
|
|
1413
1553
|
}
|
|
1414
1554
|
this.generateQueryParameterSchemas();
|
|
1555
|
+
this.generateHeaderParameterSchemas();
|
|
1556
|
+
validateFilters(this.filterStats, this.options.operationFilters);
|
|
1415
1557
|
const orderedSchemaNames = this.topologicalSort();
|
|
1416
1558
|
const output = ["// Auto-generated by @cerios/openapi-to-zod", "// Do not edit this file manually", ""];
|
|
1417
1559
|
if (this.options.showStats === true) {
|
|
@@ -1505,9 +1647,16 @@ var OpenApiGenerator = class {
|
|
|
1505
1647
|
const requestSchemas = /* @__PURE__ */ new Set();
|
|
1506
1648
|
const responseSchemas = /* @__PURE__ */ new Set();
|
|
1507
1649
|
if (this.spec.paths) {
|
|
1508
|
-
for (const [, pathItem] of Object.entries(this.spec.paths)) {
|
|
1509
|
-
|
|
1650
|
+
for (const [path, pathItem] of Object.entries(this.spec.paths)) {
|
|
1651
|
+
const methods = ["get", "post", "put", "patch", "delete", "head", "options"];
|
|
1652
|
+
for (const method of methods) {
|
|
1653
|
+
const operation = pathItem[method];
|
|
1510
1654
|
if (typeof operation !== "object" || !operation) continue;
|
|
1655
|
+
this.filterStats.totalOperations++;
|
|
1656
|
+
if (!shouldIncludeOperation(operation, path, method, this.options.operationFilters, this.filterStats)) {
|
|
1657
|
+
continue;
|
|
1658
|
+
}
|
|
1659
|
+
this.filterStats.includedOperations++;
|
|
1511
1660
|
if ("requestBody" in operation && operation.requestBody && typeof operation.requestBody === "object" && "content" in operation.requestBody && operation.requestBody.content) {
|
|
1512
1661
|
for (const mediaType of Object.values(operation.requestBody.content)) {
|
|
1513
1662
|
if (mediaType && typeof mediaType === "object" && "schema" in mediaType && mediaType.schema) {
|
|
@@ -1857,12 +2006,15 @@ ${typeCode}`;
|
|
|
1857
2006
|
if (!this.spec.paths) {
|
|
1858
2007
|
return;
|
|
1859
2008
|
}
|
|
1860
|
-
for (const [
|
|
2009
|
+
for (const [path, pathItem] of Object.entries(this.spec.paths)) {
|
|
1861
2010
|
if (!pathItem || typeof pathItem !== "object") continue;
|
|
1862
2011
|
const methods = ["get", "post", "put", "patch", "delete", "head", "options"];
|
|
1863
2012
|
for (const method of methods) {
|
|
1864
2013
|
const operation = pathItem[method];
|
|
1865
2014
|
if (!operation) continue;
|
|
2015
|
+
if (!shouldIncludeOperation(operation, path, method, this.options.operationFilters)) {
|
|
2016
|
+
continue;
|
|
2017
|
+
}
|
|
1866
2018
|
if (!operation.operationId || !operation.parameters || !Array.isArray(operation.parameters)) {
|
|
1867
2019
|
continue;
|
|
1868
2020
|
}
|
|
@@ -1923,6 +2075,80 @@ ${propsCode}
|
|
|
1923
2075
|
const jsdoc = `/**
|
|
1924
2076
|
* Query parameters for ${operation.operationId}
|
|
1925
2077
|
*/
|
|
2078
|
+
`;
|
|
2079
|
+
const fullSchemaCode = `${jsdoc}export const ${camelCaseSchemaName} = ${schemaCode};`;
|
|
2080
|
+
this.schemas.set(schemaName, fullSchemaCode);
|
|
2081
|
+
this.needsZodImport = true;
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
/**
|
|
2086
|
+
* Generate header parameter schemas for each operation
|
|
2087
|
+
* Header parameters are always string type (HTTP header semantics)
|
|
2088
|
+
*/
|
|
2089
|
+
generateHeaderParameterSchemas() {
|
|
2090
|
+
var _a;
|
|
2091
|
+
if (!this.spec.paths) {
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
for (const [path, pathItem] of Object.entries(this.spec.paths)) {
|
|
2095
|
+
if (!pathItem || typeof pathItem !== "object") continue;
|
|
2096
|
+
const methods = ["get", "post", "put", "patch", "delete", "head", "options"];
|
|
2097
|
+
for (const method of methods) {
|
|
2098
|
+
const operation = pathItem[method];
|
|
2099
|
+
if (!operation) continue;
|
|
2100
|
+
if (!shouldIncludeOperation(operation, path, method, this.options.operationFilters)) {
|
|
2101
|
+
continue;
|
|
2102
|
+
}
|
|
2103
|
+
if (!operation.operationId || !operation.parameters || !Array.isArray(operation.parameters)) {
|
|
2104
|
+
continue;
|
|
2105
|
+
}
|
|
2106
|
+
const headerParams = operation.parameters.filter(
|
|
2107
|
+
(param) => param && typeof param === "object" && param.in === "header"
|
|
2108
|
+
);
|
|
2109
|
+
if (headerParams.length === 0) {
|
|
2110
|
+
continue;
|
|
2111
|
+
}
|
|
2112
|
+
const pascalOperationId = operation.operationId.includes("-") ? toPascalCase(operation.operationId) : operation.operationId.charAt(0).toUpperCase() + operation.operationId.slice(1);
|
|
2113
|
+
const schemaName = `${pascalOperationId}HeaderParams`;
|
|
2114
|
+
if (!this.schemaDependencies.has(schemaName)) {
|
|
2115
|
+
this.schemaDependencies.set(schemaName, /* @__PURE__ */ new Set());
|
|
2116
|
+
}
|
|
2117
|
+
const properties = {};
|
|
2118
|
+
for (const param of headerParams) {
|
|
2119
|
+
const paramName = param.name;
|
|
2120
|
+
const paramSchema = param.schema;
|
|
2121
|
+
if (!paramSchema) continue;
|
|
2122
|
+
let zodType = "z.string()";
|
|
2123
|
+
if (param.description && this.requestOptions.includeDescriptions) {
|
|
2124
|
+
if (this.requestOptions.useDescribe) {
|
|
2125
|
+
zodType = `${zodType}.describe(${JSON.stringify(param.description)})`;
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
zodType = `${zodType}.optional()`;
|
|
2129
|
+
properties[paramName] = zodType;
|
|
2130
|
+
if (paramSchema.$ref) {
|
|
2131
|
+
const refName = resolveRef(paramSchema.$ref);
|
|
2132
|
+
(_a = this.schemaDependencies.get(schemaName)) == null ? void 0 : _a.add(refName);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
const objectMode = this.requestOptions.mode;
|
|
2136
|
+
const zodMethod = objectMode === "strict" ? "strictObject" : objectMode === "loose" ? "looseObject" : "object";
|
|
2137
|
+
const propsCode = Object.entries(properties).map(([key, value]) => {
|
|
2138
|
+
const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key);
|
|
2139
|
+
const quotedKey = needsQuotes ? `"${key}"` : key;
|
|
2140
|
+
return ` ${quotedKey}: ${value}`;
|
|
2141
|
+
}).join(",\n");
|
|
2142
|
+
const schemaCode = `z.${zodMethod}({
|
|
2143
|
+
${propsCode}
|
|
2144
|
+
})`;
|
|
2145
|
+
const operationName = pascalOperationId;
|
|
2146
|
+
const prefixedName = this.options.prefix ? `${toPascalCase(this.options.prefix)}${operationName}` : operationName;
|
|
2147
|
+
const suffixedName = this.options.suffix ? `${prefixedName}${toPascalCase(this.options.suffix)}` : prefixedName;
|
|
2148
|
+
const camelCaseSchemaName = `${suffixedName.charAt(0).toLowerCase() + suffixedName.slice(1)}HeaderParamsSchema`;
|
|
2149
|
+
const jsdoc = `/**
|
|
2150
|
+
* Header parameters for ${operation.operationId}
|
|
2151
|
+
*/
|
|
1926
2152
|
`;
|
|
1927
2153
|
const fullSchemaCode = `${jsdoc}export const ${camelCaseSchemaName} = ${schemaCode};`;
|
|
1928
2154
|
this.schemas.set(schemaName, fullSchemaCode);
|
|
@@ -2200,15 +2426,23 @@ ${props.join("\n")}
|
|
|
2200
2426
|
stats.withConstraints++;
|
|
2201
2427
|
}
|
|
2202
2428
|
}
|
|
2203
|
-
|
|
2429
|
+
const output = [
|
|
2204
2430
|
"// Generation Statistics:",
|
|
2205
2431
|
`// Total schemas: ${stats.totalSchemas}`,
|
|
2206
2432
|
`// Enums: ${stats.enums}`,
|
|
2207
2433
|
`// Circular references: ${stats.withCircularRefs}`,
|
|
2208
2434
|
`// Discriminated unions: ${stats.withDiscriminators}`,
|
|
2209
|
-
`// With constraints: ${stats.withConstraints}
|
|
2210
|
-
`// Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
2435
|
+
`// With constraints: ${stats.withConstraints}`
|
|
2211
2436
|
];
|
|
2437
|
+
if (this.options.operationFilters && this.filterStats.totalOperations > 0) {
|
|
2438
|
+
output.push("//");
|
|
2439
|
+
const filterStatsStr = formatFilterStatistics(this.filterStats);
|
|
2440
|
+
for (const line of filterStatsStr.split("\n")) {
|
|
2441
|
+
output.push(`// ${line}`);
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
output.push(`// Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
2445
|
+
return output;
|
|
2212
2446
|
}
|
|
2213
2447
|
};
|
|
2214
2448
|
|
|
@@ -2226,6 +2460,10 @@ function defineConfig(config) {
|
|
|
2226
2460
|
OpenApiGenerator,
|
|
2227
2461
|
SchemaGenerationError,
|
|
2228
2462
|
SpecValidationError,
|
|
2229
|
-
|
|
2463
|
+
createFilterStatistics,
|
|
2464
|
+
defineConfig,
|
|
2465
|
+
formatFilterStatistics,
|
|
2466
|
+
shouldIncludeOperation,
|
|
2467
|
+
validateFilters
|
|
2230
2468
|
});
|
|
2231
2469
|
//# sourceMappingURL=index.js.map
|