@cerios/openapi-to-zod 0.6.0 → 1.1.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/README.md +448 -51
- package/dist/cli.js +355 -186
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +418 -224
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +9 -344
- package/dist/index.d.ts +9 -344
- package/dist/index.js +156 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +155 -22
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +257 -0
- package/dist/internal.d.ts +257 -0
- package/dist/internal.js +592 -0
- package/dist/internal.js.map +1 -0
- package/dist/internal.mjs +547 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/types-B7ePTDjr.d.mts +345 -0
- package/dist/types-B7ePTDjr.d.ts +345 -0
- package/package.json +102 -78
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/batch-executor.ts","../src/utils/config-schemas.ts","../src/utils/config-validation.ts","../src/utils/lru-cache.ts","../src/utils/name-utils.ts","../src/utils/operation-filters.ts","../src/utils/pattern-utils.ts","../src/utils/string-utils.ts","../src/utils/typescript-loader.ts"],"sourcesContent":["/**\n * Custom error classes for better error handling and debugging\n */\n\n/**\n * Base error class for all generator errors\n */\nexport class GeneratorError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly code: string,\n\t\tpublic readonly context?: Record<string, unknown>\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"GeneratorError\";\n\t\tError.captureStackTrace?.(this, this.constructor);\n\t}\n}\n\n/**\n * Error thrown when OpenAPI spec validation fails\n */\nexport class SpecValidationError extends GeneratorError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, \"SPEC_VALIDATION_ERROR\", context);\n\t\tthis.name = \"SpecValidationError\";\n\t}\n}\n\n/**\n * Error thrown when file operations fail\n */\nexport class FileOperationError extends GeneratorError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly filePath: string,\n\t\tcontext?: Record<string, unknown>\n\t) {\n\t\tsuper(message, \"FILE_OPERATION_ERROR\", { ...context, filePath });\n\t\tthis.name = \"FileOperationError\";\n\t}\n}\n\n/**\n * Error thrown when config file is invalid\n */\nexport class ConfigValidationError extends GeneratorError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly configPath?: string,\n\t\tcontext?: Record<string, unknown>\n\t) {\n\t\tsuper(message, \"CONFIG_VALIDATION_ERROR\", { ...context, configPath });\n\t\tthis.name = \"ConfigValidationError\";\n\t}\n}\n\n/**\n * Error thrown when schema generation fails\n */\nexport class SchemaGenerationError extends GeneratorError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly schemaName: string,\n\t\tcontext?: Record<string, unknown>\n\t) {\n\t\tsuper(message, \"SCHEMA_GENERATION_ERROR\", { ...context, schemaName });\n\t\tthis.name = \"SchemaGenerationError\";\n\t}\n}\n\n/**\n * Error thrown when circular reference is detected in schema\n */\nexport class CircularReferenceError extends SchemaGenerationError {\n\tconstructor(\n\t\tschemaName: string,\n\t\tpublic readonly referencePath: string[]\n\t) {\n\t\tconst pathStr = referencePath.join(\" -> \");\n\t\tsuper(`Circular reference detected in schema: ${pathStr}`, schemaName, { referencePath, circularPath: pathStr });\n\t\tthis.name = \"CircularReferenceError\";\n\t}\n}\n\n/**\n * Error thrown when CLI options are invalid\n */\nexport class CliOptionsError extends GeneratorError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, \"CLI_OPTIONS_ERROR\", context);\n\t\tthis.name = \"CliOptionsError\";\n\t}\n}\n\n/**\n * Error thrown when configuration is invalid or missing required values\n */\nexport class ConfigurationError extends GeneratorError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, \"CONFIGURATION_ERROR\", context);\n\t\tthis.name = \"ConfigurationError\";\n\t}\n}\n","import { ConfigurationError } from \"./errors\";\nimport type { ExecutionMode } from \"./types\";\n\n/**\n * @shared Generator interface for batch execution\n * @since 1.0.0\n * Interface that both OpenApiGenerator and OpenApiPlaywrightGenerator must implement\n */\nexport interface Generator {\n\tgenerate(): void;\n}\n\n/**\n * Result of processing a single spec\n */\ninterface SpecResult<T> {\n\tspec: T;\n\tsuccess: boolean;\n\terror?: string;\n}\n\n/**\n * Summary of batch execution results\n */\ninterface BatchExecutionSummary<T> {\n\ttotal: number;\n\tsuccessful: number;\n\tfailed: number;\n\tresults: SpecResult<T>[];\n}\n\n/**\n * Process a single spec and return result with error handling\n */\nasync function processSpec<T>(\n\tspec: T,\n\tindex: number,\n\ttotal: number,\n\tcreateGenerator: (spec: T) => Generator\n): Promise<SpecResult<T>> {\n\t// Live progress to stdout\n\tconst specInput = (spec as any).input || \"spec\";\n\tconst specOutput = (spec as any).output || \"output\";\n\tconsole.log(`Processing [${index + 1}/${total}] ${specInput}...`);\n\n\ttry {\n\t\tconst generator = createGenerator(spec);\n\t\tgenerator.generate();\n\n\t\treturn {\n\t\t\tspec,\n\t\t\tsuccess: true,\n\t\t};\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tconsole.error(`✗ Failed to generate ${specOutput}: ${errorMessage}`);\n\n\t\treturn {\n\t\t\tspec,\n\t\t\tsuccess: false,\n\t\t\terror: errorMessage,\n\t\t};\n\t}\n}\n\n/**\n * Execute specs in parallel using Promise.allSettled with configurable batch size\n * Processes specifications in batches to control memory usage and concurrency\n * Continues processing all specs even if some fail\n */\nasync function executeParallel<T>(\n\tspecs: T[],\n\tcreateGenerator: (spec: T) => Generator,\n\tbatchSize: number\n): Promise<SpecResult<T>[]> {\n\tconsole.log(`\\nExecuting ${specs.length} specification(s) in parallel (batch size: ${batchSize})...\\n`);\n\n\tconst results: SpecResult<T>[] = [];\n\n\t// Process in batches to control memory usage\n\tfor (let i = 0; i < specs.length; i += batchSize) {\n\t\tconst batch = specs.slice(i, Math.min(i + batchSize, specs.length));\n\t\tconst batchPromises = batch.map((spec, batchIndex) =>\n\t\t\tprocessSpec(spec, i + batchIndex, specs.length, createGenerator)\n\t\t);\n\n\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t// Convert settled results to SpecResult\n\t\tfor (let j = 0; j < batchResults.length; j++) {\n\t\t\tconst result = batchResults[j];\n\t\t\tif (result.status === \"fulfilled\") {\n\t\t\t\tresults.push(result.value);\n\t\t\t} else {\n\t\t\t\t// Handle unexpected promise rejection\n\t\t\t\tresults.push({\n\t\t\t\t\tspec: batch[j],\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: result.reason instanceof Error ? result.reason.message : String(result.reason),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn results;\n}\n\n/**\n * Execute specs sequentially one at a time\n * Continues processing all specs even if some fail\n */\nasync function executeSequential<T>(specs: T[], createGenerator: (spec: T) => Generator): Promise<SpecResult<T>[]> {\n\tconsole.log(`\\nExecuting ${specs.length} spec(s) sequentially...\\n`);\n\n\tconst results: SpecResult<T>[] = [];\n\n\tfor (let i = 0; i < specs.length; i++) {\n\t\tconst result = await processSpec(specs[i], i, specs.length, createGenerator);\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/**\n * Print final summary of batch execution\n */\nfunction printSummary<T>(summary: BatchExecutionSummary<T>): void {\n\tconsole.log(`\\n${\"=\".repeat(50)}`);\n\tconsole.log(\"Batch Execution Summary\");\n\tconsole.log(\"=\".repeat(50));\n\tconsole.log(`Total specs: ${summary.total}`);\n\tconsole.log(`Successful: ${summary.successful}`);\n\tconsole.log(`Failed: ${summary.failed}`);\n\n\tif (summary.failed > 0) {\n\t\tconsole.log(\"\\nFailed specs:\");\n\t\tfor (const result of summary.results) {\n\t\t\tif (!result.success) {\n\t\t\t\tconst specInput = (result.spec as any).input || \"spec\";\n\t\t\t\tconsole.error(` ✗ ${specInput}`);\n\t\t\t\tconsole.error(` Error: ${result.error}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tconsole.log(`${\"=\".repeat(50)}\\n`);\n}\n\n/**\n * @shared Execute batch processing of multiple specs with custom generator\n * @since 1.0.0\n * Utility used by core and playwright packages\n *\n * @param specs - Array of spec configurations to process\n * @param executionMode - Execution mode: \"parallel\" (default) or \"sequential\"\n * @param createGenerator - Factory function to create generator from spec\n * @param batchSize - Number of specifications to process concurrently in parallel mode\n * @returns BatchExecutionSummary with results\n * @throws Never throws - collects all errors and reports them\n */\nexport async function executeBatch<T>(\n\tspecs: T[],\n\texecutionMode: ExecutionMode = \"parallel\",\n\tcreateGenerator: (spec: T) => Generator,\n\tbatchSize: number\n): Promise<BatchExecutionSummary<T>> {\n\tif (specs.length === 0) {\n\t\tthrow new ConfigurationError(\"No specs provided for batch execution\", { specsCount: 0, executionMode });\n\t}\n\n\tlet results: SpecResult<T>[] = [];\n\n\ttry {\n\t\t// Execute based on mode\n\t\tresults =\n\t\t\texecutionMode === \"parallel\"\n\t\t\t\t? await executeParallel(specs, createGenerator, batchSize)\n\t\t\t\t: await executeSequential(specs, createGenerator);\n\n\t\t// Calculate summary\n\t\tconst summary: BatchExecutionSummary<T> = {\n\t\t\ttotal: results.length,\n\t\t\tsuccessful: results.filter(r => r.success).length,\n\t\t\tfailed: results.filter(r => !r.success).length,\n\t\t\tresults,\n\t\t};\n\n\t\t// Print summary\n\t\tprintSummary(summary);\n\n\t\treturn summary;\n\t} finally {\n\t\t// Memory leak prevention: Clear large result objects and hint GC for large batches\n\t\tif (results.length > batchSize) {\n\t\t\t// Clear spec references to allow GC\n\t\t\tfor (const result of results) {\n\t\t\t\t// Keep only essential info, clear large objects\n\t\t\t\tif (result.spec) {\n\t\t\t\t\t(result.spec as any) = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Hint to V8 garbage collector for large batches (if available)\n\t\t\tif (global.gc) {\n\t\t\t\tglobal.gc();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Determine exit code based on batch execution results\n * Returns 1 if any spec failed, 0 if all succeeded\n */\nexport function getBatchExitCode<T>(summary: BatchExecutionSummary<T>): number {\n\treturn summary.failed > 0 ? 1 : 0;\n}\n","import { z } from \"zod\";\n\n/**\n * @shared Zod schema for request/response options validation\n * @since 1.0.0\n * Utility used by core and playwright packages\n */\nexport const RequestResponseOptionsSchema = z.strictObject({\n\tmode: z.enum([\"strict\", \"normal\", \"loose\"]).optional(),\n\tuseDescribe: z.boolean().optional(),\n\tincludeDescriptions: z.boolean().optional(),\n});\n\n/**\n * @shared Base Zod schema for operation filters (without status codes)\n * @since 1.0.0\n * Utility used by core and playwright packages\n */\nexport const OperationFiltersSchema = z.strictObject({\n\tincludeTags: z.array(z.string()).optional(),\n\texcludeTags: z.array(z.string()).optional(),\n\tincludePaths: z.array(z.string()).optional(),\n\texcludePaths: z.array(z.string()).optional(),\n\tincludeMethods: z.array(z.string()).optional(),\n\texcludeMethods: z.array(z.string()).optional(),\n\tincludeOperationIds: z.array(z.string()).optional(),\n\texcludeOperationIds: z.array(z.string()).optional(),\n\texcludeDeprecated: z.boolean().optional(),\n});\n\n/**\n * Inferred TypeScript type for request/response options\n */\nexport type RequestResponseOptions = z.infer<typeof RequestResponseOptionsSchema>;\n\n/**\n * Inferred TypeScript type for base operation filters\n */\nexport type BaseOperationFilters = z.infer<typeof OperationFiltersSchema>;\n","import { z } from \"zod\";\n\n/**\n * @shared Format Zod validation errors into user-friendly error messages\n * @since 1.0.0\n * Utility used by core and playwright packages\n *\n * @param error - The Zod validation error\n * @param filepath - Path to the config file that was being validated\n * @param configPath - Optional explicit config path provided by user\n * @param additionalNotes - Optional array of additional notes to append to the error message\n * @returns Formatted error message string\n */\nexport function formatConfigValidationError(\n\terror: z.ZodError,\n\tfilepath: string | undefined,\n\tconfigPath: string | undefined,\n\tadditionalNotes?: string[]\n): string {\n\tconst formattedErrors =\n\t\terror.issues\n\t\t\t?.map(err => {\n\t\t\t\tconst path = err.path.length > 0 ? err.path.join(\".\") : \"root\";\n\t\t\t\treturn ` - ${path}: ${err.message}`;\n\t\t\t})\n\t\t\t.join(\"\\n\") || \"Unknown validation error\";\n\n\tconst configSource = filepath || configPath || \"config file\";\n\tconst lines = [\n\t\t`Invalid configuration file at: ${configSource}`,\n\t\t\"\",\n\t\t\"Validation errors:\",\n\t\tformattedErrors,\n\t\t\"\",\n\t\t\"Please check your configuration file and ensure:\",\n\t\t\" - All required fields are present (specs array with input/output)\",\n\t\t\" - Field names are spelled correctly (no typos)\",\n\t\t\" - Values match the expected types (e.g., mode: 'strict' | 'normal' | 'loose')\",\n\t\t\" - No unknown/extra properties are included\",\n\t];\n\n\tif (additionalNotes && additionalNotes.length > 0) {\n\t\tlines.push(...additionalNotes.map(note => ` - ${note}`));\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n","/**\n * @shared Simple LRU Cache implementation for performance optimization\n * @since 1.0.0\n * Utility used by core and playwright packages\n * Prevents memory leaks from unbounded cache growth\n */\nexport class LRUCache<K, V> {\n\tprivate cache = new Map<K, V>();\n\tprivate maxSize: number;\n\n\tconstructor(maxSize: number) {\n\t\tthis.maxSize = maxSize;\n\t}\n\n\tget capacity(): number {\n\t\treturn this.maxSize;\n\t}\n\n\tget(key: K): V | undefined {\n\t\tif (!this.cache.has(key)) return undefined;\n\t\t// Move to end (most recently used)\n\t\tconst value = this.cache.get(key);\n\t\tif (value === undefined) return undefined;\n\t\tthis.cache.delete(key);\n\t\tthis.cache.set(key, value);\n\t\treturn value;\n\t}\n\n\tset(key: K, value: V): void {\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key);\n\t\t} else if (this.cache.size >= this.maxSize) {\n\t\t\t// Remove least recently used (first item)\n\t\t\tconst firstKey = this.cache.keys().next().value;\n\t\t\tif (firstKey !== undefined) {\n\t\t\t\tthis.cache.delete(firstKey);\n\t\t\t}\n\t\t}\n\t\tthis.cache.set(key, value);\n\t}\n\n\thas(key: K): boolean {\n\t\treturn this.cache.has(key);\n\t}\n\n\tclear(): void {\n\t\tthis.cache.clear();\n\t}\n\n\tsize(): number {\n\t\treturn this.cache.size;\n\t}\n}\n","/**\n * Name conversion utilities\n */\n\nexport interface NamingOptions {\n\tprefix?: string;\n\tsuffix?: string;\n}\n\n/**\n * Sanitize a string by replacing invalid identifier characters with underscores\n * Preserves dots, hyphens, underscores, and spaces as word separators\n * Example: \"User@Domain\" -> \"User_Domain\"\n * Example: \"User-Data@2024\" -> \"User-Data_2024\"\n */\nfunction sanitizeIdentifier(str: string): string {\n\t// Replace all non-identifier chars (except dots, hyphens, underscores, spaces) with underscores\n\t// Valid identifier chars: letters, digits, underscore\n\t// Preserve: dots, hyphens, underscores, spaces as word separators\n\treturn str.replace(/[^a-zA-Z0-9._\\-\\s]+/g, \"_\");\n}\n\n/**\n * Convert schema name to camelCase with optional prefix/suffix\n * Handles dotted names like \"Company.Models.User\" -> \"companyModelsUser\"\n */\nexport function toCamelCase(str: string, options?: NamingOptions): string {\n\t// Sanitize invalid characters first\n\tconst sanitized = sanitizeIdentifier(str);\n\n\t// Split by dots, hyphens, underscores, and spaces to get words\n\tconst words = sanitized.split(/[.\\-_\\s]+/).filter(word => word.length > 0);\n\n\t// Convert to camelCase: first word lowercase, rest PascalCase\n\tlet name: string;\n\tif (words.length === 0) {\n\t\tname = str.charAt(0).toLowerCase() + str.slice(1);\n\t} else if (words.length === 1) {\n\t\tname = words[0].charAt(0).toLowerCase() + words[0].slice(1);\n\t} else {\n\t\tname =\n\t\t\twords[0].charAt(0).toLowerCase() +\n\t\t\twords[0].slice(1) +\n\t\t\twords\n\t\t\t\t.slice(1)\n\t\t\t\t.map(word => word.charAt(0).toUpperCase() + word.slice(1))\n\t\t\t\t.join(\"\");\n\t}\n\n\t// Add prefix\n\tif (options?.prefix) {\n\t\tconst prefix = options.prefix.toLowerCase();\n\t\tname = prefix + name.charAt(0).toUpperCase() + name.slice(1);\n\t}\n\n\t// Add suffix before \"Schema\"\n\tif (options?.suffix) {\n\t\tconst suffix = options.suffix;\n\t\tname = name + suffix.charAt(0).toUpperCase() + suffix.slice(1).toLowerCase();\n\t}\n\n\treturn name;\n}\n\n/**\n * @shared Convert enum value to PascalCase and sanitize for TypeScript enum keys\n * @since 1.0.0\n * Utility used by core and playwright packages\n * Handles dotted names like \"Company.Models.User\" -> \"CompanyModelsUser\"\n */\nexport function toPascalCase(str: string | number): string {\n\tconst stringValue = String(str);\n\n\t// Check if it's already a valid PascalCase or camelCase identifier\n\t// (only contains letters, digits, and no special characters)\n\tconst isAlreadyValidCase = /^[a-zA-Z][a-zA-Z0-9]*$/.test(stringValue);\n\n\tif (isAlreadyValidCase) {\n\t\t// Just ensure it starts with uppercase\n\t\treturn stringValue.charAt(0).toUpperCase() + stringValue.slice(1);\n\t}\n\n\t// Sanitize invalid characters first\n\tconst sanitized = sanitizeIdentifier(stringValue);\n\n\t// Split by dots, hyphens, underscores, and spaces to get words\n\tconst words = sanitized.split(/[.\\-_\\s]+/).filter(word => word.length > 0);\n\n\t// Convert all words to PascalCase\n\tlet result: string;\n\tif (words.length === 0) {\n\t\tresult = \"Value\";\n\t} else {\n\t\tresult = words.map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(\"\");\n\t}\n\n\t// Enum keys can't start with a number - prefix with 'N'\n\tif (/^\\d/.test(result)) {\n\t\tresult = `N${result}`;\n\t}\n\n\t// If result is empty or only underscores, use a default\n\tif (!result || /^_+$/.test(result)) {\n\t\treturn \"Value\";\n\t}\n\n\treturn result;\n}\n\n/**\n * Resolve $ref to schema name\n */\nexport function resolveRef(ref: string): string {\n\tconst parts = ref.split(\"/\");\n\treturn parts[parts.length - 1];\n}\n","import { minimatch } from \"minimatch\";\nimport type { OperationFilters } from \"../types\";\n\n/**\n * Filter statistics to track which operations were included/excluded\n */\nexport interface FilterStatistics {\n\ttotalOperations: number;\n\tincludedOperations: number;\n\tfilteredByTags: number;\n\tfilteredByPaths: number;\n\tfilteredByMethods: number;\n\tfilteredByOperationIds: number;\n\tfilteredByDeprecated: number;\n}\n\n/**\n * Create a new filter statistics object with all counters initialized to zero\n */\nexport function createFilterStatistics(): FilterStatistics {\n\treturn {\n\t\ttotalOperations: 0,\n\t\tincludedOperations: 0,\n\t\tfilteredByTags: 0,\n\t\tfilteredByPaths: 0,\n\t\tfilteredByMethods: 0,\n\t\tfilteredByOperationIds: 0,\n\t\tfilteredByDeprecated: 0,\n\t};\n}\n\n/**\n * Check if a value matches any of the patterns (supports glob patterns)\n * Empty patterns array = no constraint (returns true)\n */\nfunction matchesAnyPattern(value: string | undefined, patterns: string[] | undefined): boolean {\n\tif (!patterns || patterns.length === 0) {\n\t\treturn false; // No constraint means \"don't use this filter\"\n\t}\n\tif (!value) {\n\t\treturn false;\n\t}\n\treturn patterns.some(pattern => minimatch(value, pattern));\n}\n\n/**\n * Check if an array contains any of the specified values\n * Empty values array = no constraint (returns false)\n */\nfunction containsAny(arr: string[] | undefined, values: string[] | undefined): boolean {\n\tif (!values || values.length === 0) {\n\t\treturn false; // No constraint means \"don't use this filter\"\n\t}\n\tif (!arr || arr.length === 0) {\n\t\treturn false;\n\t}\n\treturn values.some(value => arr.includes(value));\n}\n\n/**\n * Determine if an operation should be included based on filter criteria\n *\n * Filter logic:\n * 1. If no filters specified, include all operations\n * 2. Empty arrays are treated as \"no constraint\" (not as \"exclude all\")\n * 3. Include filters are applied first (allowlist)\n * 4. Exclude filters are applied second (blocklist)\n * 5. Exclude rules always win over include rules\n *\n * @param operation - The OpenAPI operation object\n * @param path - The operation path (e.g., \"/users/{id}\")\n * @param method - The HTTP method (e.g., \"get\", \"post\")\n * @param filters - Optional filter configuration\n * @param stats - Optional statistics object to track filtering reasons\n * @returns true if the operation should be included, false otherwise\n */\nexport function shouldIncludeOperation(\n\toperation: any,\n\tpath: string,\n\tmethod: string,\n\tfilters?: OperationFilters,\n\tstats?: FilterStatistics\n): boolean {\n\t// If no filters specified, include all operations\n\tif (!filters) {\n\t\treturn true;\n\t}\n\n\tconst methodLower = method.toLowerCase();\n\tconst operationId = operation?.operationId;\n\tconst tags = operation?.tags || [];\n\tconst deprecated = operation?.deprecated === true;\n\n\t// Apply include filters first (allowlist)\n\t// If any include filter is specified and the operation doesn't match, exclude it\n\n\t// Check includeTags\n\tif (filters.includeTags && filters.includeTags.length > 0) {\n\t\tif (!containsAny(tags, filters.includeTags)) {\n\t\t\tif (stats) stats.filteredByTags++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check includePaths\n\tif (filters.includePaths && filters.includePaths.length > 0) {\n\t\tif (!matchesAnyPattern(path, filters.includePaths)) {\n\t\t\tif (stats) stats.filteredByPaths++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check includeMethods\n\tif (filters.includeMethods && filters.includeMethods.length > 0) {\n\t\tconst methodsLower = filters.includeMethods.map(m => m.toLowerCase());\n\t\tif (!methodsLower.includes(methodLower)) {\n\t\t\tif (stats) stats.filteredByMethods++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check includeOperationIds\n\tif (filters.includeOperationIds && filters.includeOperationIds.length > 0) {\n\t\tif (!matchesAnyPattern(operationId, filters.includeOperationIds)) {\n\t\t\tif (stats) stats.filteredByOperationIds++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Apply exclude filters second (blocklist)\n\t// If the operation matches any exclude filter, exclude it\n\n\t// Check excludeDeprecated\n\tif (filters.excludeDeprecated === true && deprecated) {\n\t\tif (stats) stats.filteredByDeprecated++;\n\t\treturn false;\n\t}\n\n\t// Check excludeTags\n\tif (filters.excludeTags && filters.excludeTags.length > 0) {\n\t\tif (containsAny(tags, filters.excludeTags)) {\n\t\t\tif (stats) stats.filteredByTags++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check excludePaths\n\tif (filters.excludePaths && filters.excludePaths.length > 0) {\n\t\tif (matchesAnyPattern(path, filters.excludePaths)) {\n\t\t\tif (stats) stats.filteredByPaths++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check excludeMethods\n\tif (filters.excludeMethods && filters.excludeMethods.length > 0) {\n\t\tconst methodsLower = filters.excludeMethods.map(m => m.toLowerCase());\n\t\tif (methodsLower.includes(methodLower)) {\n\t\t\tif (stats) stats.filteredByMethods++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Check excludeOperationIds\n\tif (filters.excludeOperationIds && filters.excludeOperationIds.length > 0) {\n\t\tif (matchesAnyPattern(operationId, filters.excludeOperationIds)) {\n\t\t\tif (stats) stats.filteredByOperationIds++;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Operation passed all filters\n\treturn true;\n}\n\n/**\n * Validate filter statistics and emit warnings for filters that matched nothing\n * Helps users debug filter configurations that might be too restrictive or contain typos\n *\n * @param stats - Filter statistics object\n * @param filters - The filter configuration to validate\n */\nexport function validateFilters(stats: FilterStatistics, filters?: OperationFilters): void {\n\tif (!filters || stats.totalOperations === 0) {\n\t\treturn;\n\t}\n\n\t// If all operations were filtered out, emit a warning\n\tif (stats.includedOperations === 0) {\n\t\tconsole.warn(\n\t\t\t`⚠️ Warning: All ${stats.totalOperations} operations were filtered out. Check your operationFilters configuration.`\n\t\t);\n\n\t\t// Provide specific guidance about which filters might be the issue\n\t\tconst filterBreakdown: string[] = [];\n\t\tif (stats.filteredByTags > 0) filterBreakdown.push(`${stats.filteredByTags} by tags`);\n\t\tif (stats.filteredByPaths > 0) filterBreakdown.push(`${stats.filteredByPaths} by paths`);\n\t\tif (stats.filteredByMethods > 0) filterBreakdown.push(`${stats.filteredByMethods} by methods`);\n\t\tif (stats.filteredByOperationIds > 0) filterBreakdown.push(`${stats.filteredByOperationIds} by operationIds`);\n\t\tif (stats.filteredByDeprecated > 0) filterBreakdown.push(`${stats.filteredByDeprecated} by deprecated flag`);\n\n\t\tif (filterBreakdown.length > 0) {\n\t\t\tconsole.warn(` Filtered: ${filterBreakdown.join(\", \")}`);\n\t\t}\n\t}\n}\n\n/**\n * Format filter statistics for display in generated output\n * Returns a formatted string suitable for inclusion in comments\n *\n * @param stats - Filter statistics object\n * @returns Formatted statistics string\n */\nexport function formatFilterStatistics(stats: FilterStatistics): string {\n\tif (stats.totalOperations === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst lines: string[] = [];\n\tlines.push(\"Operation Filtering:\");\n\tlines.push(` Total operations: ${stats.totalOperations}`);\n\tlines.push(` Included operations: ${stats.includedOperations}`);\n\n\tconst filteredCount =\n\t\tstats.filteredByTags +\n\t\tstats.filteredByPaths +\n\t\tstats.filteredByMethods +\n\t\tstats.filteredByOperationIds +\n\t\tstats.filteredByDeprecated;\n\n\tif (filteredCount > 0) {\n\t\tlines.push(` Filtered operations: ${filteredCount}`);\n\t\tif (stats.filteredByTags > 0) lines.push(` - By tags: ${stats.filteredByTags}`);\n\t\tif (stats.filteredByPaths > 0) lines.push(` - By paths: ${stats.filteredByPaths}`);\n\t\tif (stats.filteredByMethods > 0) lines.push(` - By methods: ${stats.filteredByMethods}`);\n\t\tif (stats.filteredByOperationIds > 0) lines.push(` - By operationIds: ${stats.filteredByOperationIds}`);\n\t\tif (stats.filteredByDeprecated > 0) lines.push(` - By deprecated: ${stats.filteredByDeprecated}`);\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n","/**\n * Pattern matching utilities for prefix stripping\n *\n * Shared utility used by core and playwright packages\n *\n * Supports both literal string matching and regex patterns for stripping\n * prefixes from strings (paths, schema names, etc.)\n */\n\n/**\n * Detects if a string pattern should be treated as a regex\n * Checks for common regex indicators:\n * - Starts with ^ (anchor) or ends with $ (anchor)\n * - Contains \\d, \\w, \\s (character classes)\n * - Contains .* or .+ (quantifiers)\n * - Contains [], (), {} (groups/classes)\n */\nfunction isRegexPattern(pattern: string): boolean {\n\t// Check for regex anchors\n\tif (pattern.startsWith(\"^\") || pattern.endsWith(\"$\")) {\n\t\treturn true;\n\t}\n\n\t// Check for escaped character classes\n\tif (/\\\\[dDwWsS]/.test(pattern)) {\n\t\treturn true;\n\t}\n\n\t// Check for quantifiers and wildcards\n\tif (/\\.\\*|\\.\\+/.test(pattern)) {\n\t\treturn true;\n\t}\n\n\t// Check for character classes and groups\n\tif (/[[\\]()]/.test(pattern)) {\n\t\treturn true;\n\t}\n\n\t// Check for quantifiers in regex context\n\tif (/[^/][+?*]\\{/.test(pattern)) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Converts a string pattern to a RegExp if it looks like a regex\n * Otherwise treats it as a literal string prefix\n * @param pattern - The pattern (string or RegExp)\n * @returns A RegExp object or null for literal string matching\n */\nfunction patternToRegex(pattern: string | RegExp): RegExp | null {\n\tif (pattern instanceof RegExp) {\n\t\treturn pattern;\n\t}\n\n\tif (isRegexPattern(pattern)) {\n\t\ttry {\n\t\t\treturn new RegExp(pattern);\n\t\t} catch (error) {\n\t\t\tconsole.warn(`⚠️ Invalid regex pattern \"${pattern}\": ${error instanceof Error ? error.message : String(error)}`);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Literal string - return null to indicate literal matching\n\treturn null;\n}\n\n/**\n * @shared Strips a prefix from a string using either literal string matching or regex\n * @since 1.1.0\n * Shared utility used by core and playwright packages\n *\n * @param input - The full string to strip from\n * @param pattern - The pattern to strip (string or RegExp)\n * @param ensureLeadingChar - Optional character to ensure at start (e.g., \"/\" for paths)\n * @returns The string with prefix removed, or original string if no match\n *\n * @example\n * // Literal string matching\n * stripPrefix(\"/api/v1/users\", \"/api/v1\") // => \"/users\"\n * stripPrefix(\"Company.Models.User\", \"Company.Models.\") // => \"User\"\n *\n * @example\n * // Regex pattern matching\n * stripPrefix(\"/api/v1.0/users\", \"^/api/v\\\\d+\\\\.\\\\d+\") // => \"/users\"\n * stripPrefix(\"api_v2_UserSchema\", \"^api_v\\\\d+_\") // => \"UserSchema\"\n */\nexport function stripPrefix(input: string, pattern: string | RegExp | undefined, ensureLeadingChar?: string): string {\n\tif (!pattern) {\n\t\treturn input;\n\t}\n\n\tconst regex = patternToRegex(pattern);\n\n\tif (regex) {\n\t\t// Regex matching\n\t\tconst match = input.match(regex);\n\t\tif (match && match.index === 0) {\n\t\t\t// Remove the matched prefix\n\t\t\tconst stripped = input.substring(match[0].length);\n\n\t\t\t// Ensure result starts with specified character if provided\n\t\t\tif (ensureLeadingChar) {\n\t\t\t\tif (stripped === \"\") {\n\t\t\t\t\treturn ensureLeadingChar;\n\t\t\t\t}\n\t\t\t\tif (!stripped.startsWith(ensureLeadingChar)) {\n\t\t\t\t\treturn `${ensureLeadingChar}${stripped}`;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stripped;\n\t\t}\n\t} else {\n\t\t// Literal string matching\n\t\tconst stringPattern = pattern as string;\n\n\t\t// For exact matching, use the pattern as-is\n\t\tif (input.startsWith(stringPattern)) {\n\t\t\tconst stripped = input.substring(stringPattern.length);\n\n\t\t\t// Ensure result starts with specified character if provided\n\t\t\tif (ensureLeadingChar) {\n\t\t\t\tif (stripped === \"\") {\n\t\t\t\t\treturn ensureLeadingChar;\n\t\t\t\t}\n\t\t\t\tif (!stripped.startsWith(ensureLeadingChar)) {\n\t\t\t\t\treturn `${ensureLeadingChar}${stripped}`;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stripped;\n\t\t}\n\t}\n\n\t// No match - return original input\n\treturn input;\n}\n\n/**\n * @shared Strips a prefix from a path (ensures leading slash)\n * @since 1.1.0\n * Shared utility used by playwright package for path manipulation\n *\n * @param path - The full path to strip from\n * @param pattern - The pattern to strip (string or RegExp)\n * @returns The path with prefix removed, or original path if no match\n *\n * @example\n * stripPathPrefix(\"/api/v1/users\", \"/api/v1\") // => \"/users\"\n * stripPathPrefix(\"/api/v2/posts\", \"^/api/v\\\\d+\") // => \"/posts\"\n */\nexport function stripPathPrefix(path: string, pattern: string | RegExp | undefined): string {\n\tif (!pattern) {\n\t\treturn path;\n\t}\n\n\tconst regex = patternToRegex(pattern);\n\n\tif (!regex) {\n\t\t// For literal string matching with paths, normalize the pattern\n\t\tlet normalizedPattern = (pattern as string).trim();\n\t\tif (!normalizedPattern.startsWith(\"/\")) {\n\t\t\tnormalizedPattern = `/${normalizedPattern}`;\n\t\t}\n\t\tif (normalizedPattern.endsWith(\"/\") && normalizedPattern !== \"/\") {\n\t\t\tnormalizedPattern = normalizedPattern.slice(0, -1);\n\t\t}\n\n\t\treturn stripPrefix(path, normalizedPattern, \"/\");\n\t}\n\n\treturn stripPrefix(path, regex, \"/\");\n}\n","/**\n * String utility functions for escaping and formatting\n */\n\nimport type { OpenAPISchema } from \"../types\";\n\n/**\n * Escape string for description in .describe()\n */\nexport function escapeDescription(str: string): string {\n\treturn str.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n}\n\n/**\n * Escape regex pattern for use in code\n */\nexport function escapePattern(str: string): string {\n\treturn str.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n}\n\n/**\n * @shared Escape JSDoc comment content to prevent injection\n * @since 1.0.0\n * Utility used by core and playwright packages\n */\nexport function escapeJSDoc(str: string): string {\n\treturn str.replace(/\\*\\//g, \"*\\\\/\");\n}\n\n/**\n * Wrap validation with .nullable() if needed\n */\nexport function wrapNullable(validation: string, isNullable: boolean): string {\n\treturn isNullable ? `${validation}.nullable()` : validation;\n}\n\n/**\n * Check if schema is nullable (supports both OpenAPI 3.0 and 3.1 syntax)\n */\nexport function isNullable(schema: OpenAPISchema): boolean {\n\t// OpenAPI 3.0 style: nullable: true\n\tif (schema.nullable === true) {\n\t\treturn true;\n\t}\n\t// OpenAPI 3.1 style: type can be an array including \"null\"\n\tif (Array.isArray(schema.type)) {\n\t\treturn schema.type.includes(\"null\");\n\t}\n\treturn false;\n}\n\n/**\n * Get the primary type from schema (handles OpenAPI 3.1 type arrays)\n */\nexport function getPrimaryType(schema: OpenAPISchema): string | undefined {\n\tif (Array.isArray(schema.type)) {\n\t\t// OpenAPI 3.1: type can be an array like [\"string\", \"null\"]\n\t\t// Return the first non-null type\n\t\tconst nonNullType = schema.type.find(t => t !== \"null\");\n\t\treturn nonNullType;\n\t}\n\treturn schema.type;\n}\n\n/**\n * Check if schema has multiple non-null types\n */\nexport function hasMultipleTypes(schema: OpenAPISchema): boolean {\n\tif (Array.isArray(schema.type)) {\n\t\tconst nonNullTypes = schema.type.filter(t => t !== \"null\");\n\t\treturn nonNullTypes.length > 1;\n\t}\n\treturn false;\n}\n\n/**\n * Add description to a schema validation string\n */\nexport function addDescription(validation: string, description: string | undefined, useDescribe: boolean): string {\n\tif (!description || !useDescribe) return validation;\n\n\tconst escapedDesc = escapeDescription(description);\n\treturn `${validation}.describe(\"${escapedDesc}\")`;\n}\n","import type { Loader } from \"cosmiconfig\";\n\n/**\n * @shared Create a TypeScript loader for cosmiconfig using esbuild\n * @since 1.0.0\n * Utility used by core and playwright packages\n *\n * Creates a loader that transpiles TypeScript config files to JavaScript\n * using esbuild, then executes them to load the configuration.\n *\n * @returns A cosmiconfig Loader function\n */\nexport function createTypeScriptLoader(): Loader {\n\treturn async (filepath: string) => {\n\t\ttry {\n\t\t\t// Use esbuild to transpile TypeScript to JavaScript\n\t\t\tconst esbuild = await import(\"esbuild\");\n\t\t\tconst fs = await import(\"node:fs\");\n\t\t\tconst path = await import(\"node:path\");\n\n\t\t\tconst tsCode = fs.readFileSync(filepath, \"utf-8\");\n\t\t\tconst result = await esbuild.build({\n\t\t\t\tstdin: {\n\t\t\t\t\tcontents: tsCode,\n\t\t\t\t\tloader: \"ts\",\n\t\t\t\t\tresolveDir: path.dirname(filepath),\n\t\t\t\t\tsourcefile: filepath,\n\t\t\t\t},\n\t\t\t\tformat: \"cjs\",\n\t\t\t\tplatform: \"node\",\n\t\t\t\ttarget: \"node18\",\n\t\t\t\tbundle: false,\n\t\t\t\twrite: false,\n\t\t\t});\n\n\t\t\tconst jsCode = result.outputFiles[0].text;\n\n\t\t\t// Create a module and execute it\n\t\t\tconst module = { exports: {} } as any;\n\t\t\tconst func = new Function(\"exports\", \"module\", \"require\", \"__filename\", \"__dirname\", jsCode);\n\t\t\tfunc(module.exports, module, require, filepath, path.dirname(filepath));\n\n\t\t\treturn module.exports.default || module.exports;\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to load TypeScript config from ${filepath}: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t);\n\t\t}\n\t};\n}\n"],"mappings":";;;;;;;;AAOO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EACzC,YACC,SACgB,MACA,SACf;AAZH;AAaE,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AACZ,gBAAM,sBAAN,+BAA0B,MAAM,KAAK;AAAA,EACtC;AACD;AAiFO,IAAM,qBAAN,cAAiC,eAAe;AAAA,EACtD,YAAY,SAAiB,SAAmC;AAC/D,UAAM,SAAS,uBAAuB,OAAO;AAC7C,SAAK,OAAO;AAAA,EACb;AACD;;;ACrEA,eAAe,YACd,MACA,OACA,OACA,iBACyB;AAEzB,QAAM,YAAa,KAAa,SAAS;AACzC,QAAM,aAAc,KAAa,UAAU;AAC3C,UAAQ,IAAI,eAAe,QAAQ,CAAC,IAAI,KAAK,KAAK,SAAS,KAAK;AAEhE,MAAI;AACH,UAAM,YAAY,gBAAgB,IAAI;AACtC,cAAU,SAAS;AAEnB,WAAO;AAAA,MACN;AAAA,MACA,SAAS;AAAA,IACV;AAAA,EACD,SAAS,OAAO;AACf,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAQ,MAAM,6BAAwB,UAAU,KAAK,YAAY,EAAE;AAEnE,WAAO;AAAA,MACN;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,IACR;AAAA,EACD;AACD;AAOA,eAAe,gBACd,OACA,iBACA,WAC2B;AAC3B,UAAQ,IAAI;AAAA,YAAe,MAAM,MAAM,8CAA8C,SAAS;AAAA,CAAQ;AAEtG,QAAM,UAA2B,CAAC;AAGlC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,WAAW;AACjD,UAAM,QAAQ,MAAM,MAAM,GAAG,KAAK,IAAI,IAAI,WAAW,MAAM,MAAM,CAAC;AAClE,UAAM,gBAAgB,MAAM;AAAA,MAAI,CAAC,MAAM,eACtC,YAAY,MAAM,IAAI,YAAY,MAAM,QAAQ,eAAe;AAAA,IAChE;AAEA,UAAM,eAAe,MAAM,QAAQ,WAAW,aAAa;AAG3D,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC7C,YAAM,SAAS,aAAa,CAAC;AAC7B,UAAI,OAAO,WAAW,aAAa;AAClC,gBAAQ,KAAK,OAAO,KAAK;AAAA,MAC1B,OAAO;AAEN,gBAAQ,KAAK;AAAA,UACZ,MAAM,MAAM,CAAC;AAAA,UACb,SAAS;AAAA,UACT,OAAO,OAAO,kBAAkB,QAAQ,OAAO,OAAO,UAAU,OAAO,OAAO,MAAM;AAAA,QACrF,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;AAMA,eAAe,kBAAqB,OAAY,iBAAmE;AAClH,UAAQ,IAAI;AAAA,YAAe,MAAM,MAAM;AAAA,CAA4B;AAEnE,QAAM,UAA2B,CAAC;AAElC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtC,UAAM,SAAS,MAAM,YAAY,MAAM,CAAC,GAAG,GAAG,MAAM,QAAQ,eAAe;AAC3E,YAAQ,KAAK,MAAM;AAAA,EACpB;AAEA,SAAO;AACR;AAKA,SAAS,aAAgB,SAAyC;AACjE,UAAQ,IAAI;AAAA,EAAK,IAAI,OAAO,EAAE,CAAC,EAAE;AACjC,UAAQ,IAAI,yBAAyB;AACrC,UAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,UAAQ,IAAI,gBAAgB,QAAQ,KAAK,EAAE;AAC3C,UAAQ,IAAI,eAAe,QAAQ,UAAU,EAAE;AAC/C,UAAQ,IAAI,WAAW,QAAQ,MAAM,EAAE;AAEvC,MAAI,QAAQ,SAAS,GAAG;AACvB,YAAQ,IAAI,iBAAiB;AAC7B,eAAW,UAAU,QAAQ,SAAS;AACrC,UAAI,CAAC,OAAO,SAAS;AACpB,cAAM,YAAa,OAAO,KAAa,SAAS;AAChD,gBAAQ,MAAM,YAAO,SAAS,EAAE;AAChC,gBAAQ,MAAM,cAAc,OAAO,KAAK,EAAE;AAAA,MAC3C;AAAA,IACD;AAAA,EACD;AAEA,UAAQ,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;AAAA,CAAI;AAClC;AAcA,eAAsB,aACrB,OACA,gBAA+B,YAC/B,iBACA,WACoC;AACpC,MAAI,MAAM,WAAW,GAAG;AACvB,UAAM,IAAI,mBAAmB,yCAAyC,EAAE,YAAY,GAAG,cAAc,CAAC;AAAA,EACvG;AAEA,MAAI,UAA2B,CAAC;AAEhC,MAAI;AAEH,cACC,kBAAkB,aACf,MAAM,gBAAgB,OAAO,iBAAiB,SAAS,IACvD,MAAM,kBAAkB,OAAO,eAAe;AAGlD,UAAM,UAAoC;AAAA,MACzC,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ,OAAO,OAAK,EAAE,OAAO,EAAE;AAAA,MAC3C,QAAQ,QAAQ,OAAO,OAAK,CAAC,EAAE,OAAO,EAAE;AAAA,MACxC;AAAA,IACD;AAGA,iBAAa,OAAO;AAEpB,WAAO;AAAA,EACR,UAAE;AAED,QAAI,QAAQ,SAAS,WAAW;AAE/B,iBAAW,UAAU,SAAS;AAE7B,YAAI,OAAO,MAAM;AAChB,UAAC,OAAO,OAAe;AAAA,QACxB;AAAA,MACD;AAGA,UAAI,OAAO,IAAI;AACd,eAAO,GAAG;AAAA,MACX;AAAA,IACD;AAAA,EACD;AACD;AAMO,SAAS,iBAAoB,SAA2C;AAC9E,SAAO,QAAQ,SAAS,IAAI,IAAI;AACjC;;;ACzNA,SAAS,SAAS;AAOX,IAAM,+BAA+B,EAAE,aAAa;AAAA,EAC1D,MAAM,EAAE,KAAK,CAAC,UAAU,UAAU,OAAO,CAAC,EAAE,SAAS;AAAA,EACrD,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,EAClC,qBAAqB,EAAE,QAAQ,EAAE,SAAS;AAC3C,CAAC;AAOM,IAAM,yBAAyB,EAAE,aAAa;AAAA,EACpD,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC1C,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC1C,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC3C,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC3C,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC7C,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC7C,qBAAqB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAClD,qBAAqB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAClD,mBAAmB,EAAE,QAAQ,EAAE,SAAS;AACzC,CAAC;;;ACfM,SAAS,4BACf,OACA,UACA,YACA,iBACS;AAlBV;AAmBC,QAAM,oBACL,WAAM,WAAN,mBACG,IAAI,SAAO;AACZ,UAAM,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI;AACxD,WAAO,OAAO,IAAI,KAAK,IAAI,OAAO;AAAA,EACnC,GACC,KAAK,UAAS;AAEjB,QAAM,eAAe,YAAY,cAAc;AAC/C,QAAM,QAAQ;AAAA,IACb,kCAAkC,YAAY;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAEA,MAAI,mBAAmB,gBAAgB,SAAS,GAAG;AAClD,UAAM,KAAK,GAAG,gBAAgB,IAAI,UAAQ,OAAO,IAAI,EAAE,CAAC;AAAA,EACzD;AAEA,SAAO,MAAM,KAAK,IAAI;AACvB;;;ACxCO,IAAM,WAAN,MAAqB;AAAA,EAI3B,YAAY,SAAiB;AAH7B,SAAQ,QAAQ,oBAAI,IAAU;AAI7B,SAAK,UAAU;AAAA,EAChB;AAAA,EAEA,IAAI,WAAmB;AACtB,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAI,KAAuB;AAC1B,QAAI,CAAC,KAAK,MAAM,IAAI,GAAG,EAAG,QAAO;AAEjC,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,UAAU,OAAW,QAAO;AAChC,SAAK,MAAM,OAAO,GAAG;AACrB,SAAK,MAAM,IAAI,KAAK,KAAK;AACzB,WAAO;AAAA,EACR;AAAA,EAEA,IAAI,KAAQ,OAAgB;AAC3B,QAAI,KAAK,MAAM,IAAI,GAAG,GAAG;AACxB,WAAK,MAAM,OAAO,GAAG;AAAA,IACtB,WAAW,KAAK,MAAM,QAAQ,KAAK,SAAS;AAE3C,YAAM,WAAW,KAAK,MAAM,KAAK,EAAE,KAAK,EAAE;AAC1C,UAAI,aAAa,QAAW;AAC3B,aAAK,MAAM,OAAO,QAAQ;AAAA,MAC3B;AAAA,IACD;AACA,SAAK,MAAM,IAAI,KAAK,KAAK;AAAA,EAC1B;AAAA,EAEA,IAAI,KAAiB;AACpB,WAAO,KAAK,MAAM,IAAI,GAAG;AAAA,EAC1B;AAAA,EAEA,QAAc;AACb,SAAK,MAAM,MAAM;AAAA,EAClB;AAAA,EAEA,OAAe;AACd,WAAO,KAAK,MAAM;AAAA,EACnB;AACD;;;ACrCA,SAAS,mBAAmB,KAAqB;AAIhD,SAAO,IAAI,QAAQ,wBAAwB,GAAG;AAC/C;AAMO,SAAS,YAAY,KAAa,SAAiC;AAEzE,QAAM,YAAY,mBAAmB,GAAG;AAGxC,QAAM,QAAQ,UAAU,MAAM,WAAW,EAAE,OAAO,UAAQ,KAAK,SAAS,CAAC;AAGzE,MAAI;AACJ,MAAI,MAAM,WAAW,GAAG;AACvB,WAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,EACjD,WAAW,MAAM,WAAW,GAAG;AAC9B,WAAO,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,CAAC,EAAE,MAAM,CAAC;AAAA,EAC3D,OAAO;AACN,WACC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,IAChB,MACE,MAAM,CAAC,EACP,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EACxD,KAAK,EAAE;AAAA,EACX;AAGA,MAAI,mCAAS,QAAQ;AACpB,UAAM,SAAS,QAAQ,OAAO,YAAY;AAC1C,WAAO,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,EAC5D;AAGA,MAAI,mCAAS,QAAQ;AACpB,UAAM,SAAS,QAAQ;AACvB,WAAO,OAAO,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC,EAAE,YAAY;AAAA,EAC5E;AAEA,SAAO;AACR;AAQO,SAAS,aAAa,KAA8B;AAC1D,QAAM,cAAc,OAAO,GAAG;AAI9B,QAAM,qBAAqB,yBAAyB,KAAK,WAAW;AAEpE,MAAI,oBAAoB;AAEvB,WAAO,YAAY,OAAO,CAAC,EAAE,YAAY,IAAI,YAAY,MAAM,CAAC;AAAA,EACjE;AAGA,QAAM,YAAY,mBAAmB,WAAW;AAGhD,QAAM,QAAQ,UAAU,MAAM,WAAW,EAAE,OAAO,UAAQ,KAAK,SAAS,CAAC;AAGzE,MAAI;AACJ,MAAI,MAAM,WAAW,GAAG;AACvB,aAAS;AAAA,EACV,OAAO;AACN,aAAS,MAAM,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE;AAAA,EACjF;AAGA,MAAI,MAAM,KAAK,MAAM,GAAG;AACvB,aAAS,IAAI,MAAM;AAAA,EACpB;AAGA,MAAI,CAAC,UAAU,OAAO,KAAK,MAAM,GAAG;AACnC,WAAO;AAAA,EACR;AAEA,SAAO;AACR;;;AC3GA,SAAS,iBAAiB;AAmBnB,SAAS,yBAA2C;AAC1D,SAAO;AAAA,IACN,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,wBAAwB;AAAA,IACxB,sBAAsB;AAAA,EACvB;AACD;AAMA,SAAS,kBAAkB,OAA2B,UAAyC;AAC9F,MAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACvC,WAAO;AAAA,EACR;AACA,MAAI,CAAC,OAAO;AACX,WAAO;AAAA,EACR;AACA,SAAO,SAAS,KAAK,aAAW,UAAU,OAAO,OAAO,CAAC;AAC1D;AAMA,SAAS,YAAY,KAA2B,QAAuC;AACtF,MAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AACnC,WAAO;AAAA,EACR;AACA,MAAI,CAAC,OAAO,IAAI,WAAW,GAAG;AAC7B,WAAO;AAAA,EACR;AACA,SAAO,OAAO,KAAK,WAAS,IAAI,SAAS,KAAK,CAAC;AAChD;AAmBO,SAAS,uBACf,WACA,MACA,QACA,SACA,OACU;AAEV,MAAI,CAAC,SAAS;AACb,WAAO;AAAA,EACR;AAEA,QAAM,cAAc,OAAO,YAAY;AACvC,QAAM,cAAc,uCAAW;AAC/B,QAAM,QAAO,uCAAW,SAAQ,CAAC;AACjC,QAAM,cAAa,uCAAW,gBAAe;AAM7C,MAAI,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AAC1D,QAAI,CAAC,YAAY,MAAM,QAAQ,WAAW,GAAG;AAC5C,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,MAAI,QAAQ,gBAAgB,QAAQ,aAAa,SAAS,GAAG;AAC5D,QAAI,CAAC,kBAAkB,MAAM,QAAQ,YAAY,GAAG;AACnD,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,MAAI,QAAQ,kBAAkB,QAAQ,eAAe,SAAS,GAAG;AAChE,UAAM,eAAe,QAAQ,eAAe,IAAI,OAAK,EAAE,YAAY,CAAC;AACpE,QAAI,CAAC,aAAa,SAAS,WAAW,GAAG;AACxC,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,MAAI,QAAQ,uBAAuB,QAAQ,oBAAoB,SAAS,GAAG;AAC1E,QAAI,CAAC,kBAAkB,aAAa,QAAQ,mBAAmB,GAAG;AACjE,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAMA,MAAI,QAAQ,sBAAsB,QAAQ,YAAY;AACrD,QAAI,MAAO,OAAM;AACjB,WAAO;AAAA,EACR;AAGA,MAAI,QAAQ,eAAe,QAAQ,YAAY,SAAS,GAAG;AAC1D,QAAI,YAAY,MAAM,QAAQ,WAAW,GAAG;AAC3C,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,MAAI,QAAQ,gBAAgB,QAAQ,aAAa,SAAS,GAAG;AAC5D,QAAI,kBAAkB,MAAM,QAAQ,YAAY,GAAG;AAClD,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,MAAI,QAAQ,kBAAkB,QAAQ,eAAe,SAAS,GAAG;AAChE,UAAM,eAAe,QAAQ,eAAe,IAAI,OAAK,EAAE,YAAY,CAAC;AACpE,QAAI,aAAa,SAAS,WAAW,GAAG;AACvC,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,MAAI,QAAQ,uBAAuB,QAAQ,oBAAoB,SAAS,GAAG;AAC1E,QAAI,kBAAkB,aAAa,QAAQ,mBAAmB,GAAG;AAChE,UAAI,MAAO,OAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,SAAO;AACR;AASO,SAAS,gBAAgB,OAAyB,SAAkC;AAC1F,MAAI,CAAC,WAAW,MAAM,oBAAoB,GAAG;AAC5C;AAAA,EACD;AAGA,MAAI,MAAM,uBAAuB,GAAG;AACnC,YAAQ;AAAA,MACP,8BAAoB,MAAM,eAAe;AAAA,IAC1C;AAGA,UAAM,kBAA4B,CAAC;AACnC,QAAI,MAAM,iBAAiB,EAAG,iBAAgB,KAAK,GAAG,MAAM,cAAc,UAAU;AACpF,QAAI,MAAM,kBAAkB,EAAG,iBAAgB,KAAK,GAAG,MAAM,eAAe,WAAW;AACvF,QAAI,MAAM,oBAAoB,EAAG,iBAAgB,KAAK,GAAG,MAAM,iBAAiB,aAAa;AAC7F,QAAI,MAAM,yBAAyB,EAAG,iBAAgB,KAAK,GAAG,MAAM,sBAAsB,kBAAkB;AAC5G,QAAI,MAAM,uBAAuB,EAAG,iBAAgB,KAAK,GAAG,MAAM,oBAAoB,qBAAqB;AAE3G,QAAI,gBAAgB,SAAS,GAAG;AAC/B,cAAQ,KAAK,gBAAgB,gBAAgB,KAAK,IAAI,CAAC,EAAE;AAAA,IAC1D;AAAA,EACD;AACD;AASO,SAAS,uBAAuB,OAAiC;AACvE,MAAI,MAAM,oBAAoB,GAAG;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,uBAAuB,MAAM,eAAe,EAAE;AACzD,QAAM,KAAK,0BAA0B,MAAM,kBAAkB,EAAE;AAE/D,QAAM,gBACL,MAAM,iBACN,MAAM,kBACN,MAAM,oBACN,MAAM,yBACN,MAAM;AAEP,MAAI,gBAAgB,GAAG;AACtB,UAAM,KAAK,0BAA0B,aAAa,EAAE;AACpD,QAAI,MAAM,iBAAiB,EAAG,OAAM,KAAK,kBAAkB,MAAM,cAAc,EAAE;AACjF,QAAI,MAAM,kBAAkB,EAAG,OAAM,KAAK,mBAAmB,MAAM,eAAe,EAAE;AACpF,QAAI,MAAM,oBAAoB,EAAG,OAAM,KAAK,qBAAqB,MAAM,iBAAiB,EAAE;AAC1F,QAAI,MAAM,yBAAyB,EAAG,OAAM,KAAK,0BAA0B,MAAM,sBAAsB,EAAE;AACzG,QAAI,MAAM,uBAAuB,EAAG,OAAM,KAAK,wBAAwB,MAAM,oBAAoB,EAAE;AAAA,EACpG;AAEA,SAAO,MAAM,KAAK,IAAI;AACvB;;;AChOA,SAAS,eAAe,SAA0B;AAEjD,MAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AACrD,WAAO;AAAA,EACR;AAGA,MAAI,aAAa,KAAK,OAAO,GAAG;AAC/B,WAAO;AAAA,EACR;AAGA,MAAI,YAAY,KAAK,OAAO,GAAG;AAC9B,WAAO;AAAA,EACR;AAGA,MAAI,UAAU,KAAK,OAAO,GAAG;AAC5B,WAAO;AAAA,EACR;AAGA,MAAI,cAAc,KAAK,OAAO,GAAG;AAChC,WAAO;AAAA,EACR;AAEA,SAAO;AACR;AAQA,SAAS,eAAe,SAAyC;AAChE,MAAI,mBAAmB,QAAQ;AAC9B,WAAO;AAAA,EACR;AAEA,MAAI,eAAe,OAAO,GAAG;AAC5B,QAAI;AACH,aAAO,IAAI,OAAO,OAAO;AAAA,IAC1B,SAAS,OAAO;AACf,cAAQ,KAAK,wCAA8B,OAAO,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChH,aAAO;AAAA,IACR;AAAA,EACD;AAGA,SAAO;AACR;AAsBO,SAAS,YAAY,OAAe,SAAsC,mBAAoC;AACpH,MAAI,CAAC,SAAS;AACb,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,eAAe,OAAO;AAEpC,MAAI,OAAO;AAEV,UAAM,QAAQ,MAAM,MAAM,KAAK;AAC/B,QAAI,SAAS,MAAM,UAAU,GAAG;AAE/B,YAAM,WAAW,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM;AAGhD,UAAI,mBAAmB;AACtB,YAAI,aAAa,IAAI;AACpB,iBAAO;AAAA,QACR;AACA,YAAI,CAAC,SAAS,WAAW,iBAAiB,GAAG;AAC5C,iBAAO,GAAG,iBAAiB,GAAG,QAAQ;AAAA,QACvC;AAAA,MACD;AAEA,aAAO;AAAA,IACR;AAAA,EACD,OAAO;AAEN,UAAM,gBAAgB;AAGtB,QAAI,MAAM,WAAW,aAAa,GAAG;AACpC,YAAM,WAAW,MAAM,UAAU,cAAc,MAAM;AAGrD,UAAI,mBAAmB;AACtB,YAAI,aAAa,IAAI;AACpB,iBAAO;AAAA,QACR;AACA,YAAI,CAAC,SAAS,WAAW,iBAAiB,GAAG;AAC5C,iBAAO,GAAG,iBAAiB,GAAG,QAAQ;AAAA,QACvC;AAAA,MACD;AAEA,aAAO;AAAA,IACR;AAAA,EACD;AAGA,SAAO;AACR;AAeO,SAAS,gBAAgB,MAAc,SAA8C;AAC3F,MAAI,CAAC,SAAS;AACb,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,eAAe,OAAO;AAEpC,MAAI,CAAC,OAAO;AAEX,QAAI,oBAAqB,QAAmB,KAAK;AACjD,QAAI,CAAC,kBAAkB,WAAW,GAAG,GAAG;AACvC,0BAAoB,IAAI,iBAAiB;AAAA,IAC1C;AACA,QAAI,kBAAkB,SAAS,GAAG,KAAK,sBAAsB,KAAK;AACjE,0BAAoB,kBAAkB,MAAM,GAAG,EAAE;AAAA,IAClD;AAEA,WAAO,YAAY,MAAM,mBAAmB,GAAG;AAAA,EAChD;AAEA,SAAO,YAAY,MAAM,OAAO,GAAG;AACpC;;;ACvJO,SAAS,YAAY,KAAqB;AAChD,SAAO,IAAI,QAAQ,SAAS,MAAM;AACnC;;;ACfO,SAAS,yBAAiC;AAChD,SAAO,OAAO,aAAqB;AAClC,QAAI;AAEH,YAAM,UAAU,MAAM,OAAO,SAAS;AACtC,YAAM,KAAK,MAAM,OAAO,IAAS;AACjC,YAAM,OAAO,MAAM,OAAO,MAAW;AAErC,YAAM,SAAS,GAAG,aAAa,UAAU,OAAO;AAChD,YAAM,SAAS,MAAM,QAAQ,MAAM;AAAA,QAClC,OAAO;AAAA,UACN,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,YAAY,KAAK,QAAQ,QAAQ;AAAA,UACjC,YAAY;AAAA,QACb;AAAA,QACA,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,OAAO;AAAA,MACR,CAAC;AAED,YAAM,SAAS,OAAO,YAAY,CAAC,EAAE;AAGrC,YAAM,SAAS,EAAE,SAAS,CAAC,EAAE;AAC7B,YAAM,OAAO,IAAI,SAAS,WAAW,UAAU,WAAW,cAAc,aAAa,MAAM;AAC3F,WAAK,OAAO,SAAS,QAAQ,WAAS,UAAU,KAAK,QAAQ,QAAQ,CAAC;AAEtE,aAAO,OAAO,QAAQ,WAAW,OAAO;AAAA,IACzC,SAAS,OAAO;AACf,YAAM,IAAI;AAAA,QACT,yCAAyC,QAAQ,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC7G;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common options shared by both request and response contexts
|
|
3
|
+
*/
|
|
4
|
+
interface CommonSchemaOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Object validation mode
|
|
7
|
+
* - 'strict': Uses z.strictObject() - no additional properties allowed
|
|
8
|
+
* - 'normal': Uses z.object() - additional properties allowed
|
|
9
|
+
* - 'loose': Uses z.looseObject() - explicitly allows additional properties
|
|
10
|
+
*/
|
|
11
|
+
mode?: "strict" | "normal" | "loose";
|
|
12
|
+
/**
|
|
13
|
+
* Whether to add .describe() calls for better error messages
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
useDescribe?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to include descriptions as JSDoc comments
|
|
19
|
+
*/
|
|
20
|
+
includeDescriptions?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Request-specific options that can override root-level options
|
|
24
|
+
*/
|
|
25
|
+
interface RequestOptions extends CommonSchemaOptions {
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Response-specific options that can override root-level options
|
|
29
|
+
*/
|
|
30
|
+
interface ResponseOptions extends CommonSchemaOptions {
|
|
31
|
+
}
|
|
32
|
+
interface OpenApiGeneratorOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Object validation mode
|
|
35
|
+
* - 'strict': Uses z.strictObject() - no additional properties allowed
|
|
36
|
+
* - 'normal': Uses z.object() - additional properties allowed
|
|
37
|
+
* - 'loose': Uses z.looseObject() - explicitly allows additional properties
|
|
38
|
+
*/
|
|
39
|
+
mode?: "strict" | "normal" | "loose";
|
|
40
|
+
/**
|
|
41
|
+
* Input OpenAPI YAML file path
|
|
42
|
+
*/
|
|
43
|
+
input: string;
|
|
44
|
+
/**
|
|
45
|
+
* Output TypeScript file path
|
|
46
|
+
* Optional when using string generation methods (generateString)
|
|
47
|
+
* Required when calling generate() to write to a file
|
|
48
|
+
*/
|
|
49
|
+
output?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Whether to include descriptions as JSDoc comments
|
|
52
|
+
*/
|
|
53
|
+
includeDescriptions?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Whether to add .describe() calls for better error messages
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
useDescribe?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Schema filtering mode
|
|
61
|
+
* - 'all': Generate all schemas (default)
|
|
62
|
+
* - 'request': Only include schemas suitable for requests (excludes readOnly)
|
|
63
|
+
* - 'response': Only include schemas suitable for responses (excludes writeOnly)
|
|
64
|
+
*/
|
|
65
|
+
schemaType?: "all" | "request" | "response";
|
|
66
|
+
/**
|
|
67
|
+
* Prefix to add to all generated schema names
|
|
68
|
+
* @example "api" -> "apiUserSchema"
|
|
69
|
+
*/
|
|
70
|
+
prefix?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Suffix to add before "Schema" in generated names
|
|
73
|
+
* @example "dto" -> "userDtoSchema"
|
|
74
|
+
*/
|
|
75
|
+
suffix?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Strip a common prefix from all schema names before processing
|
|
78
|
+
* Useful when OpenAPI spec has redundant schema prefixes that you want to ignore
|
|
79
|
+
*
|
|
80
|
+
* Supports both literal strings and regex patterns:
|
|
81
|
+
* - Literal string: "Company.Models." (must match exactly)
|
|
82
|
+
* - Regex pattern: "^[A-Z][a-z]+\\." (auto-detected or use RegExp for TypeScript configs)
|
|
83
|
+
*
|
|
84
|
+
* Regex auto-detection checks for: ^, $, \\d, \\w, \\s, .*, .+, [], ()
|
|
85
|
+
*
|
|
86
|
+
* This affects:
|
|
87
|
+
* - Schema name generation (shorter, cleaner names)
|
|
88
|
+
* - Type name generation
|
|
89
|
+
* - References to schemas
|
|
90
|
+
*
|
|
91
|
+
* Applied before prefix/suffix options.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* // Spec has: "Company.Models.User", "Company.Models.Post"
|
|
95
|
+
* // stripSchemaPrefix: "Company.Models."
|
|
96
|
+
* // Results in: "User", "Post"
|
|
97
|
+
* // Schema names: userSchema, postSchema
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* // Strip any namespace prefix
|
|
101
|
+
* // stripSchemaPrefix: "^[A-Za-z]+\\."
|
|
102
|
+
* // Matches: "Namespace.User", "App.User", etc.
|
|
103
|
+
*
|
|
104
|
+
* @default undefined (no stripping)
|
|
105
|
+
*/
|
|
106
|
+
stripSchemaPrefix?: string | RegExp;
|
|
107
|
+
/**
|
|
108
|
+
* Whether to include generation statistics in output file
|
|
109
|
+
* @default true
|
|
110
|
+
*/
|
|
111
|
+
showStats?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Request-specific options that override root-level options
|
|
114
|
+
* Applied when schemas are used in request contexts
|
|
115
|
+
*/
|
|
116
|
+
request?: RequestOptions;
|
|
117
|
+
/**
|
|
118
|
+
* Response-specific options that override root-level options
|
|
119
|
+
* Applied when schemas are used in response contexts
|
|
120
|
+
*/
|
|
121
|
+
response?: ResponseOptions;
|
|
122
|
+
/**
|
|
123
|
+
* Filter which operations to include/exclude from generation
|
|
124
|
+
* Useful for generating separate schemas for different API subsets
|
|
125
|
+
*
|
|
126
|
+
* Filtering logic:
|
|
127
|
+
* 1. If no filters specified, all operations are included
|
|
128
|
+
* 2. Empty arrays are treated as "no constraint" (not as "exclude all")
|
|
129
|
+
* 3. Include filters are applied first (allowlist)
|
|
130
|
+
* 4. Exclude filters are applied second (blocklist)
|
|
131
|
+
* 5. Exclude rules always win over include rules
|
|
132
|
+
*
|
|
133
|
+
* Supports glob patterns for paths and operationIds (e.g., "/api/v1/**", "get*")
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* // Only generate schemas for user-related endpoints
|
|
137
|
+
* operationFilters: {
|
|
138
|
+
* includeTags: ["users"]
|
|
139
|
+
* }
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* // Generate only GET endpoints, excluding deprecated ones
|
|
143
|
+
* operationFilters: {
|
|
144
|
+
* includeMethods: ["get"],
|
|
145
|
+
* excludeDeprecated: true
|
|
146
|
+
* }
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* // Generate only v1 API endpoints
|
|
150
|
+
* operationFilters: {
|
|
151
|
+
* includePaths: ["/api/v1/**"]
|
|
152
|
+
* }
|
|
153
|
+
*/
|
|
154
|
+
operationFilters?: OperationFilters;
|
|
155
|
+
/**
|
|
156
|
+
* Header parameters to ignore during schema generation
|
|
157
|
+
* Supports glob patterns for flexible matching
|
|
158
|
+
* Case-insensitive matching (HTTP header semantics)
|
|
159
|
+
*
|
|
160
|
+
* @internal Used by Playwright generator
|
|
161
|
+
*/
|
|
162
|
+
ignoreHeaders?: string[];
|
|
163
|
+
/**
|
|
164
|
+
* Cache size for pattern regex compilation
|
|
165
|
+
* Higher values improve performance for large specifications with many string patterns
|
|
166
|
+
* @default 1000
|
|
167
|
+
*/
|
|
168
|
+
cacheSize?: number;
|
|
169
|
+
/**
|
|
170
|
+
* Batch size for parallel execution
|
|
171
|
+
* Controls how many specifications are processed concurrently in parallel mode
|
|
172
|
+
* Higher values increase memory usage but may improve throughput
|
|
173
|
+
* @default 10
|
|
174
|
+
*/
|
|
175
|
+
batchSize?: number;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Operation filtering options
|
|
179
|
+
* Controls which operations from the OpenAPI specification are included in generation
|
|
180
|
+
*/
|
|
181
|
+
interface OperationFilters {
|
|
182
|
+
/**
|
|
183
|
+
* Include only operations with these tags
|
|
184
|
+
* If specified, only operations with at least one matching tag are included
|
|
185
|
+
* Empty array = no constraint
|
|
186
|
+
*/
|
|
187
|
+
includeTags?: string[];
|
|
188
|
+
/**
|
|
189
|
+
* Exclude operations with these tags
|
|
190
|
+
* Operations with any matching tag are excluded
|
|
191
|
+
* Empty array = no constraint
|
|
192
|
+
*/
|
|
193
|
+
excludeTags?: string[];
|
|
194
|
+
/**
|
|
195
|
+
* Include only operations matching these path patterns
|
|
196
|
+
* Supports glob patterns (e.g., "/users/**", "/api/v1/*")
|
|
197
|
+
* Empty array = no constraint
|
|
198
|
+
*/
|
|
199
|
+
includePaths?: string[];
|
|
200
|
+
/**
|
|
201
|
+
* Exclude operations matching these path patterns
|
|
202
|
+
* Supports glob patterns (e.g., "/internal/**", "/admin/*")
|
|
203
|
+
* Empty array = no constraint
|
|
204
|
+
*/
|
|
205
|
+
excludePaths?: string[];
|
|
206
|
+
/**
|
|
207
|
+
* Include only these HTTP methods
|
|
208
|
+
* Valid values: "get", "post", "put", "patch", "delete", "head", "options"
|
|
209
|
+
* Empty array = no constraint
|
|
210
|
+
*/
|
|
211
|
+
includeMethods?: string[];
|
|
212
|
+
/**
|
|
213
|
+
* Exclude these HTTP methods
|
|
214
|
+
* Valid values: "get", "post", "put", "patch", "delete", "head", "options"
|
|
215
|
+
* Empty array = no constraint
|
|
216
|
+
*/
|
|
217
|
+
excludeMethods?: string[];
|
|
218
|
+
/**
|
|
219
|
+
* Include only operations matching these operationId patterns
|
|
220
|
+
* Supports glob patterns (e.g., "getUser*", "*Admin")
|
|
221
|
+
* Empty array = no constraint
|
|
222
|
+
*/
|
|
223
|
+
includeOperationIds?: string[];
|
|
224
|
+
/**
|
|
225
|
+
* Exclude operations matching these operationId patterns
|
|
226
|
+
* Supports glob patterns (e.g., "deleteUser*", "*Internal")
|
|
227
|
+
* Empty array = no constraint
|
|
228
|
+
*/
|
|
229
|
+
excludeOperationIds?: string[];
|
|
230
|
+
/**
|
|
231
|
+
* Whether to exclude deprecated operations
|
|
232
|
+
* @default false
|
|
233
|
+
*/
|
|
234
|
+
excludeDeprecated?: boolean;
|
|
235
|
+
}
|
|
236
|
+
interface OpenAPISchema {
|
|
237
|
+
type?: string | string[];
|
|
238
|
+
format?: string;
|
|
239
|
+
enum?: (string | number)[];
|
|
240
|
+
const?: string | number | boolean | null;
|
|
241
|
+
properties?: Record<string, OpenAPISchema>;
|
|
242
|
+
required?: string[];
|
|
243
|
+
items?: OpenAPISchema;
|
|
244
|
+
prefixItems?: OpenAPISchema[];
|
|
245
|
+
allOf?: OpenAPISchema[];
|
|
246
|
+
oneOf?: OpenAPISchema[];
|
|
247
|
+
anyOf?: OpenAPISchema[];
|
|
248
|
+
$ref?: string;
|
|
249
|
+
nullable?: boolean;
|
|
250
|
+
minLength?: number;
|
|
251
|
+
maxLength?: number;
|
|
252
|
+
minimum?: number;
|
|
253
|
+
maximum?: number;
|
|
254
|
+
exclusiveMinimum?: boolean | number;
|
|
255
|
+
exclusiveMaximum?: boolean | number;
|
|
256
|
+
multipleOf?: number;
|
|
257
|
+
pattern?: string;
|
|
258
|
+
description?: string;
|
|
259
|
+
title?: string;
|
|
260
|
+
example?: any;
|
|
261
|
+
examples?: any[];
|
|
262
|
+
additionalProperties?: boolean | OpenAPISchema;
|
|
263
|
+
minProperties?: number;
|
|
264
|
+
maxProperties?: number;
|
|
265
|
+
minItems?: number;
|
|
266
|
+
maxItems?: number;
|
|
267
|
+
uniqueItems?: boolean;
|
|
268
|
+
contains?: OpenAPISchema;
|
|
269
|
+
minContains?: number;
|
|
270
|
+
maxContains?: number;
|
|
271
|
+
discriminator?: {
|
|
272
|
+
propertyName: string;
|
|
273
|
+
mapping?: Record<string, string>;
|
|
274
|
+
};
|
|
275
|
+
readOnly?: boolean;
|
|
276
|
+
writeOnly?: boolean;
|
|
277
|
+
deprecated?: boolean;
|
|
278
|
+
dependentRequired?: Record<string, string[]>;
|
|
279
|
+
dependencies?: Record<string, string[] | OpenAPISchema>;
|
|
280
|
+
patternProperties?: Record<string, OpenAPISchema>;
|
|
281
|
+
propertyNames?: OpenAPISchema;
|
|
282
|
+
contentMediaType?: string;
|
|
283
|
+
contentEncoding?: string;
|
|
284
|
+
not?: OpenAPISchema;
|
|
285
|
+
if?: OpenAPISchema;
|
|
286
|
+
then?: OpenAPISchema;
|
|
287
|
+
else?: OpenAPISchema;
|
|
288
|
+
unevaluatedProperties?: boolean | OpenAPISchema;
|
|
289
|
+
unevaluatedItems?: boolean | OpenAPISchema;
|
|
290
|
+
}
|
|
291
|
+
interface OpenAPISpec {
|
|
292
|
+
components?: {
|
|
293
|
+
schemas?: Record<string, OpenAPISchema>;
|
|
294
|
+
};
|
|
295
|
+
paths?: Record<string, any>;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Execution mode for batch processing
|
|
299
|
+
* - 'parallel': Process all specifications concurrently (default, faster)
|
|
300
|
+
* - 'sequential': Process specifications one at a time (safer for resource constraints)
|
|
301
|
+
*/
|
|
302
|
+
type ExecutionMode = "parallel" | "sequential";
|
|
303
|
+
/**
|
|
304
|
+
* Root configuration file structure
|
|
305
|
+
*/
|
|
306
|
+
interface ConfigFile {
|
|
307
|
+
/**
|
|
308
|
+
* Global default options applied to all specifications
|
|
309
|
+
* Can be overridden by individual specification configurations
|
|
310
|
+
*/
|
|
311
|
+
defaults?: Partial<Omit<OpenApiGeneratorOptions, "input" | "output">>;
|
|
312
|
+
/**
|
|
313
|
+
* Array of OpenAPI specifications to process
|
|
314
|
+
* Each specification must have input and output paths
|
|
315
|
+
*/
|
|
316
|
+
specs: OpenApiGeneratorOptions[];
|
|
317
|
+
/**
|
|
318
|
+
* Execution mode for batch processing
|
|
319
|
+
* @default "parallel"
|
|
320
|
+
*/
|
|
321
|
+
executionMode?: ExecutionMode;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Helper function for type-safe config file creation
|
|
325
|
+
* Provides IDE autocomplete and type checking for config files
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```typescript
|
|
329
|
+
* import { defineConfig } from '@cerios/openapi-to-zod';
|
|
330
|
+
*
|
|
331
|
+
* export default defineConfig({
|
|
332
|
+
* defaults: {
|
|
333
|
+
* mode: 'strict',
|
|
334
|
+
* includeDescriptions: true
|
|
335
|
+
* },
|
|
336
|
+
* specs: [
|
|
337
|
+
* { input: 'api-v1.yaml', output: 'schemas/v1.ts' },
|
|
338
|
+
* { input: 'api-v2.yaml', output: 'schemas/v2.ts', mode: 'normal' }
|
|
339
|
+
* ]
|
|
340
|
+
* });
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
declare function defineConfig(config: ConfigFile): ConfigFile;
|
|
344
|
+
|
|
345
|
+
export { type CommonSchemaOptions as C, type ExecutionMode as E, type OpenApiGeneratorOptions as O, type RequestOptions as R, type ConfigFile as a, type OpenAPISchema as b, type OpenAPISpec as c, type OperationFilters as d, type ResponseOptions as e, defineConfig as f };
|