@alt-stack/zod-openapi 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/interface-generator.spec.ts +6 -5
- package/src/to-typescript.ts +1 -1
- package/src/to-zod.spec.ts +5 -6
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @alt-stack/zod-openapi@1.3.
|
|
2
|
+
> @alt-stack/zod-openapi@1.3.1 build /home/runner/work/alt-stack/alt-stack/packages/zod-openapi
|
|
3
3
|
> tsup
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m42.
|
|
14
|
-
[32mCJS[39m [1mdist/index.cjs.map [22m[32m90.
|
|
15
|
-
[32mCJS[39m ⚡️ Build success in
|
|
16
|
-
[32mESM[39m [1mdist/index.js [22m[32m41.
|
|
17
|
-
[32mESM[39m [1mdist/index.js.map [22m[32m89.
|
|
13
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m42.73 KB[39m
|
|
14
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m90.41 KB[39m
|
|
15
|
+
[32mCJS[39m ⚡️ Build success in 32ms
|
|
16
|
+
[32mESM[39m [1mdist/index.js [22m[32m41.10 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m89.46 KB[39m
|
|
18
18
|
[32mESM[39m ⚡️ Build success in 33ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 1521ms
|
|
21
21
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m6.06 KB[39m
|
|
22
22
|
[32mDTS[39m [1mdist/index.d.cts [22m[32m6.06 KB[39m
|
package/dist/index.cjs
CHANGED
|
@@ -1228,7 +1228,7 @@ var openApiToZodTsCode = (openapi, customImportLines, options) => {
|
|
|
1228
1228
|
const schemaName = `${name}Schema`;
|
|
1229
1229
|
const typeName = name;
|
|
1230
1230
|
schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));
|
|
1231
|
-
schemaBlocks.push(`export const ${schemaName}
|
|
1231
|
+
schemaBlocks.push(`export const ${schemaName} = ${zodExpr};`);
|
|
1232
1232
|
schemaBlocks.push("");
|
|
1233
1233
|
typeAssertions.push(`type _Assert${typeName} = _AssertEqual<${typeName}, z.infer<typeof ${schemaName}>>;`);
|
|
1234
1234
|
const fingerprint = getSchemaFingerprint(schema);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/dependencies.ts","../src/schema-dedup.ts","../src/types/boolean.ts","../src/types/number.ts","../src/registry.ts","../src/types/string.ts","../src/types/array.ts","../src/types/object.ts","../src/types/union.ts","../src/types/intersection.ts","../src/to-zod.ts","../src/routes.ts","../src/interface-generator.ts","../src/to-typescript.ts"],"sourcesContent":["export { openApiToZodTsCode } from \"./to-typescript.js\";\nexport {\n registerZodSchemaToOpenApiSchema,\n clearZodSchemaToOpenApiSchemaRegistry,\n getSchemaExportedVariableNameForStringFormat,\n SUPPORTED_STRING_FORMATS,\n schemaRegistry,\n} from \"./registry.js\";\nexport type {\n ZodOpenApiRegistrationString,\n ZodOpenApiRegistrationStrings,\n ZodOpenApiRegistrationPrimitive,\n ZodOpenApiRegistration,\n} from \"./registry.js\";\nexport { convertSchemaToZodString } from \"./to-zod.js\";\nexport { generateInterface, schemaToTypeString } from \"./interface-generator.js\";\nexport {\n parseOpenApiPaths,\n generateRouteSchemaNames,\n} from \"./routes.js\";\nexport type {\n HttpMethod,\n RouteParameter,\n RouteInfo,\n RouteSchemaNames,\n} from \"./routes.js\";\nexport type { AnySchema, OpenAPIObjectSchema } from \"./types/types.js\";\n\n","import type { AnySchema } from \"./types/types\";\n\n/**\n * Extracts all schema references ($ref) from an OpenAPI schema by recursively\n * traversing its structure.\n *\n * This function is used during the OpenAPI-to-Zod conversion process to identify\n * which schemas a given schema depends on. It traverses all OpenAPI schema\n * structures including objects, arrays, unions (oneOf), intersections (allOf),\n * conditionals (if/then/else), and discriminator mappings to find all $ref\n * references that point to other schemas in the components/schemas section.\n *\n * The extracted dependency names are used by `topologicalSortSchemas` to build\n * a dependency graph and determine the correct order for generating Zod schemas,\n * ensuring that referenced schemas are defined before they are used in the\n * generated TypeScript code.\n *\n * @param schema - The OpenAPI schema to extract dependencies from\n * @returns An array of schema names that this schema references (via $ref)\n */\nexport function extractSchemaDependencies(schema: AnySchema): string[] {\n const dependencies: Set<string> = new Set();\n const visited = new WeakSet();\n\n function traverse(obj: any): void {\n if (!obj || typeof obj !== \"object\") return;\n\n if (visited.has(obj)) return;\n visited.add(obj);\n\n if (obj[\"$ref\"] && typeof obj[\"$ref\"] === \"string\") {\n const match = (obj[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n if (match && match[1]) {\n dependencies.add(decodeURIComponent(match[1]));\n }\n return;\n }\n\n if (Array.isArray(obj)) {\n obj.forEach(traverse);\n return;\n }\n\n if (obj.properties && typeof obj.properties === \"object\") {\n for (const propValue of Object.values(obj.properties)) {\n traverse(propValue);\n }\n }\n\n const schemaKeys = [\n \"items\",\n \"oneOf\",\n \"allOf\",\n \"anyOf\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n \"prefixItems\",\n \"contains\",\n \"propertyNames\",\n \"dependentSchemas\",\n ];\n\n for (const key of schemaKeys) {\n if (obj[key]) {\n traverse(obj[key]);\n }\n }\n\n if (\n obj.additionalProperties &&\n typeof obj.additionalProperties === \"object\"\n ) {\n traverse(obj.additionalProperties);\n }\n\n if (obj.discriminator?.mapping) {\n Object.values(obj.discriminator.mapping).forEach(traverse);\n }\n }\n\n traverse(schema);\n return Array.from(dependencies);\n}\n\n/**\n * Sorts OpenAPI schemas topologically based on their dependencies to ensure\n * correct generation order.\n *\n * When converting OpenAPI schemas to Zod schemas and generating TypeScript code,\n * schemas must be defined before they are referenced. For example, if `UserSchema`\n * references `ProfileSchema` (via $ref), then `ProfileSchema` must be generated\n * before `UserSchema` to avoid \"undefined variable\" errors in the generated code.\n *\n * This function uses Kahn's algorithm for topological sorting to order schemas\n * such that all dependencies come before their dependents. It:\n * 1. Extracts dependencies for each schema using `extractSchemaDependencies`\n * 2. Builds a dependency graph and computes in-degrees\n * 3. Sorts schemas starting with those that have no dependencies (in-degree 0)\n * 4. Handles circular dependencies gracefully by appending any remaining schemas\n * that couldn't be sorted (though this indicates a problematic schema structure)\n *\n * This function is called by `openApiToZodTsCode` to determine the order in which\n * schemas should be converted and emitted in the generated TypeScript file.\n *\n * @param schemas - A record mapping schema names to their OpenAPI schema definitions\n * @returns An array of schema names sorted in topological order (dependencies before dependents)\n */\nexport function topologicalSortSchemas(\n schemas: Record<string, AnySchema>,\n): string[] {\n const schemaNames = Object.keys(schemas);\n const dependencies: Map<string, string[]> = new Map();\n const inDegree: Map<string, number> = new Map();\n const sorted: string[] = [];\n const queue: string[] = [];\n const dependents: Map<string, string[]> = new Map();\n\n for (const name of schemaNames) {\n dependencies.set(name, []);\n dependents.set(name, []);\n inDegree.set(name, 0);\n }\n\n for (const name of schemaNames) {\n const schemaValue = schemas[name];\n if (schemaValue) {\n const deps = extractSchemaDependencies(schemaValue);\n const validDeps = deps.filter((dep) => schemaNames.includes(dep));\n dependencies.set(name, validDeps);\n\n for (const dep of validDeps) {\n const currentDependents = dependents.get(dep) || [];\n currentDependents.push(name);\n dependents.set(dep, currentDependents);\n }\n }\n }\n\n for (const [name, deps] of dependencies.entries()) {\n inDegree.set(name, deps.length);\n }\n\n for (const [name, degree] of inDegree.entries()) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n sorted.push(current);\n\n const currentDependents = dependents.get(current) || [];\n for (const dependent of currentDependents) {\n const newDegree = (inDegree.get(dependent) || 0) - 1;\n inDegree.set(dependent, newDegree);\n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n if (sorted.length !== schemaNames.length) {\n for (const name of schemaNames) {\n if (!sorted.includes(name)) {\n sorted.push(name);\n }\n }\n }\n\n return sorted;\n}\n","import type { AnySchema } from \"./types/types\";\n\n/**\n * Schema deduplication utilities for optimizing generated TypeScript types.\n *\n * This module provides fingerprinting and registry functionality to detect\n * structurally identical schemas and generate them only once, reducing\n * memory usage in consuming TypeScript projects.\n */\n\n/**\n * Recursively sorts an object's keys to create a stable representation.\n * This ensures that {a: 1, b: 2} and {b: 2, a: 1} produce the same fingerprint.\n */\nfunction sortObjectDeep(obj: unknown): unknown {\n if (obj === null || typeof obj !== \"object\") return obj;\n if (Array.isArray(obj)) return obj.map(sortObjectDeep);\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObjectDeep((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n}\n\n/**\n * Generates a canonical fingerprint for an OpenAPI schema.\n * Identical schemas will produce identical fingerprints.\n */\nexport function getSchemaFingerprint(schema: AnySchema): string {\n return JSON.stringify(sortObjectDeep(schema));\n}\n\n/**\n * Registry for tracking unique schemas and their canonical names.\n */\nexport interface SchemaRegistry {\n /** Map from fingerprint to the first schema name that used it */\n fingerprintToName: Map<string, string>;\n /** Map from schema name to its fingerprint (for reverse lookup) */\n nameToFingerprint: Map<string, string>;\n}\n\n/**\n * Creates a new empty schema registry.\n */\nexport function createSchemaRegistry(): SchemaRegistry {\n return {\n fingerprintToName: new Map(),\n nameToFingerprint: new Map(),\n };\n}\n\n/**\n * Result of registering a schema.\n */\nexport interface RegisterSchemaResult {\n /** Whether this is a new unique schema */\n isNew: boolean;\n /** The canonical name for this schema (may be different from input name if duplicate) */\n canonicalName: string;\n}\n\n/**\n * Registers a schema in the registry. If an identical schema already exists,\n * returns the existing canonical name instead.\n */\nexport function registerSchema(\n registry: SchemaRegistry,\n name: string,\n schema: AnySchema,\n): RegisterSchemaResult {\n const fingerprint = getSchemaFingerprint(schema);\n\n const existing = registry.fingerprintToName.get(fingerprint);\n if (existing) {\n return { isNew: false, canonicalName: existing };\n }\n\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n return { isNew: true, canonicalName: name };\n}\n\n/**\n * Pre-registers a schema with a specific fingerprint.\n * Used for common schemas that should take priority.\n */\nexport function preRegisterSchema(\n registry: SchemaRegistry,\n name: string,\n fingerprint: string,\n): void {\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n}\n\n/**\n * Extracts the error code from an OpenAPI error schema.\n * Looks for patterns like: { error: { code: enum(['UNAUTHORIZED']) } }\n */\nexport function extractErrorCode(schema: AnySchema): string | null {\n const properties = schema?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const errorObj = properties?.[\"error\"] as AnySchema | undefined;\n const errorProps = errorObj?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const codeSchema = errorProps?.[\"code\"] as AnySchema | undefined;\n const codeEnum = codeSchema?.[\"enum\"] as string[] | undefined;\n\n if (Array.isArray(codeEnum) && codeEnum.length === 1) {\n return codeEnum[0]!;\n }\n return null;\n}\n\n/**\n * Converts an error code like UNAUTHORIZED or NOT_FOUND to PascalCase.\n * UNAUTHORIZED -> Unauthorized\n * NOT_FOUND -> NotFound\n */\nexport function errorCodeToPascalCase(code: string): string {\n return code\n .split(\"_\")\n .map((part) => part.charAt(0) + part.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Generates a common error schema name from an error code.\n * UNAUTHORIZED -> UnauthorizedErrorSchema\n */\nexport function generateCommonErrorSchemaName(errorCode: string): string {\n return `${errorCodeToPascalCase(errorCode)}ErrorSchema`;\n}\n\n/**\n * Represents a common schema that appears multiple times.\n */\nexport interface CommonSchema {\n /** The canonical name for this schema */\n name: string;\n /** The schema definition */\n schema: AnySchema;\n /** The fingerprint for deduplication */\n fingerprint: string;\n /** Number of times this schema appears */\n count: number;\n}\n\n/**\n * Scans schemas and identifies those that appear multiple times.\n * Returns common schemas sorted by count (most common first).\n */\nexport function findCommonSchemas(\n schemas: Array<{ name: string; schema: AnySchema }>,\n minCount: number = 2,\n): CommonSchema[] {\n const fingerprints = new Map<\n string,\n { schema: AnySchema; names: string[]; errorCode: string | null }\n >();\n\n // Count occurrences of each unique schema\n for (const { name, schema } of schemas) {\n const fingerprint = getSchemaFingerprint(schema);\n const existing = fingerprints.get(fingerprint);\n\n if (existing) {\n existing.names.push(name);\n } else {\n fingerprints.set(fingerprint, {\n schema,\n names: [name],\n errorCode: extractErrorCode(schema),\n });\n }\n }\n\n // Filter to schemas appearing minCount+ times\n const commonSchemas: CommonSchema[] = [];\n for (const [fingerprint, data] of fingerprints) {\n if (data.names.length >= minCount) {\n // Generate a semantic name if it's an error schema, otherwise use first occurrence\n const name = data.errorCode\n ? generateCommonErrorSchemaName(data.errorCode)\n : data.names[0]!;\n\n commonSchemas.push({\n name,\n schema: data.schema,\n fingerprint,\n count: data.names.length,\n });\n }\n }\n\n // Sort by count descending (most common first)\n return commonSchemas.sort((a, b) => b.count - a.count);\n}\n","/**\n * Convert an OpenAPI v3 boolean schema to a Zod schema string\n */\nexport function convertOpenAPIBooleanToZod(_: { type: \"boolean\" }): string {\n return \"z.boolean()\";\n}\n","/**\n * Convert an OpenAPI v3 number/integer schema to a Zod schema string\n */\nexport function convertOpenAPINumberToZod(schema: {\n type: \"number\" | \"integer\";\n minimum?: number;\n maximum?: number;\n}): string {\n let result = \"z.number()\";\n if (schema.type === \"integer\") {\n result += \".int()\";\n }\n if (typeof schema.minimum === \"number\") {\n result += `.min(${schema.minimum})`;\n }\n if (typeof schema.maximum === \"number\") {\n result += `.max(${schema.maximum})`;\n }\n return result;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst SUPPORTED_STRING_FORMATS_MAP = {\n \"color-hex\": 1,\n date: 1,\n \"date-time\": 1,\n email: 1,\n \"iso-date\": 1,\n \"iso-date-time\": 1,\n objectid: 1,\n uri: 1,\n url: 1,\n uuid: 1,\n} as const;\n\nexport const SUPPORTED_STRING_FORMATS = Object.keys(\n SUPPORTED_STRING_FORMATS_MAP,\n) as unknown as keyof typeof SUPPORTED_STRING_FORMATS_MAP;\n\ntype SupportedStringFormat = typeof SUPPORTED_STRING_FORMATS;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ZodOpenApiRegistrationString<\n F extends SupportedStringFormat = SupportedStringFormat,\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n format: F;\n};\n\nexport type ZodOpenApiRegistrationStrings<\n Fs extends\n readonly SupportedStringFormat[] = readonly SupportedStringFormat[],\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n formats: Fs;\n};\n\nexport type ZodOpenApiRegistrationPrimitive = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n description?: string;\n type: \"number\" | \"integer\" | \"boolean\";\n};\n\nexport type ZodOpenApiRegistration =\n | ZodOpenApiRegistrationString\n | ZodOpenApiRegistrationStrings\n | ZodOpenApiRegistrationPrimitive;\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isStringRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationString {\n return reg.type === \"string\" && \"format\" in reg;\n}\n\nfunction isStringsRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationStrings {\n return reg.type === \"string\" && \"formats\" in reg;\n}\n\nfunction isSupportedStringFormat(\n format: string,\n): format is SupportedStringFormat {\n return Object.prototype.hasOwnProperty.call(SUPPORTED_STRING_FORMATS_MAP, format);\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\ntype TypeFormatPair = { type: string; format: string | undefined };\n\nfunction getTypeFormatPairs(reg: ZodOpenApiRegistration): TypeFormatPair[] {\n if (isStringRegistration(reg)) {\n return [{ type: \"string\", format: reg.format }];\n }\n\n if (isStringsRegistration(reg)) {\n return reg.formats.map((f) => ({ type: \"string\", format: f }));\n }\n\n return [];\n}\n\n// ============================================================================\n// Registry Class\n// ============================================================================\n\n/**\n * Global registry for mapping Zod schemas to OpenAPI schema representations\n */\nclass ZodSchemaRegistry {\n private readonly map = new Map<z.ZodTypeAny, ZodOpenApiRegistration>();\n\n /**\n * Register a Zod schema with its OpenAPI representation\n */\n register<F extends SupportedStringFormat>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationString<F>,\n ): void;\n register<Fs extends readonly SupportedStringFormat[]>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationStrings<Fs>,\n ): void;\n register(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationPrimitive,\n ): void;\n register(schema: z.ZodTypeAny, registration: ZodOpenApiRegistration): void {\n const newPairs = getTypeFormatPairs(registration);\n\n if (newPairs.length > 0) {\n for (const [existingSchema, existingRegistration] of this.map.entries()) {\n if (existingSchema === schema) continue;\n\n const existingPairs = getTypeFormatPairs(existingRegistration);\n for (const { type, format } of newPairs) {\n if (\n existingPairs.some((p) => p.type === type && p.format === format)\n ) {\n throw new Error(\n `duplicate Zod OpenAPI registration for (type, format)=('${type}', '${format as string}')`,\n );\n }\n }\n }\n }\n\n this.map.set(schema, registration);\n }\n\n /**\n * Get the OpenAPI schema for a given Zod schema\n */\n getOpenApiSchema(schema: z.ZodTypeAny): ZodOpenApiRegistration | undefined {\n return this.map.get(schema);\n }\n\n /**\n * Check if a Zod schema is registered\n */\n isRegistered(schema: z.ZodTypeAny): boolean {\n return this.map.has(schema);\n }\n\n /**\n * Clear all registered schemas\n */\n clear(): void {\n this.map.clear();\n }\n\n /**\n * Reverse-lookup helper: given a string format, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n ): string | undefined {\n if (!isSupportedStringFormat(format)) return undefined;\n for (const registration of this.map.values()) {\n if (registration.type !== \"string\") continue;\n\n if (\n isStringRegistration(registration) &&\n registration.format === format\n ) {\n return registration.schemaExportedVariableName;\n }\n\n if (\n isStringsRegistration(registration) &&\n registration.formats.includes(format)\n ) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n\n /**\n * Reverse-lookup helper: given a primitive type, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n ): string | undefined {\n for (const registration of this.map.values()) {\n if (registration.type === type) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n}\n\n// ============================================================================\n// Global Registry Instance\n// ============================================================================\n\nexport const schemaRegistry = new ZodSchemaRegistry();\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Helper function to register a Zod schema with its OpenAPI representation\n */\nexport function registerZodSchemaToOpenApiSchema(\n schema: z.ZodTypeAny,\n openApiSchema: ZodOpenApiRegistration,\n): void {\n schemaRegistry.register(schema, openApiSchema as any);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given string format\n */\nexport function getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForStringFormat(format);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given primitive type\n */\nexport function getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForPrimitiveType(type);\n}\n\n/**\n * Clear all registered schemas in the global registry\n */\nexport function clearZodSchemaToOpenApiSchemaRegistry(): void {\n schemaRegistry.clear();\n}\n","import {\n getSchemaExportedVariableNameForStringFormat,\n SUPPORTED_STRING_FORMATS,\n} from \"../registry\";\n\n/**\n * Convert an OpenAPI v3 string schema to a Zod schema string\n */\nexport function convertOpenAPIStringToZod(schema: {\n type: \"string\";\n format?: typeof SUPPORTED_STRING_FORMATS;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n enum?: string[];\n}): string {\n // Handle enum values\n if (schema.enum) {\n return `z.enum([${schema.enum.map((value) => `'${value}'`).join(\", \")}])`;\n }\n\n // Check for custom registered format schemas\n if (schema.format && SUPPORTED_STRING_FORMATS.includes(schema.format)) {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema.format,\n );\n\n // Use custom schema if registered (ignores other constraints)\n if (customSchemaName) {\n return customSchemaName;\n }\n }\n\n // Build string schema with format modifiers\n let zodSchema = \"z.string()\";\n\n if (schema.format) {\n zodSchema += getFormatModifier(schema.format);\n }\n\n // Apply length constraints\n if (typeof schema.minLength === \"number\") {\n zodSchema += `.min(${schema.minLength})`;\n }\n\n if (typeof schema.maxLength === \"number\") {\n zodSchema += `.max(${schema.maxLength})`;\n }\n\n // Apply pattern constraint\n if (typeof schema.pattern === \"string\") {\n zodSchema += `.regex(/${schema.pattern}/)`;\n }\n\n return zodSchema;\n}\n\n/**\n * Get the Zod modifier for built-in string formats\n */\nfunction getFormatModifier(format: string): string {\n switch (format) {\n case \"email\":\n return \".email()\";\n case \"url\":\n case \"uri\":\n return \".url()\";\n case \"uuid\":\n return \".uuid()\";\n case \"color-hex\":\n return \".regex(/^[a-fA-F0-9]{6}$/)\";\n default:\n return \"\";\n }\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIArrayToZod(\n schema: {\n type: \"array\";\n items?: any;\n minItems?: number;\n maxItems?: number;\n },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const item = schema.items;\n\n let itemZodString = \"z.unknown()\";\n if (item && typeof item === \"object\") {\n itemZodString = convertSchema(item);\n }\n\n let result = `z.array(${itemZodString})`;\n\n if (typeof schema.minItems === \"number\") {\n result += `.min(${schema.minItems})`;\n }\n if (typeof schema.maxItems === \"number\") {\n result += `.max(${schema.maxItems})`;\n }\n\n return result;\n}\n","import { AnySchema, OpenAPIObjectSchema } from \"./types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nexport function convertOpenAPIObjectToZod(\n schema: OpenAPIObjectSchema,\n convertSchema: (schema: AnySchema) => string,\n): string {\n const properties = schema.properties || {};\n const propertyNames = Object.keys(properties);\n\n if (propertyNames.length === 0) {\n if (schema.additionalProperties === false) {\n return \"z.object({}).strict()\";\n }\n return \"z.record(z.string(), z.unknown())\";\n }\n\n const requiredSet = new Set(schema.required || []);\n\n const entries: string[] = [];\n for (const [propName, propSchema] of Object.entries(properties)) {\n let zodProp = \"z.unknown()\";\n\n if (propSchema && typeof propSchema === \"object\") {\n zodProp = convertSchema(propSchema);\n }\n\n if (!requiredSet.has(propName)) {\n zodProp += \".optional()\";\n }\n\n entries.push(`${quotePropertyName(propName)}: ${zodProp}`);\n }\n\n let result = `z.object({ ${entries.join(\", \")} })`;\n\n if (schema.additionalProperties === false) {\n result += \".strict()\";\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIUnionToZod(\n schema: { oneOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.oneOf.map((item) => convertSchema(item));\n return `z.union([${items.join(\", \")}])`;\n}\n\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIIntersectionToZod(\n schema: { allOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.allOf.map((item) => convertSchema(item));\n\n if (schema.allOf.length === 0) return \"z.unknown()\";\n if (schema.allOf.length === 1) return convertSchema(schema.allOf[0]!);\n\n return `z.intersection(${items.join(\", \")})`;\n}\n\n","import { convertOpenAPIBooleanToZod } from \"./types/boolean\";\nimport { convertOpenAPINumberToZod } from \"./types/number\";\nimport { convertOpenAPIStringToZod } from \"./types/string\";\nimport { convertOpenAPIArrayToZod } from \"./types/array\";\nimport { convertOpenAPIObjectToZod } from \"./types/object\";\nimport { convertOpenAPIUnionToZod } from \"./types/union\";\nimport { convertOpenAPIIntersectionToZod } from \"./types/intersection\";\nimport type { AnySchema } from \"./types/types\";\n\nexport function convertSchemaToZodString(schema: AnySchema): string {\n if (!schema || typeof schema !== \"object\") return \"z.unknown()\";\n\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"z.unknown()\";\n if (match && match[1]) {\n result = `${match[1]}Schema`;\n }\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n return result;\n }\n let result: string = \"z.unknown()\";\n\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n result = convertOpenAPIUnionToZod(\n schema as { oneOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n result = convertOpenAPIIntersectionToZod(\n schema as { allOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else {\n switch (schema[\"type\"]) {\n case \"string\":\n result = convertOpenAPIStringToZod({\n enum: schema[\"enum\"],\n format: schema[\"format\"],\n maxLength: schema[\"maxLength\"],\n minLength: schema[\"minLength\"],\n pattern: schema[\"pattern\"],\n type: \"string\",\n });\n break;\n case \"number\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"number\",\n });\n break;\n case \"integer\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"integer\",\n });\n break;\n case \"boolean\":\n result = convertOpenAPIBooleanToZod({ type: \"boolean\" });\n break;\n case \"array\":\n result = convertOpenAPIArrayToZod(\n {\n items: schema[\"items\"],\n maxItems: schema[\"maxItems\"],\n minItems: schema[\"minItems\"],\n type: \"array\",\n },\n convertSchemaToZodString,\n );\n break;\n case \"object\":\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n break;\n default:\n if (schema[\"properties\"]) {\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n } else {\n result = \"z.unknown()\";\n }\n break;\n }\n }\n\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types/types\";\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"HEAD\" | \"OPTIONS\";\n\nexport interface RouteParameter {\n name: string;\n in: \"path\" | \"query\" | \"header\" | \"cookie\";\n required: boolean;\n schema: AnySchema;\n}\n\nexport interface RouteInfo {\n path: string;\n method: HttpMethod;\n parameters: RouteParameter[];\n requestBody?: AnySchema;\n responses: Record<string, AnySchema>;\n}\n\nexport interface RouteSchemaNames {\n paramsSchemaName?: string;\n querySchemaName?: string;\n headersSchemaName?: string;\n bodySchemaName?: string;\n responseSchemaName?: string;\n}\n\nfunction toUpperCaseMethod(method: string): HttpMethod {\n const upper = method.toUpperCase();\n if (\n upper === \"GET\" ||\n upper === \"POST\" ||\n upper === \"PUT\" ||\n upper === \"PATCH\" ||\n upper === \"DELETE\" ||\n upper === \"HEAD\" ||\n upper === \"OPTIONS\"\n ) {\n return upper as HttpMethod;\n }\n return \"GET\";\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: HttpMethod,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map(toPascalCase);\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\nexport function parseOpenApiPaths(\n openapi: Record<string, unknown>,\n): RouteInfo[] {\n const paths = (openapi as AnySchema)[\"paths\"] as\n | Record<string, AnySchema>\n | undefined;\n if (!paths) {\n return [];\n }\n\n const routes: RouteInfo[] = [];\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem || typeof pathItem !== \"object\") continue;\n\n const methods = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"head\",\n \"options\",\n ] as const;\n\n for (const method of methods) {\n const operation = pathItem[method] as AnySchema | undefined;\n if (!operation) continue;\n\n const parameters: RouteParameter[] = [];\n const responses: Record<string, AnySchema> = {};\n\n if (Array.isArray(pathItem[\"parameters\"])) {\n for (const param of pathItem[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n if (Array.isArray(operation[\"parameters\"])) {\n for (const param of operation[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n let requestBody: AnySchema | undefined;\n if (operation[\"requestBody\"]) {\n const rb = operation[\"requestBody\"];\n if (rb && typeof rb === \"object\") {\n const content = rb[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n requestBody = jsonContent[\"schema\"] || {};\n }\n }\n }\n }\n\n if (operation[\"responses\"] && typeof operation[\"responses\"] === \"object\") {\n for (const [statusCode, response] of Object.entries(\n operation[\"responses\"],\n )) {\n if (response && typeof response === \"object\") {\n const responseSchema = response as AnySchema;\n const content = responseSchema[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n const schema = jsonContent[\"schema\"];\n if (schema) {\n responses[statusCode] = schema;\n }\n }\n }\n }\n }\n }\n\n routes.push({\n path,\n method: toUpperCaseMethod(method),\n parameters,\n requestBody,\n responses,\n });\n }\n }\n\n return routes;\n}\n\nexport function generateRouteSchemaNames(\n route: RouteInfo,\n): RouteSchemaNames {\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n const successStatuses = Object.keys(route.responses).filter((s) =>\n s.startsWith(\"2\"),\n );\n\n const result: RouteSchemaNames = {\n responseSchemaName: successStatuses.length > 0\n ? generateRouteSchemaName(\n route.path,\n route.method,\n \"Response\",\n )\n : undefined,\n };\n\n if (pathParams.length > 0) {\n result.paramsSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Params\",\n );\n }\n\n if (queryParams.length > 0) {\n result.querySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Query\",\n );\n }\n\n if (headerParams.length > 0) {\n result.headersSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Headers\",\n );\n }\n\n if (route.requestBody) {\n result.bodySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Body\",\n );\n }\n\n return result;\n}\n\n","/**\n * Generates TypeScript interface/type strings from OpenAPI schemas.\n *\n * This produces concrete types that appear directly in .d.ts files,\n * rather than requiring z.infer<> resolution at the type level.\n */\n\nimport {\n getSchemaExportedVariableNameForPrimitiveType,\n getSchemaExportedVariableNameForStringFormat,\n} from \"./registry\";\nimport type { AnySchema } from \"./types/types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\ntype SchemaToTypeOptions = {\n outputSchemaNames?: Set<string>;\n};\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction toPascalCase(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\nexport function schemaExportNameToOutputAlias(name: string): string {\n return `${toPascalCase(name)}Output`;\n}\n\nfunction registerOutputSchemaName(\n schemaName: string,\n options?: SchemaToTypeOptions,\n): string {\n options?.outputSchemaNames?.add(schemaName);\n return schemaExportNameToOutputAlias(schemaName);\n}\n\nfunction getRegisteredOutputAlias(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string | undefined {\n if (!schema || typeof schema !== \"object\") return undefined;\n\n if (schema[\"type\"] === \"string\" && typeof schema[\"format\"] === \"string\") {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema[\"format\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n if (\n schema[\"type\"] === \"number\" ||\n schema[\"type\"] === \"integer\" ||\n schema[\"type\"] === \"boolean\"\n ) {\n const customSchemaName = getSchemaExportedVariableNameForPrimitiveType(\n schema[\"type\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n return undefined;\n}\n\n/**\n * Converts an OpenAPI schema to a TypeScript type string.\n *\n * @example\n * schemaToTypeString({ type: 'string' }) // => 'string'\n * schemaToTypeString({ type: 'object', properties: { id: { type: 'string' } } }) // => '{ id?: string }'\n */\nexport function schemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n if (!schema || typeof schema !== \"object\") return \"unknown\";\n\n // Handle $ref\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"unknown\";\n if (match && match[1]) {\n // Decode URI-encoded schema names (e.g., %20 -> space)\n result = decodeURIComponent(match[1]);\n }\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n return result;\n }\n\n let result: string = \"unknown\";\n\n // Handle oneOf (union)\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n const unionMembers = (schema[\"oneOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle allOf (intersection)\n else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n const intersectionMembers = (schema[\"allOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = intersectionMembers.length > 1\n ? `(${intersectionMembers.join(\" & \")})`\n : intersectionMembers[0] ?? \"unknown\";\n }\n // Handle anyOf (union, similar to oneOf)\n else if (\"anyOf\" in schema && Array.isArray(schema[\"anyOf\"])) {\n const unionMembers = (schema[\"anyOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle type-based schemas\n else {\n switch (schema[\"type\"]) {\n case \"string\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // String enum\n result = (schema[\"enum\"] as string[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"string\";\n }\n break;\n }\n case \"number\":\n case \"integer\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Numeric enum\n result = (schema[\"enum\"] as number[]).map((v) => String(v)).join(\" | \");\n } else {\n result = \"number\";\n }\n break;\n }\n case \"boolean\":\n result = getRegisteredOutputAlias(schema, options) ?? \"boolean\";\n break;\n case \"null\":\n result = \"null\";\n break;\n case \"array\":\n if (schema[\"items\"]) {\n const itemType = schemaToTypeString(schema[\"items\"] as AnySchema, options);\n result = `Array<${itemType}>`;\n } else {\n result = \"unknown[]\";\n }\n break;\n case \"object\":\n result = objectSchemaToTypeString(schema, options);\n break;\n default:\n // Try to detect object from properties\n if (schema[\"properties\"]) {\n result = objectSchemaToTypeString(schema, options);\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Untyped enum\n result = (schema[\"enum\"] as unknown[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"unknown\";\n }\n break;\n }\n }\n\n // Handle nullable\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n\n return result;\n}\n\n/**\n * Converts an OpenAPI object schema to a TypeScript object type string.\n */\nfunction objectSchemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n const additionalProperties = schema[\"additionalProperties\"];\n\n if (!properties && !additionalProperties) {\n return \"Record<string, unknown>\";\n }\n\n const propertyStrings: string[] = [];\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n propertyStrings.push(\n `${quotedName}${isRequired ? \"\" : \"?\"}: ${propType}`,\n );\n }\n }\n\n // Handle additionalProperties\n if (additionalProperties === true) {\n propertyStrings.push(\"[key: string]: unknown\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n propertyStrings.push(`[key: string]: ${additionalType}`);\n }\n\n return `{ ${propertyStrings.join(\"; \")} }`;\n}\n\n/**\n * Generates a full TypeScript interface declaration.\n *\n * @example\n * generateInterface('User', { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] })\n * // => 'export interface User { id: string; }'\n */\nexport function generateInterface(\n name: string,\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n\n // For non-object types, use type alias instead of interface\n if (schema[\"type\"] !== \"object\" && !properties) {\n return `export type ${name} = ${schemaToTypeString(schema, options)};`;\n }\n\n const lines: string[] = [];\n lines.push(`export interface ${name} {`);\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n lines.push(` ${quotedName}${isRequired ? \"\" : \"?\"}: ${propType};`);\n }\n }\n\n // Handle additionalProperties\n const additionalProperties = schema[\"additionalProperties\"];\n if (additionalProperties === true) {\n lines.push(\" [key: string]: unknown;\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n lines.push(` [key: string]: ${additionalType};`);\n }\n\n lines.push(\"}\");\n return lines.join(\"\\n\");\n}\n","import { topologicalSortSchemas } from \"./dependencies\";\nimport {\n createSchemaRegistry,\n findCommonSchemas,\n getSchemaFingerprint,\n preRegisterSchema,\n registerSchema,\n type SchemaRegistry,\n} from \"./schema-dedup\";\nimport { convertSchemaToZodString } from \"./to-zod\";\nimport type { AnySchema } from \"./types/types\";\nimport {\n parseOpenApiPaths,\n generateRouteSchemaNames,\n type RouteInfo,\n} from \"./routes\";\nimport { generateInterface, schemaExportNameToOutputAlias } from \"./interface-generator\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: string,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map((word) => {\n // Convert hyphenated words to PascalCase (e.g., \"timer-drafts\" -> \"TimerDrafts\")\n return word\n .split(/[-_]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase())\n .join(\"\");\n });\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\n/**\n * Result of route schema generation including declarations and name mappings.\n */\ninterface RouteSchemaResult {\n /** Schema declarations to be emitted */\n declarations: string[];\n /** Maps route-specific schema name to its canonical name (for deduplication) */\n schemaNameToCanonical: Map<string, string>;\n}\n\nfunction generateRouteSchemas(\n routes: RouteInfo[],\n convertSchema: (schema: AnySchema) => string,\n registry: SchemaRegistry,\n): RouteSchemaResult {\n const declarations: string[] = [];\n const schemaNameToCanonical = new Map<string, string>();\n const generatedNames = new Set<string>();\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n // Generate params schema with deduplication\n if (names.paramsSchemaName && pathParams.length > 0) {\n const paramsSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n pathParams.map((p) => [p.name, p.schema]),\n ),\n required: pathParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.paramsSchemaName,\n paramsSchema,\n );\n schemaNameToCanonical.set(names.paramsSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n const properties: string[] = [];\n for (const param of pathParams) {\n const zodExpr = convertSchema(param.schema);\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.paramsSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.paramsSchemaName !== canonicalName) {\n if (!generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n declarations.push(\n `export const ${names.paramsSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate query schema with deduplication\n if (names.querySchemaName && queryParams.length > 0) {\n const querySchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n queryParams.map((p) => [p.name, p.schema]),\n ),\n required: queryParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.querySchemaName,\n querySchema,\n );\n schemaNameToCanonical.set(names.querySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n const properties: string[] = [];\n for (const param of queryParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.querySchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.querySchemaName !== canonicalName) {\n if (!generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n declarations.push(\n `export const ${names.querySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate headers schema with deduplication\n if (names.headersSchemaName && headerParams.length > 0) {\n const headersSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n headerParams.map((p) => [p.name, p.schema]),\n ),\n required: headerParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.headersSchemaName,\n headersSchema,\n );\n schemaNameToCanonical.set(names.headersSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n const properties: string[] = [];\n for (const param of headerParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.headersSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.headersSchemaName !== canonicalName) {\n if (!generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n declarations.push(\n `export const ${names.headersSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate body schema with deduplication\n if (names.bodySchemaName && route.requestBody) {\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.bodySchemaName,\n route.requestBody,\n );\n schemaNameToCanonical.set(names.bodySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n const zodExpr = convertSchema(route.requestBody);\n declarations.push(`export const ${names.bodySchemaName} = ${zodExpr};`);\n } else if (!isNew && names.bodySchemaName !== canonicalName) {\n if (!generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n declarations.push(\n `export const ${names.bodySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate schemas for ALL status codes with deduplication\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n responseSchemaName,\n responseSchema,\n );\n schemaNameToCanonical.set(responseSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n const zodExpr = convertSchema(responseSchema);\n declarations.push(`export const ${responseSchemaName} = ${zodExpr};`);\n } else if (!isNew && responseSchemaName !== canonicalName) {\n if (!generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n declarations.push(\n `export const ${responseSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n }\n\n return { declarations, schemaNameToCanonical };\n}\n\nfunction generateRequestResponseObjects(\n routes: RouteInfo[],\n schemaNameToCanonical: Map<string, string>,\n): string[] {\n const lines: string[] = [];\n const requestPaths: Record<string, Record<string, string[]>> = {};\n const responsePaths: Record<\n string,\n Record<string, Record<string, string>>\n > = {};\n\n /**\n * Resolves a schema name to its canonical name if it exists,\n * otherwise returns the original name.\n */\n const resolveSchemaName = (name: string): string => {\n return schemaNameToCanonical.get(name) ?? name;\n };\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n if (!requestPaths[route.path]) {\n requestPaths[route.path] = {};\n }\n const requestMethodObj = requestPaths[route.path]!;\n if (!requestMethodObj[route.method]) {\n requestMethodObj[route.method] = [];\n }\n\n const requestParts: string[] = [];\n if (names.paramsSchemaName && pathParams.length > 0) {\n requestParts.push(\n `params: ${resolveSchemaName(names.paramsSchemaName)}`,\n );\n }\n if (names.querySchemaName && queryParams.length > 0) {\n requestParts.push(`query: ${resolveSchemaName(names.querySchemaName)}`);\n }\n if (names.headersSchemaName && headerParams.length > 0) {\n requestParts.push(\n `headers: ${resolveSchemaName(names.headersSchemaName)}`,\n );\n }\n if (names.bodySchemaName && route.requestBody) {\n requestParts.push(`body: ${resolveSchemaName(names.bodySchemaName)}`);\n }\n\n if (requestParts.length > 0) {\n requestMethodObj[route.method] = requestParts;\n }\n\n // Store all status codes in nested structure\n if (!responsePaths[route.path]) {\n responsePaths[route.path] = {};\n }\n const responseMethodObj = responsePaths[route.path]!;\n if (!responseMethodObj[route.method]) {\n responseMethodObj[route.method] = {};\n }\n\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n // Use canonical name for the Response object\n responseMethodObj[route.method]![statusCode] =\n resolveSchemaName(responseSchemaName);\n }\n }\n\n lines.push(\"export const Request = {\");\n for (const [path, methods] of Object.entries(requestPaths)) {\n const methodEntries = Object.entries(methods).filter(\n ([, parts]) => parts.length > 0,\n );\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, parts] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const part of parts) {\n lines.push(` ${part},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n lines.push(\"\");\n\n lines.push(\"export const Response = {\");\n for (const [path, methods] of Object.entries(responsePaths)) {\n const methodEntries = Object.entries(methods);\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, statusCodes] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const [statusCode, schemaName] of Object.entries(statusCodes)) {\n lines.push(` '${statusCode}': ${schemaName},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n\n return lines;\n}\n\n/**\n * Collects all response schemas from routes for common schema detection.\n */\nfunction collectRouteSchemas(\n routes: RouteInfo[],\n): Array<{ name: string; schema: AnySchema }> {\n const collected: Array<{ name: string; schema: AnySchema }> = [];\n\n for (const route of routes) {\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n collected.push({ name: responseSchemaName, schema: responseSchema });\n }\n }\n\n return collected;\n}\n\nexport const openApiToZodTsCode = (\n openapi: Record<string, unknown>,\n customImportLines?: string[],\n options?: { includeRoutes?: boolean },\n): string => {\n const components = (openapi as AnySchema)[\"components\"] as\n | AnySchema\n | undefined;\n const schemas: Record<string, AnySchema> =\n (components?.[\"schemas\"] as Record<string, AnySchema>) ?? {};\n\n const lines: string[] = [];\n lines.push(\"/**\");\n lines.push(\" * This file was automatically generated from OpenAPI schema\");\n lines.push(\" * Do not manually edit this file\");\n lines.push(\" */\");\n lines.push(\"\");\n lines.push(\"import { z } from 'zod';\");\n lines.push(...(customImportLines ?? []));\n lines.push(\"\");\n\n // Type assertion helper for compile-time verification\n lines.push(\"// Type assertion helper - verifies interface matches schema at compile time\");\n lines.push(\"type _AssertEqual<T, U> = [T] extends [U] ? ([U] extends [T] ? true : never) : never;\");\n lines.push(\"\");\n\n // Create registry for schema deduplication\n const registry = createSchemaRegistry();\n\n const sortedSchemaNames = topologicalSortSchemas(schemas);\n\n // Collect all type assertions to emit after all schemas\n const typeAssertions: string[] = [];\n const outputSchemaNames = new Set<string>();\n const schemaBlocks: string[] = [];\n\n for (const name of sortedSchemaNames) {\n const schema = schemas[name];\n if (schema) {\n const zodExpr = convertSchemaToZodString(schema);\n const schemaName = `${name}Schema`;\n const typeName = name;\n\n // Generate interface (concrete type in .d.ts)\n schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));\n\n // Generate schema with ZodType<T> annotation (simple type in .d.ts)\n schemaBlocks.push(`export const ${schemaName}: z.ZodType<${typeName}> = ${zodExpr};`);\n schemaBlocks.push(\"\");\n\n // Add type assertion to verify interface matches schema\n typeAssertions.push(`type _Assert${typeName} = _AssertEqual<${typeName}, z.infer<typeof ${schemaName}>>;`);\n\n // Register component schemas so they can be referenced by route schemas\n const fingerprint = getSchemaFingerprint(schema);\n preRegisterSchema(registry, schemaName, fingerprint);\n }\n }\n\n if (outputSchemaNames.size > 0) {\n lines.push(\"// Zod output aliases for registered schemas\");\n for (const schemaName of outputSchemaNames) {\n const aliasName = schemaExportNameToOutputAlias(schemaName);\n lines.push(`type ${aliasName} = z.output<typeof ${schemaName}>;`);\n }\n lines.push(\"\");\n }\n\n lines.push(...schemaBlocks);\n\n // Emit all type assertions\n if (typeAssertions.length > 0) {\n lines.push(\"// Compile-time type assertions - ensure interfaces match schemas\");\n lines.push(typeAssertions.join(\"\\n\"));\n lines.push(\"\");\n }\n\n if (options?.includeRoutes) {\n const routes = parseOpenApiPaths(openapi);\n if (routes.length > 0) {\n // Find common schemas that appear multiple times (for error responses, etc.)\n const routeSchemaList = collectRouteSchemas(routes);\n const commonSchemas = findCommonSchemas(routeSchemaList, 2);\n\n // Generate common schemas first (e.g., UnauthorizedErrorSchema, NotFoundErrorSchema)\n if (commonSchemas.length > 0) {\n lines.push(\"// Common Error Schemas (deduplicated)\");\n for (const common of commonSchemas) {\n const zodExpr = convertSchemaToZodString(common.schema);\n lines.push(`export const ${common.name} = ${zodExpr};`);\n // Pre-register so route schemas reference this instead of duplicating\n preRegisterSchema(registry, common.name, common.fingerprint);\n }\n lines.push(\"\");\n }\n\n // Generate route schemas with deduplication\n const { declarations, schemaNameToCanonical } = generateRouteSchemas(\n routes,\n convertSchemaToZodString,\n registry,\n );\n\n if (declarations.length > 0) {\n lines.push(\"// Route Schemas\");\n lines.push(...declarations);\n lines.push(\"\");\n\n // Generate Request/Response objects using canonical names\n const requestResponseObjs = generateRequestResponseObjects(\n routes,\n schemaNameToCanonical,\n );\n lines.push(...requestResponseObjs);\n }\n }\n }\n\n return lines.join(\"\\n\");\n};\n"],"mappings":"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","names":["result","validIdentifierRegex","quotePropertyName","toPascalCase","result","validIdentifierRegex","quotePropertyName","generateRouteSchemaName"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/dependencies.ts","../src/schema-dedup.ts","../src/types/boolean.ts","../src/types/number.ts","../src/registry.ts","../src/types/string.ts","../src/types/array.ts","../src/types/object.ts","../src/types/union.ts","../src/types/intersection.ts","../src/to-zod.ts","../src/routes.ts","../src/interface-generator.ts","../src/to-typescript.ts"],"sourcesContent":["export { openApiToZodTsCode } from \"./to-typescript.js\";\nexport {\n registerZodSchemaToOpenApiSchema,\n clearZodSchemaToOpenApiSchemaRegistry,\n getSchemaExportedVariableNameForStringFormat,\n SUPPORTED_STRING_FORMATS,\n schemaRegistry,\n} from \"./registry.js\";\nexport type {\n ZodOpenApiRegistrationString,\n ZodOpenApiRegistrationStrings,\n ZodOpenApiRegistrationPrimitive,\n ZodOpenApiRegistration,\n} from \"./registry.js\";\nexport { convertSchemaToZodString } from \"./to-zod.js\";\nexport { generateInterface, schemaToTypeString } from \"./interface-generator.js\";\nexport {\n parseOpenApiPaths,\n generateRouteSchemaNames,\n} from \"./routes.js\";\nexport type {\n HttpMethod,\n RouteParameter,\n RouteInfo,\n RouteSchemaNames,\n} from \"./routes.js\";\nexport type { AnySchema, OpenAPIObjectSchema } from \"./types/types.js\";\n\n","import type { AnySchema } from \"./types/types\";\n\n/**\n * Extracts all schema references ($ref) from an OpenAPI schema by recursively\n * traversing its structure.\n *\n * This function is used during the OpenAPI-to-Zod conversion process to identify\n * which schemas a given schema depends on. It traverses all OpenAPI schema\n * structures including objects, arrays, unions (oneOf), intersections (allOf),\n * conditionals (if/then/else), and discriminator mappings to find all $ref\n * references that point to other schemas in the components/schemas section.\n *\n * The extracted dependency names are used by `topologicalSortSchemas` to build\n * a dependency graph and determine the correct order for generating Zod schemas,\n * ensuring that referenced schemas are defined before they are used in the\n * generated TypeScript code.\n *\n * @param schema - The OpenAPI schema to extract dependencies from\n * @returns An array of schema names that this schema references (via $ref)\n */\nexport function extractSchemaDependencies(schema: AnySchema): string[] {\n const dependencies: Set<string> = new Set();\n const visited = new WeakSet();\n\n function traverse(obj: any): void {\n if (!obj || typeof obj !== \"object\") return;\n\n if (visited.has(obj)) return;\n visited.add(obj);\n\n if (obj[\"$ref\"] && typeof obj[\"$ref\"] === \"string\") {\n const match = (obj[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n if (match && match[1]) {\n dependencies.add(decodeURIComponent(match[1]));\n }\n return;\n }\n\n if (Array.isArray(obj)) {\n obj.forEach(traverse);\n return;\n }\n\n if (obj.properties && typeof obj.properties === \"object\") {\n for (const propValue of Object.values(obj.properties)) {\n traverse(propValue);\n }\n }\n\n const schemaKeys = [\n \"items\",\n \"oneOf\",\n \"allOf\",\n \"anyOf\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n \"prefixItems\",\n \"contains\",\n \"propertyNames\",\n \"dependentSchemas\",\n ];\n\n for (const key of schemaKeys) {\n if (obj[key]) {\n traverse(obj[key]);\n }\n }\n\n if (\n obj.additionalProperties &&\n typeof obj.additionalProperties === \"object\"\n ) {\n traverse(obj.additionalProperties);\n }\n\n if (obj.discriminator?.mapping) {\n Object.values(obj.discriminator.mapping).forEach(traverse);\n }\n }\n\n traverse(schema);\n return Array.from(dependencies);\n}\n\n/**\n * Sorts OpenAPI schemas topologically based on their dependencies to ensure\n * correct generation order.\n *\n * When converting OpenAPI schemas to Zod schemas and generating TypeScript code,\n * schemas must be defined before they are referenced. For example, if `UserSchema`\n * references `ProfileSchema` (via $ref), then `ProfileSchema` must be generated\n * before `UserSchema` to avoid \"undefined variable\" errors in the generated code.\n *\n * This function uses Kahn's algorithm for topological sorting to order schemas\n * such that all dependencies come before their dependents. It:\n * 1. Extracts dependencies for each schema using `extractSchemaDependencies`\n * 2. Builds a dependency graph and computes in-degrees\n * 3. Sorts schemas starting with those that have no dependencies (in-degree 0)\n * 4. Handles circular dependencies gracefully by appending any remaining schemas\n * that couldn't be sorted (though this indicates a problematic schema structure)\n *\n * This function is called by `openApiToZodTsCode` to determine the order in which\n * schemas should be converted and emitted in the generated TypeScript file.\n *\n * @param schemas - A record mapping schema names to their OpenAPI schema definitions\n * @returns An array of schema names sorted in topological order (dependencies before dependents)\n */\nexport function topologicalSortSchemas(\n schemas: Record<string, AnySchema>,\n): string[] {\n const schemaNames = Object.keys(schemas);\n const dependencies: Map<string, string[]> = new Map();\n const inDegree: Map<string, number> = new Map();\n const sorted: string[] = [];\n const queue: string[] = [];\n const dependents: Map<string, string[]> = new Map();\n\n for (const name of schemaNames) {\n dependencies.set(name, []);\n dependents.set(name, []);\n inDegree.set(name, 0);\n }\n\n for (const name of schemaNames) {\n const schemaValue = schemas[name];\n if (schemaValue) {\n const deps = extractSchemaDependencies(schemaValue);\n const validDeps = deps.filter((dep) => schemaNames.includes(dep));\n dependencies.set(name, validDeps);\n\n for (const dep of validDeps) {\n const currentDependents = dependents.get(dep) || [];\n currentDependents.push(name);\n dependents.set(dep, currentDependents);\n }\n }\n }\n\n for (const [name, deps] of dependencies.entries()) {\n inDegree.set(name, deps.length);\n }\n\n for (const [name, degree] of inDegree.entries()) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n sorted.push(current);\n\n const currentDependents = dependents.get(current) || [];\n for (const dependent of currentDependents) {\n const newDegree = (inDegree.get(dependent) || 0) - 1;\n inDegree.set(dependent, newDegree);\n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n if (sorted.length !== schemaNames.length) {\n for (const name of schemaNames) {\n if (!sorted.includes(name)) {\n sorted.push(name);\n }\n }\n }\n\n return sorted;\n}\n","import type { AnySchema } from \"./types/types\";\n\n/**\n * Schema deduplication utilities for optimizing generated TypeScript types.\n *\n * This module provides fingerprinting and registry functionality to detect\n * structurally identical schemas and generate them only once, reducing\n * memory usage in consuming TypeScript projects.\n */\n\n/**\n * Recursively sorts an object's keys to create a stable representation.\n * This ensures that {a: 1, b: 2} and {b: 2, a: 1} produce the same fingerprint.\n */\nfunction sortObjectDeep(obj: unknown): unknown {\n if (obj === null || typeof obj !== \"object\") return obj;\n if (Array.isArray(obj)) return obj.map(sortObjectDeep);\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObjectDeep((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n}\n\n/**\n * Generates a canonical fingerprint for an OpenAPI schema.\n * Identical schemas will produce identical fingerprints.\n */\nexport function getSchemaFingerprint(schema: AnySchema): string {\n return JSON.stringify(sortObjectDeep(schema));\n}\n\n/**\n * Registry for tracking unique schemas and their canonical names.\n */\nexport interface SchemaRegistry {\n /** Map from fingerprint to the first schema name that used it */\n fingerprintToName: Map<string, string>;\n /** Map from schema name to its fingerprint (for reverse lookup) */\n nameToFingerprint: Map<string, string>;\n}\n\n/**\n * Creates a new empty schema registry.\n */\nexport function createSchemaRegistry(): SchemaRegistry {\n return {\n fingerprintToName: new Map(),\n nameToFingerprint: new Map(),\n };\n}\n\n/**\n * Result of registering a schema.\n */\nexport interface RegisterSchemaResult {\n /** Whether this is a new unique schema */\n isNew: boolean;\n /** The canonical name for this schema (may be different from input name if duplicate) */\n canonicalName: string;\n}\n\n/**\n * Registers a schema in the registry. If an identical schema already exists,\n * returns the existing canonical name instead.\n */\nexport function registerSchema(\n registry: SchemaRegistry,\n name: string,\n schema: AnySchema,\n): RegisterSchemaResult {\n const fingerprint = getSchemaFingerprint(schema);\n\n const existing = registry.fingerprintToName.get(fingerprint);\n if (existing) {\n return { isNew: false, canonicalName: existing };\n }\n\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n return { isNew: true, canonicalName: name };\n}\n\n/**\n * Pre-registers a schema with a specific fingerprint.\n * Used for common schemas that should take priority.\n */\nexport function preRegisterSchema(\n registry: SchemaRegistry,\n name: string,\n fingerprint: string,\n): void {\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n}\n\n/**\n * Extracts the error code from an OpenAPI error schema.\n * Looks for patterns like: { error: { code: enum(['UNAUTHORIZED']) } }\n */\nexport function extractErrorCode(schema: AnySchema): string | null {\n const properties = schema?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const errorObj = properties?.[\"error\"] as AnySchema | undefined;\n const errorProps = errorObj?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const codeSchema = errorProps?.[\"code\"] as AnySchema | undefined;\n const codeEnum = codeSchema?.[\"enum\"] as string[] | undefined;\n\n if (Array.isArray(codeEnum) && codeEnum.length === 1) {\n return codeEnum[0]!;\n }\n return null;\n}\n\n/**\n * Converts an error code like UNAUTHORIZED or NOT_FOUND to PascalCase.\n * UNAUTHORIZED -> Unauthorized\n * NOT_FOUND -> NotFound\n */\nexport function errorCodeToPascalCase(code: string): string {\n return code\n .split(\"_\")\n .map((part) => part.charAt(0) + part.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Generates a common error schema name from an error code.\n * UNAUTHORIZED -> UnauthorizedErrorSchema\n */\nexport function generateCommonErrorSchemaName(errorCode: string): string {\n return `${errorCodeToPascalCase(errorCode)}ErrorSchema`;\n}\n\n/**\n * Represents a common schema that appears multiple times.\n */\nexport interface CommonSchema {\n /** The canonical name for this schema */\n name: string;\n /** The schema definition */\n schema: AnySchema;\n /** The fingerprint for deduplication */\n fingerprint: string;\n /** Number of times this schema appears */\n count: number;\n}\n\n/**\n * Scans schemas and identifies those that appear multiple times.\n * Returns common schemas sorted by count (most common first).\n */\nexport function findCommonSchemas(\n schemas: Array<{ name: string; schema: AnySchema }>,\n minCount: number = 2,\n): CommonSchema[] {\n const fingerprints = new Map<\n string,\n { schema: AnySchema; names: string[]; errorCode: string | null }\n >();\n\n // Count occurrences of each unique schema\n for (const { name, schema } of schemas) {\n const fingerprint = getSchemaFingerprint(schema);\n const existing = fingerprints.get(fingerprint);\n\n if (existing) {\n existing.names.push(name);\n } else {\n fingerprints.set(fingerprint, {\n schema,\n names: [name],\n errorCode: extractErrorCode(schema),\n });\n }\n }\n\n // Filter to schemas appearing minCount+ times\n const commonSchemas: CommonSchema[] = [];\n for (const [fingerprint, data] of fingerprints) {\n if (data.names.length >= minCount) {\n // Generate a semantic name if it's an error schema, otherwise use first occurrence\n const name = data.errorCode\n ? generateCommonErrorSchemaName(data.errorCode)\n : data.names[0]!;\n\n commonSchemas.push({\n name,\n schema: data.schema,\n fingerprint,\n count: data.names.length,\n });\n }\n }\n\n // Sort by count descending (most common first)\n return commonSchemas.sort((a, b) => b.count - a.count);\n}\n","/**\n * Convert an OpenAPI v3 boolean schema to a Zod schema string\n */\nexport function convertOpenAPIBooleanToZod(_: { type: \"boolean\" }): string {\n return \"z.boolean()\";\n}\n","/**\n * Convert an OpenAPI v3 number/integer schema to a Zod schema string\n */\nexport function convertOpenAPINumberToZod(schema: {\n type: \"number\" | \"integer\";\n minimum?: number;\n maximum?: number;\n}): string {\n let result = \"z.number()\";\n if (schema.type === \"integer\") {\n result += \".int()\";\n }\n if (typeof schema.minimum === \"number\") {\n result += `.min(${schema.minimum})`;\n }\n if (typeof schema.maximum === \"number\") {\n result += `.max(${schema.maximum})`;\n }\n return result;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst SUPPORTED_STRING_FORMATS_MAP = {\n \"color-hex\": 1,\n date: 1,\n \"date-time\": 1,\n email: 1,\n \"iso-date\": 1,\n \"iso-date-time\": 1,\n objectid: 1,\n uri: 1,\n url: 1,\n uuid: 1,\n} as const;\n\nexport const SUPPORTED_STRING_FORMATS = Object.keys(\n SUPPORTED_STRING_FORMATS_MAP,\n) as unknown as keyof typeof SUPPORTED_STRING_FORMATS_MAP;\n\ntype SupportedStringFormat = typeof SUPPORTED_STRING_FORMATS;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ZodOpenApiRegistrationString<\n F extends SupportedStringFormat = SupportedStringFormat,\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n format: F;\n};\n\nexport type ZodOpenApiRegistrationStrings<\n Fs extends\n readonly SupportedStringFormat[] = readonly SupportedStringFormat[],\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n formats: Fs;\n};\n\nexport type ZodOpenApiRegistrationPrimitive = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n description?: string;\n type: \"number\" | \"integer\" | \"boolean\";\n};\n\nexport type ZodOpenApiRegistration =\n | ZodOpenApiRegistrationString\n | ZodOpenApiRegistrationStrings\n | ZodOpenApiRegistrationPrimitive;\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isStringRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationString {\n return reg.type === \"string\" && \"format\" in reg;\n}\n\nfunction isStringsRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationStrings {\n return reg.type === \"string\" && \"formats\" in reg;\n}\n\nfunction isSupportedStringFormat(\n format: string,\n): format is SupportedStringFormat {\n return Object.prototype.hasOwnProperty.call(SUPPORTED_STRING_FORMATS_MAP, format);\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\ntype TypeFormatPair = { type: string; format: string | undefined };\n\nfunction getTypeFormatPairs(reg: ZodOpenApiRegistration): TypeFormatPair[] {\n if (isStringRegistration(reg)) {\n return [{ type: \"string\", format: reg.format }];\n }\n\n if (isStringsRegistration(reg)) {\n return reg.formats.map((f) => ({ type: \"string\", format: f }));\n }\n\n return [];\n}\n\n// ============================================================================\n// Registry Class\n// ============================================================================\n\n/**\n * Global registry for mapping Zod schemas to OpenAPI schema representations\n */\nclass ZodSchemaRegistry {\n private readonly map = new Map<z.ZodTypeAny, ZodOpenApiRegistration>();\n\n /**\n * Register a Zod schema with its OpenAPI representation\n */\n register<F extends SupportedStringFormat>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationString<F>,\n ): void;\n register<Fs extends readonly SupportedStringFormat[]>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationStrings<Fs>,\n ): void;\n register(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationPrimitive,\n ): void;\n register(schema: z.ZodTypeAny, registration: ZodOpenApiRegistration): void {\n const newPairs = getTypeFormatPairs(registration);\n\n if (newPairs.length > 0) {\n for (const [existingSchema, existingRegistration] of this.map.entries()) {\n if (existingSchema === schema) continue;\n\n const existingPairs = getTypeFormatPairs(existingRegistration);\n for (const { type, format } of newPairs) {\n if (\n existingPairs.some((p) => p.type === type && p.format === format)\n ) {\n throw new Error(\n `duplicate Zod OpenAPI registration for (type, format)=('${type}', '${format as string}')`,\n );\n }\n }\n }\n }\n\n this.map.set(schema, registration);\n }\n\n /**\n * Get the OpenAPI schema for a given Zod schema\n */\n getOpenApiSchema(schema: z.ZodTypeAny): ZodOpenApiRegistration | undefined {\n return this.map.get(schema);\n }\n\n /**\n * Check if a Zod schema is registered\n */\n isRegistered(schema: z.ZodTypeAny): boolean {\n return this.map.has(schema);\n }\n\n /**\n * Clear all registered schemas\n */\n clear(): void {\n this.map.clear();\n }\n\n /**\n * Reverse-lookup helper: given a string format, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n ): string | undefined {\n if (!isSupportedStringFormat(format)) return undefined;\n for (const registration of this.map.values()) {\n if (registration.type !== \"string\") continue;\n\n if (\n isStringRegistration(registration) &&\n registration.format === format\n ) {\n return registration.schemaExportedVariableName;\n }\n\n if (\n isStringsRegistration(registration) &&\n registration.formats.includes(format)\n ) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n\n /**\n * Reverse-lookup helper: given a primitive type, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n ): string | undefined {\n for (const registration of this.map.values()) {\n if (registration.type === type) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n}\n\n// ============================================================================\n// Global Registry Instance\n// ============================================================================\n\nexport const schemaRegistry = new ZodSchemaRegistry();\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Helper function to register a Zod schema with its OpenAPI representation\n */\nexport function registerZodSchemaToOpenApiSchema(\n schema: z.ZodTypeAny,\n openApiSchema: ZodOpenApiRegistration,\n): void {\n schemaRegistry.register(schema, openApiSchema as any);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given string format\n */\nexport function getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForStringFormat(format);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given primitive type\n */\nexport function getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForPrimitiveType(type);\n}\n\n/**\n * Clear all registered schemas in the global registry\n */\nexport function clearZodSchemaToOpenApiSchemaRegistry(): void {\n schemaRegistry.clear();\n}\n","import {\n getSchemaExportedVariableNameForStringFormat,\n SUPPORTED_STRING_FORMATS,\n} from \"../registry\";\n\n/**\n * Convert an OpenAPI v3 string schema to a Zod schema string\n */\nexport function convertOpenAPIStringToZod(schema: {\n type: \"string\";\n format?: typeof SUPPORTED_STRING_FORMATS;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n enum?: string[];\n}): string {\n // Handle enum values\n if (schema.enum) {\n return `z.enum([${schema.enum.map((value) => `'${value}'`).join(\", \")}])`;\n }\n\n // Check for custom registered format schemas\n if (schema.format && SUPPORTED_STRING_FORMATS.includes(schema.format)) {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema.format,\n );\n\n // Use custom schema if registered (ignores other constraints)\n if (customSchemaName) {\n return customSchemaName;\n }\n }\n\n // Build string schema with format modifiers\n let zodSchema = \"z.string()\";\n\n if (schema.format) {\n zodSchema += getFormatModifier(schema.format);\n }\n\n // Apply length constraints\n if (typeof schema.minLength === \"number\") {\n zodSchema += `.min(${schema.minLength})`;\n }\n\n if (typeof schema.maxLength === \"number\") {\n zodSchema += `.max(${schema.maxLength})`;\n }\n\n // Apply pattern constraint\n if (typeof schema.pattern === \"string\") {\n zodSchema += `.regex(/${schema.pattern}/)`;\n }\n\n return zodSchema;\n}\n\n/**\n * Get the Zod modifier for built-in string formats\n */\nfunction getFormatModifier(format: string): string {\n switch (format) {\n case \"email\":\n return \".email()\";\n case \"url\":\n case \"uri\":\n return \".url()\";\n case \"uuid\":\n return \".uuid()\";\n case \"color-hex\":\n return \".regex(/^[a-fA-F0-9]{6}$/)\";\n default:\n return \"\";\n }\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIArrayToZod(\n schema: {\n type: \"array\";\n items?: any;\n minItems?: number;\n maxItems?: number;\n },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const item = schema.items;\n\n let itemZodString = \"z.unknown()\";\n if (item && typeof item === \"object\") {\n itemZodString = convertSchema(item);\n }\n\n let result = `z.array(${itemZodString})`;\n\n if (typeof schema.minItems === \"number\") {\n result += `.min(${schema.minItems})`;\n }\n if (typeof schema.maxItems === \"number\") {\n result += `.max(${schema.maxItems})`;\n }\n\n return result;\n}\n","import { AnySchema, OpenAPIObjectSchema } from \"./types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nexport function convertOpenAPIObjectToZod(\n schema: OpenAPIObjectSchema,\n convertSchema: (schema: AnySchema) => string,\n): string {\n const properties = schema.properties || {};\n const propertyNames = Object.keys(properties);\n\n if (propertyNames.length === 0) {\n if (schema.additionalProperties === false) {\n return \"z.object({}).strict()\";\n }\n return \"z.record(z.string(), z.unknown())\";\n }\n\n const requiredSet = new Set(schema.required || []);\n\n const entries: string[] = [];\n for (const [propName, propSchema] of Object.entries(properties)) {\n let zodProp = \"z.unknown()\";\n\n if (propSchema && typeof propSchema === \"object\") {\n zodProp = convertSchema(propSchema);\n }\n\n if (!requiredSet.has(propName)) {\n zodProp += \".optional()\";\n }\n\n entries.push(`${quotePropertyName(propName)}: ${zodProp}`);\n }\n\n let result = `z.object({ ${entries.join(\", \")} })`;\n\n if (schema.additionalProperties === false) {\n result += \".strict()\";\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIUnionToZod(\n schema: { oneOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.oneOf.map((item) => convertSchema(item));\n return `z.union([${items.join(\", \")}])`;\n}\n\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIIntersectionToZod(\n schema: { allOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.allOf.map((item) => convertSchema(item));\n\n if (schema.allOf.length === 0) return \"z.unknown()\";\n if (schema.allOf.length === 1) return convertSchema(schema.allOf[0]!);\n\n return `z.intersection(${items.join(\", \")})`;\n}\n\n","import { convertOpenAPIBooleanToZod } from \"./types/boolean\";\nimport { convertOpenAPINumberToZod } from \"./types/number\";\nimport { convertOpenAPIStringToZod } from \"./types/string\";\nimport { convertOpenAPIArrayToZod } from \"./types/array\";\nimport { convertOpenAPIObjectToZod } from \"./types/object\";\nimport { convertOpenAPIUnionToZod } from \"./types/union\";\nimport { convertOpenAPIIntersectionToZod } from \"./types/intersection\";\nimport type { AnySchema } from \"./types/types\";\n\nexport function convertSchemaToZodString(schema: AnySchema): string {\n if (!schema || typeof schema !== \"object\") return \"z.unknown()\";\n\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"z.unknown()\";\n if (match && match[1]) {\n result = `${match[1]}Schema`;\n }\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n return result;\n }\n let result: string = \"z.unknown()\";\n\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n result = convertOpenAPIUnionToZod(\n schema as { oneOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n result = convertOpenAPIIntersectionToZod(\n schema as { allOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else {\n switch (schema[\"type\"]) {\n case \"string\":\n result = convertOpenAPIStringToZod({\n enum: schema[\"enum\"],\n format: schema[\"format\"],\n maxLength: schema[\"maxLength\"],\n minLength: schema[\"minLength\"],\n pattern: schema[\"pattern\"],\n type: \"string\",\n });\n break;\n case \"number\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"number\",\n });\n break;\n case \"integer\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"integer\",\n });\n break;\n case \"boolean\":\n result = convertOpenAPIBooleanToZod({ type: \"boolean\" });\n break;\n case \"array\":\n result = convertOpenAPIArrayToZod(\n {\n items: schema[\"items\"],\n maxItems: schema[\"maxItems\"],\n minItems: schema[\"minItems\"],\n type: \"array\",\n },\n convertSchemaToZodString,\n );\n break;\n case \"object\":\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n break;\n default:\n if (schema[\"properties\"]) {\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n } else {\n result = \"z.unknown()\";\n }\n break;\n }\n }\n\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types/types\";\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"HEAD\" | \"OPTIONS\";\n\nexport interface RouteParameter {\n name: string;\n in: \"path\" | \"query\" | \"header\" | \"cookie\";\n required: boolean;\n schema: AnySchema;\n}\n\nexport interface RouteInfo {\n path: string;\n method: HttpMethod;\n parameters: RouteParameter[];\n requestBody?: AnySchema;\n responses: Record<string, AnySchema>;\n}\n\nexport interface RouteSchemaNames {\n paramsSchemaName?: string;\n querySchemaName?: string;\n headersSchemaName?: string;\n bodySchemaName?: string;\n responseSchemaName?: string;\n}\n\nfunction toUpperCaseMethod(method: string): HttpMethod {\n const upper = method.toUpperCase();\n if (\n upper === \"GET\" ||\n upper === \"POST\" ||\n upper === \"PUT\" ||\n upper === \"PATCH\" ||\n upper === \"DELETE\" ||\n upper === \"HEAD\" ||\n upper === \"OPTIONS\"\n ) {\n return upper as HttpMethod;\n }\n return \"GET\";\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: HttpMethod,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map(toPascalCase);\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\nexport function parseOpenApiPaths(\n openapi: Record<string, unknown>,\n): RouteInfo[] {\n const paths = (openapi as AnySchema)[\"paths\"] as\n | Record<string, AnySchema>\n | undefined;\n if (!paths) {\n return [];\n }\n\n const routes: RouteInfo[] = [];\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem || typeof pathItem !== \"object\") continue;\n\n const methods = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"head\",\n \"options\",\n ] as const;\n\n for (const method of methods) {\n const operation = pathItem[method] as AnySchema | undefined;\n if (!operation) continue;\n\n const parameters: RouteParameter[] = [];\n const responses: Record<string, AnySchema> = {};\n\n if (Array.isArray(pathItem[\"parameters\"])) {\n for (const param of pathItem[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n if (Array.isArray(operation[\"parameters\"])) {\n for (const param of operation[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n let requestBody: AnySchema | undefined;\n if (operation[\"requestBody\"]) {\n const rb = operation[\"requestBody\"];\n if (rb && typeof rb === \"object\") {\n const content = rb[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n requestBody = jsonContent[\"schema\"] || {};\n }\n }\n }\n }\n\n if (operation[\"responses\"] && typeof operation[\"responses\"] === \"object\") {\n for (const [statusCode, response] of Object.entries(\n operation[\"responses\"],\n )) {\n if (response && typeof response === \"object\") {\n const responseSchema = response as AnySchema;\n const content = responseSchema[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n const schema = jsonContent[\"schema\"];\n if (schema) {\n responses[statusCode] = schema;\n }\n }\n }\n }\n }\n }\n\n routes.push({\n path,\n method: toUpperCaseMethod(method),\n parameters,\n requestBody,\n responses,\n });\n }\n }\n\n return routes;\n}\n\nexport function generateRouteSchemaNames(\n route: RouteInfo,\n): RouteSchemaNames {\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n const successStatuses = Object.keys(route.responses).filter((s) =>\n s.startsWith(\"2\"),\n );\n\n const result: RouteSchemaNames = {\n responseSchemaName: successStatuses.length > 0\n ? generateRouteSchemaName(\n route.path,\n route.method,\n \"Response\",\n )\n : undefined,\n };\n\n if (pathParams.length > 0) {\n result.paramsSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Params\",\n );\n }\n\n if (queryParams.length > 0) {\n result.querySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Query\",\n );\n }\n\n if (headerParams.length > 0) {\n result.headersSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Headers\",\n );\n }\n\n if (route.requestBody) {\n result.bodySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Body\",\n );\n }\n\n return result;\n}\n\n","/**\n * Generates TypeScript interface/type strings from OpenAPI schemas.\n *\n * This produces concrete types that appear directly in .d.ts files,\n * rather than requiring z.infer<> resolution at the type level.\n */\n\nimport {\n getSchemaExportedVariableNameForPrimitiveType,\n getSchemaExportedVariableNameForStringFormat,\n} from \"./registry\";\nimport type { AnySchema } from \"./types/types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\ntype SchemaToTypeOptions = {\n outputSchemaNames?: Set<string>;\n};\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction toPascalCase(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\nexport function schemaExportNameToOutputAlias(name: string): string {\n return `${toPascalCase(name)}Output`;\n}\n\nfunction registerOutputSchemaName(\n schemaName: string,\n options?: SchemaToTypeOptions,\n): string {\n options?.outputSchemaNames?.add(schemaName);\n return schemaExportNameToOutputAlias(schemaName);\n}\n\nfunction getRegisteredOutputAlias(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string | undefined {\n if (!schema || typeof schema !== \"object\") return undefined;\n\n if (schema[\"type\"] === \"string\" && typeof schema[\"format\"] === \"string\") {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema[\"format\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n if (\n schema[\"type\"] === \"number\" ||\n schema[\"type\"] === \"integer\" ||\n schema[\"type\"] === \"boolean\"\n ) {\n const customSchemaName = getSchemaExportedVariableNameForPrimitiveType(\n schema[\"type\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n return undefined;\n}\n\n/**\n * Converts an OpenAPI schema to a TypeScript type string.\n *\n * @example\n * schemaToTypeString({ type: 'string' }) // => 'string'\n * schemaToTypeString({ type: 'object', properties: { id: { type: 'string' } } }) // => '{ id?: string }'\n */\nexport function schemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n if (!schema || typeof schema !== \"object\") return \"unknown\";\n\n // Handle $ref\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"unknown\";\n if (match && match[1]) {\n // Decode URI-encoded schema names (e.g., %20 -> space)\n result = decodeURIComponent(match[1]);\n }\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n return result;\n }\n\n let result: string = \"unknown\";\n\n // Handle oneOf (union)\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n const unionMembers = (schema[\"oneOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle allOf (intersection)\n else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n const intersectionMembers = (schema[\"allOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = intersectionMembers.length > 1\n ? `(${intersectionMembers.join(\" & \")})`\n : intersectionMembers[0] ?? \"unknown\";\n }\n // Handle anyOf (union, similar to oneOf)\n else if (\"anyOf\" in schema && Array.isArray(schema[\"anyOf\"])) {\n const unionMembers = (schema[\"anyOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle type-based schemas\n else {\n switch (schema[\"type\"]) {\n case \"string\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // String enum\n result = (schema[\"enum\"] as string[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"string\";\n }\n break;\n }\n case \"number\":\n case \"integer\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Numeric enum\n result = (schema[\"enum\"] as number[]).map((v) => String(v)).join(\" | \");\n } else {\n result = \"number\";\n }\n break;\n }\n case \"boolean\":\n result = getRegisteredOutputAlias(schema, options) ?? \"boolean\";\n break;\n case \"null\":\n result = \"null\";\n break;\n case \"array\":\n if (schema[\"items\"]) {\n const itemType = schemaToTypeString(schema[\"items\"] as AnySchema, options);\n result = `Array<${itemType}>`;\n } else {\n result = \"unknown[]\";\n }\n break;\n case \"object\":\n result = objectSchemaToTypeString(schema, options);\n break;\n default:\n // Try to detect object from properties\n if (schema[\"properties\"]) {\n result = objectSchemaToTypeString(schema, options);\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Untyped enum\n result = (schema[\"enum\"] as unknown[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"unknown\";\n }\n break;\n }\n }\n\n // Handle nullable\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n\n return result;\n}\n\n/**\n * Converts an OpenAPI object schema to a TypeScript object type string.\n */\nfunction objectSchemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n const additionalProperties = schema[\"additionalProperties\"];\n\n if (!properties && !additionalProperties) {\n return \"Record<string, unknown>\";\n }\n\n const propertyStrings: string[] = [];\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n propertyStrings.push(\n `${quotedName}${isRequired ? \"\" : \"?\"}: ${propType}`,\n );\n }\n }\n\n // Handle additionalProperties\n if (additionalProperties === true) {\n propertyStrings.push(\"[key: string]: unknown\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n propertyStrings.push(`[key: string]: ${additionalType}`);\n }\n\n return `{ ${propertyStrings.join(\"; \")} }`;\n}\n\n/**\n * Generates a full TypeScript interface declaration.\n *\n * @example\n * generateInterface('User', { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] })\n * // => 'export interface User { id: string; }'\n */\nexport function generateInterface(\n name: string,\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n\n // For non-object types, use type alias instead of interface\n if (schema[\"type\"] !== \"object\" && !properties) {\n return `export type ${name} = ${schemaToTypeString(schema, options)};`;\n }\n\n const lines: string[] = [];\n lines.push(`export interface ${name} {`);\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n lines.push(` ${quotedName}${isRequired ? \"\" : \"?\"}: ${propType};`);\n }\n }\n\n // Handle additionalProperties\n const additionalProperties = schema[\"additionalProperties\"];\n if (additionalProperties === true) {\n lines.push(\" [key: string]: unknown;\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n lines.push(` [key: string]: ${additionalType};`);\n }\n\n lines.push(\"}\");\n return lines.join(\"\\n\");\n}\n","import { topologicalSortSchemas } from \"./dependencies\";\nimport {\n createSchemaRegistry,\n findCommonSchemas,\n getSchemaFingerprint,\n preRegisterSchema,\n registerSchema,\n type SchemaRegistry,\n} from \"./schema-dedup\";\nimport { convertSchemaToZodString } from \"./to-zod\";\nimport type { AnySchema } from \"./types/types\";\nimport {\n parseOpenApiPaths,\n generateRouteSchemaNames,\n type RouteInfo,\n} from \"./routes\";\nimport { generateInterface, schemaExportNameToOutputAlias } from \"./interface-generator\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: string,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map((word) => {\n // Convert hyphenated words to PascalCase (e.g., \"timer-drafts\" -> \"TimerDrafts\")\n return word\n .split(/[-_]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase())\n .join(\"\");\n });\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\n/**\n * Result of route schema generation including declarations and name mappings.\n */\ninterface RouteSchemaResult {\n /** Schema declarations to be emitted */\n declarations: string[];\n /** Maps route-specific schema name to its canonical name (for deduplication) */\n schemaNameToCanonical: Map<string, string>;\n}\n\nfunction generateRouteSchemas(\n routes: RouteInfo[],\n convertSchema: (schema: AnySchema) => string,\n registry: SchemaRegistry,\n): RouteSchemaResult {\n const declarations: string[] = [];\n const schemaNameToCanonical = new Map<string, string>();\n const generatedNames = new Set<string>();\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n // Generate params schema with deduplication\n if (names.paramsSchemaName && pathParams.length > 0) {\n const paramsSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n pathParams.map((p) => [p.name, p.schema]),\n ),\n required: pathParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.paramsSchemaName,\n paramsSchema,\n );\n schemaNameToCanonical.set(names.paramsSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n const properties: string[] = [];\n for (const param of pathParams) {\n const zodExpr = convertSchema(param.schema);\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.paramsSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.paramsSchemaName !== canonicalName) {\n if (!generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n declarations.push(\n `export const ${names.paramsSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate query schema with deduplication\n if (names.querySchemaName && queryParams.length > 0) {\n const querySchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n queryParams.map((p) => [p.name, p.schema]),\n ),\n required: queryParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.querySchemaName,\n querySchema,\n );\n schemaNameToCanonical.set(names.querySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n const properties: string[] = [];\n for (const param of queryParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.querySchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.querySchemaName !== canonicalName) {\n if (!generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n declarations.push(\n `export const ${names.querySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate headers schema with deduplication\n if (names.headersSchemaName && headerParams.length > 0) {\n const headersSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n headerParams.map((p) => [p.name, p.schema]),\n ),\n required: headerParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.headersSchemaName,\n headersSchema,\n );\n schemaNameToCanonical.set(names.headersSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n const properties: string[] = [];\n for (const param of headerParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.headersSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.headersSchemaName !== canonicalName) {\n if (!generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n declarations.push(\n `export const ${names.headersSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate body schema with deduplication\n if (names.bodySchemaName && route.requestBody) {\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.bodySchemaName,\n route.requestBody,\n );\n schemaNameToCanonical.set(names.bodySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n const zodExpr = convertSchema(route.requestBody);\n declarations.push(`export const ${names.bodySchemaName} = ${zodExpr};`);\n } else if (!isNew && names.bodySchemaName !== canonicalName) {\n if (!generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n declarations.push(\n `export const ${names.bodySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate schemas for ALL status codes with deduplication\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n responseSchemaName,\n responseSchema,\n );\n schemaNameToCanonical.set(responseSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n const zodExpr = convertSchema(responseSchema);\n declarations.push(`export const ${responseSchemaName} = ${zodExpr};`);\n } else if (!isNew && responseSchemaName !== canonicalName) {\n if (!generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n declarations.push(\n `export const ${responseSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n }\n\n return { declarations, schemaNameToCanonical };\n}\n\nfunction generateRequestResponseObjects(\n routes: RouteInfo[],\n schemaNameToCanonical: Map<string, string>,\n): string[] {\n const lines: string[] = [];\n const requestPaths: Record<string, Record<string, string[]>> = {};\n const responsePaths: Record<\n string,\n Record<string, Record<string, string>>\n > = {};\n\n /**\n * Resolves a schema name to its canonical name if it exists,\n * otherwise returns the original name.\n */\n const resolveSchemaName = (name: string): string => {\n return schemaNameToCanonical.get(name) ?? name;\n };\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n if (!requestPaths[route.path]) {\n requestPaths[route.path] = {};\n }\n const requestMethodObj = requestPaths[route.path]!;\n if (!requestMethodObj[route.method]) {\n requestMethodObj[route.method] = [];\n }\n\n const requestParts: string[] = [];\n if (names.paramsSchemaName && pathParams.length > 0) {\n requestParts.push(\n `params: ${resolveSchemaName(names.paramsSchemaName)}`,\n );\n }\n if (names.querySchemaName && queryParams.length > 0) {\n requestParts.push(`query: ${resolveSchemaName(names.querySchemaName)}`);\n }\n if (names.headersSchemaName && headerParams.length > 0) {\n requestParts.push(\n `headers: ${resolveSchemaName(names.headersSchemaName)}`,\n );\n }\n if (names.bodySchemaName && route.requestBody) {\n requestParts.push(`body: ${resolveSchemaName(names.bodySchemaName)}`);\n }\n\n if (requestParts.length > 0) {\n requestMethodObj[route.method] = requestParts;\n }\n\n // Store all status codes in nested structure\n if (!responsePaths[route.path]) {\n responsePaths[route.path] = {};\n }\n const responseMethodObj = responsePaths[route.path]!;\n if (!responseMethodObj[route.method]) {\n responseMethodObj[route.method] = {};\n }\n\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n // Use canonical name for the Response object\n responseMethodObj[route.method]![statusCode] =\n resolveSchemaName(responseSchemaName);\n }\n }\n\n lines.push(\"export const Request = {\");\n for (const [path, methods] of Object.entries(requestPaths)) {\n const methodEntries = Object.entries(methods).filter(\n ([, parts]) => parts.length > 0,\n );\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, parts] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const part of parts) {\n lines.push(` ${part},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n lines.push(\"\");\n\n lines.push(\"export const Response = {\");\n for (const [path, methods] of Object.entries(responsePaths)) {\n const methodEntries = Object.entries(methods);\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, statusCodes] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const [statusCode, schemaName] of Object.entries(statusCodes)) {\n lines.push(` '${statusCode}': ${schemaName},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n\n return lines;\n}\n\n/**\n * Collects all response schemas from routes for common schema detection.\n */\nfunction collectRouteSchemas(\n routes: RouteInfo[],\n): Array<{ name: string; schema: AnySchema }> {\n const collected: Array<{ name: string; schema: AnySchema }> = [];\n\n for (const route of routes) {\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n collected.push({ name: responseSchemaName, schema: responseSchema });\n }\n }\n\n return collected;\n}\n\nexport const openApiToZodTsCode = (\n openapi: Record<string, unknown>,\n customImportLines?: string[],\n options?: { includeRoutes?: boolean },\n): string => {\n const components = (openapi as AnySchema)[\"components\"] as\n | AnySchema\n | undefined;\n const schemas: Record<string, AnySchema> =\n (components?.[\"schemas\"] as Record<string, AnySchema>) ?? {};\n\n const lines: string[] = [];\n lines.push(\"/**\");\n lines.push(\" * This file was automatically generated from OpenAPI schema\");\n lines.push(\" * Do not manually edit this file\");\n lines.push(\" */\");\n lines.push(\"\");\n lines.push(\"import { z } from 'zod';\");\n lines.push(...(customImportLines ?? []));\n lines.push(\"\");\n\n // Type assertion helper for compile-time verification\n lines.push(\"// Type assertion helper - verifies interface matches schema at compile time\");\n lines.push(\"type _AssertEqual<T, U> = [T] extends [U] ? ([U] extends [T] ? true : never) : never;\");\n lines.push(\"\");\n\n // Create registry for schema deduplication\n const registry = createSchemaRegistry();\n\n const sortedSchemaNames = topologicalSortSchemas(schemas);\n\n // Collect all type assertions to emit after all schemas\n const typeAssertions: string[] = [];\n const outputSchemaNames = new Set<string>();\n const schemaBlocks: string[] = [];\n\n for (const name of sortedSchemaNames) {\n const schema = schemas[name];\n if (schema) {\n const zodExpr = convertSchemaToZodString(schema);\n const schemaName = `${name}Schema`;\n const typeName = name;\n\n // Generate interface (concrete type in .d.ts)\n schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));\n\n // Generate schema with ZodType<T> annotation (simple type in .d.ts)\n schemaBlocks.push(`export const ${schemaName} = ${zodExpr};`);\n schemaBlocks.push(\"\");\n\n // Add type assertion to verify interface matches schema\n typeAssertions.push(`type _Assert${typeName} = _AssertEqual<${typeName}, z.infer<typeof ${schemaName}>>;`);\n\n // Register component schemas so they can be referenced by route schemas\n const fingerprint = getSchemaFingerprint(schema);\n preRegisterSchema(registry, schemaName, fingerprint);\n }\n }\n\n if (outputSchemaNames.size > 0) {\n lines.push(\"// Zod output aliases for registered schemas\");\n for (const schemaName of outputSchemaNames) {\n const aliasName = schemaExportNameToOutputAlias(schemaName);\n lines.push(`type ${aliasName} = z.output<typeof ${schemaName}>;`);\n }\n lines.push(\"\");\n }\n\n lines.push(...schemaBlocks);\n\n // Emit all type assertions\n if (typeAssertions.length > 0) {\n lines.push(\"// Compile-time type assertions - ensure interfaces match schemas\");\n lines.push(typeAssertions.join(\"\\n\"));\n lines.push(\"\");\n }\n\n if (options?.includeRoutes) {\n const routes = parseOpenApiPaths(openapi);\n if (routes.length > 0) {\n // Find common schemas that appear multiple times (for error responses, etc.)\n const routeSchemaList = collectRouteSchemas(routes);\n const commonSchemas = findCommonSchemas(routeSchemaList, 2);\n\n // Generate common schemas first (e.g., UnauthorizedErrorSchema, NotFoundErrorSchema)\n if (commonSchemas.length > 0) {\n lines.push(\"// Common Error Schemas (deduplicated)\");\n for (const common of commonSchemas) {\n const zodExpr = convertSchemaToZodString(common.schema);\n lines.push(`export const ${common.name} = ${zodExpr};`);\n // Pre-register so route schemas reference this instead of duplicating\n preRegisterSchema(registry, common.name, common.fingerprint);\n }\n lines.push(\"\");\n }\n\n // Generate route schemas with deduplication\n const { declarations, schemaNameToCanonical } = generateRouteSchemas(\n routes,\n convertSchemaToZodString,\n registry,\n );\n\n if (declarations.length > 0) {\n lines.push(\"// Route Schemas\");\n lines.push(...declarations);\n lines.push(\"\");\n\n // Generate Request/Response objects using canonical names\n const requestResponseObjs = generateRequestResponseObjects(\n routes,\n schemaNameToCanonical,\n );\n lines.push(...requestResponseObjs);\n }\n }\n }\n\n return lines.join(\"\\n\");\n};\n"],"mappings":"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","names":["result","validIdentifierRegex","quotePropertyName","toPascalCase","result","validIdentifierRegex","quotePropertyName","generateRouteSchemaName"]}
|
package/dist/index.js
CHANGED
|
@@ -1192,7 +1192,7 @@ var openApiToZodTsCode = (openapi, customImportLines, options) => {
|
|
|
1192
1192
|
const schemaName = `${name}Schema`;
|
|
1193
1193
|
const typeName = name;
|
|
1194
1194
|
schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));
|
|
1195
|
-
schemaBlocks.push(`export const ${schemaName}
|
|
1195
|
+
schemaBlocks.push(`export const ${schemaName} = ${zodExpr};`);
|
|
1196
1196
|
schemaBlocks.push("");
|
|
1197
1197
|
typeAssertions.push(`type _Assert${typeName} = _AssertEqual<${typeName}, z.infer<typeof ${schemaName}>>;`);
|
|
1198
1198
|
const fingerprint = getSchemaFingerprint(schema);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dependencies.ts","../src/schema-dedup.ts","../src/types/boolean.ts","../src/types/number.ts","../src/registry.ts","../src/types/string.ts","../src/types/array.ts","../src/types/object.ts","../src/types/union.ts","../src/types/intersection.ts","../src/to-zod.ts","../src/routes.ts","../src/interface-generator.ts","../src/to-typescript.ts"],"sourcesContent":["import type { AnySchema } from \"./types/types\";\n\n/**\n * Extracts all schema references ($ref) from an OpenAPI schema by recursively\n * traversing its structure.\n *\n * This function is used during the OpenAPI-to-Zod conversion process to identify\n * which schemas a given schema depends on. It traverses all OpenAPI schema\n * structures including objects, arrays, unions (oneOf), intersections (allOf),\n * conditionals (if/then/else), and discriminator mappings to find all $ref\n * references that point to other schemas in the components/schemas section.\n *\n * The extracted dependency names are used by `topologicalSortSchemas` to build\n * a dependency graph and determine the correct order for generating Zod schemas,\n * ensuring that referenced schemas are defined before they are used in the\n * generated TypeScript code.\n *\n * @param schema - The OpenAPI schema to extract dependencies from\n * @returns An array of schema names that this schema references (via $ref)\n */\nexport function extractSchemaDependencies(schema: AnySchema): string[] {\n const dependencies: Set<string> = new Set();\n const visited = new WeakSet();\n\n function traverse(obj: any): void {\n if (!obj || typeof obj !== \"object\") return;\n\n if (visited.has(obj)) return;\n visited.add(obj);\n\n if (obj[\"$ref\"] && typeof obj[\"$ref\"] === \"string\") {\n const match = (obj[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n if (match && match[1]) {\n dependencies.add(decodeURIComponent(match[1]));\n }\n return;\n }\n\n if (Array.isArray(obj)) {\n obj.forEach(traverse);\n return;\n }\n\n if (obj.properties && typeof obj.properties === \"object\") {\n for (const propValue of Object.values(obj.properties)) {\n traverse(propValue);\n }\n }\n\n const schemaKeys = [\n \"items\",\n \"oneOf\",\n \"allOf\",\n \"anyOf\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n \"prefixItems\",\n \"contains\",\n \"propertyNames\",\n \"dependentSchemas\",\n ];\n\n for (const key of schemaKeys) {\n if (obj[key]) {\n traverse(obj[key]);\n }\n }\n\n if (\n obj.additionalProperties &&\n typeof obj.additionalProperties === \"object\"\n ) {\n traverse(obj.additionalProperties);\n }\n\n if (obj.discriminator?.mapping) {\n Object.values(obj.discriminator.mapping).forEach(traverse);\n }\n }\n\n traverse(schema);\n return Array.from(dependencies);\n}\n\n/**\n * Sorts OpenAPI schemas topologically based on their dependencies to ensure\n * correct generation order.\n *\n * When converting OpenAPI schemas to Zod schemas and generating TypeScript code,\n * schemas must be defined before they are referenced. For example, if `UserSchema`\n * references `ProfileSchema` (via $ref), then `ProfileSchema` must be generated\n * before `UserSchema` to avoid \"undefined variable\" errors in the generated code.\n *\n * This function uses Kahn's algorithm for topological sorting to order schemas\n * such that all dependencies come before their dependents. It:\n * 1. Extracts dependencies for each schema using `extractSchemaDependencies`\n * 2. Builds a dependency graph and computes in-degrees\n * 3. Sorts schemas starting with those that have no dependencies (in-degree 0)\n * 4. Handles circular dependencies gracefully by appending any remaining schemas\n * that couldn't be sorted (though this indicates a problematic schema structure)\n *\n * This function is called by `openApiToZodTsCode` to determine the order in which\n * schemas should be converted and emitted in the generated TypeScript file.\n *\n * @param schemas - A record mapping schema names to their OpenAPI schema definitions\n * @returns An array of schema names sorted in topological order (dependencies before dependents)\n */\nexport function topologicalSortSchemas(\n schemas: Record<string, AnySchema>,\n): string[] {\n const schemaNames = Object.keys(schemas);\n const dependencies: Map<string, string[]> = new Map();\n const inDegree: Map<string, number> = new Map();\n const sorted: string[] = [];\n const queue: string[] = [];\n const dependents: Map<string, string[]> = new Map();\n\n for (const name of schemaNames) {\n dependencies.set(name, []);\n dependents.set(name, []);\n inDegree.set(name, 0);\n }\n\n for (const name of schemaNames) {\n const schemaValue = schemas[name];\n if (schemaValue) {\n const deps = extractSchemaDependencies(schemaValue);\n const validDeps = deps.filter((dep) => schemaNames.includes(dep));\n dependencies.set(name, validDeps);\n\n for (const dep of validDeps) {\n const currentDependents = dependents.get(dep) || [];\n currentDependents.push(name);\n dependents.set(dep, currentDependents);\n }\n }\n }\n\n for (const [name, deps] of dependencies.entries()) {\n inDegree.set(name, deps.length);\n }\n\n for (const [name, degree] of inDegree.entries()) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n sorted.push(current);\n\n const currentDependents = dependents.get(current) || [];\n for (const dependent of currentDependents) {\n const newDegree = (inDegree.get(dependent) || 0) - 1;\n inDegree.set(dependent, newDegree);\n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n if (sorted.length !== schemaNames.length) {\n for (const name of schemaNames) {\n if (!sorted.includes(name)) {\n sorted.push(name);\n }\n }\n }\n\n return sorted;\n}\n","import type { AnySchema } from \"./types/types\";\n\n/**\n * Schema deduplication utilities for optimizing generated TypeScript types.\n *\n * This module provides fingerprinting and registry functionality to detect\n * structurally identical schemas and generate them only once, reducing\n * memory usage in consuming TypeScript projects.\n */\n\n/**\n * Recursively sorts an object's keys to create a stable representation.\n * This ensures that {a: 1, b: 2} and {b: 2, a: 1} produce the same fingerprint.\n */\nfunction sortObjectDeep(obj: unknown): unknown {\n if (obj === null || typeof obj !== \"object\") return obj;\n if (Array.isArray(obj)) return obj.map(sortObjectDeep);\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObjectDeep((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n}\n\n/**\n * Generates a canonical fingerprint for an OpenAPI schema.\n * Identical schemas will produce identical fingerprints.\n */\nexport function getSchemaFingerprint(schema: AnySchema): string {\n return JSON.stringify(sortObjectDeep(schema));\n}\n\n/**\n * Registry for tracking unique schemas and their canonical names.\n */\nexport interface SchemaRegistry {\n /** Map from fingerprint to the first schema name that used it */\n fingerprintToName: Map<string, string>;\n /** Map from schema name to its fingerprint (for reverse lookup) */\n nameToFingerprint: Map<string, string>;\n}\n\n/**\n * Creates a new empty schema registry.\n */\nexport function createSchemaRegistry(): SchemaRegistry {\n return {\n fingerprintToName: new Map(),\n nameToFingerprint: new Map(),\n };\n}\n\n/**\n * Result of registering a schema.\n */\nexport interface RegisterSchemaResult {\n /** Whether this is a new unique schema */\n isNew: boolean;\n /** The canonical name for this schema (may be different from input name if duplicate) */\n canonicalName: string;\n}\n\n/**\n * Registers a schema in the registry. If an identical schema already exists,\n * returns the existing canonical name instead.\n */\nexport function registerSchema(\n registry: SchemaRegistry,\n name: string,\n schema: AnySchema,\n): RegisterSchemaResult {\n const fingerprint = getSchemaFingerprint(schema);\n\n const existing = registry.fingerprintToName.get(fingerprint);\n if (existing) {\n return { isNew: false, canonicalName: existing };\n }\n\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n return { isNew: true, canonicalName: name };\n}\n\n/**\n * Pre-registers a schema with a specific fingerprint.\n * Used for common schemas that should take priority.\n */\nexport function preRegisterSchema(\n registry: SchemaRegistry,\n name: string,\n fingerprint: string,\n): void {\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n}\n\n/**\n * Extracts the error code from an OpenAPI error schema.\n * Looks for patterns like: { error: { code: enum(['UNAUTHORIZED']) } }\n */\nexport function extractErrorCode(schema: AnySchema): string | null {\n const properties = schema?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const errorObj = properties?.[\"error\"] as AnySchema | undefined;\n const errorProps = errorObj?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const codeSchema = errorProps?.[\"code\"] as AnySchema | undefined;\n const codeEnum = codeSchema?.[\"enum\"] as string[] | undefined;\n\n if (Array.isArray(codeEnum) && codeEnum.length === 1) {\n return codeEnum[0]!;\n }\n return null;\n}\n\n/**\n * Converts an error code like UNAUTHORIZED or NOT_FOUND to PascalCase.\n * UNAUTHORIZED -> Unauthorized\n * NOT_FOUND -> NotFound\n */\nexport function errorCodeToPascalCase(code: string): string {\n return code\n .split(\"_\")\n .map((part) => part.charAt(0) + part.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Generates a common error schema name from an error code.\n * UNAUTHORIZED -> UnauthorizedErrorSchema\n */\nexport function generateCommonErrorSchemaName(errorCode: string): string {\n return `${errorCodeToPascalCase(errorCode)}ErrorSchema`;\n}\n\n/**\n * Represents a common schema that appears multiple times.\n */\nexport interface CommonSchema {\n /** The canonical name for this schema */\n name: string;\n /** The schema definition */\n schema: AnySchema;\n /** The fingerprint for deduplication */\n fingerprint: string;\n /** Number of times this schema appears */\n count: number;\n}\n\n/**\n * Scans schemas and identifies those that appear multiple times.\n * Returns common schemas sorted by count (most common first).\n */\nexport function findCommonSchemas(\n schemas: Array<{ name: string; schema: AnySchema }>,\n minCount: number = 2,\n): CommonSchema[] {\n const fingerprints = new Map<\n string,\n { schema: AnySchema; names: string[]; errorCode: string | null }\n >();\n\n // Count occurrences of each unique schema\n for (const { name, schema } of schemas) {\n const fingerprint = getSchemaFingerprint(schema);\n const existing = fingerprints.get(fingerprint);\n\n if (existing) {\n existing.names.push(name);\n } else {\n fingerprints.set(fingerprint, {\n schema,\n names: [name],\n errorCode: extractErrorCode(schema),\n });\n }\n }\n\n // Filter to schemas appearing minCount+ times\n const commonSchemas: CommonSchema[] = [];\n for (const [fingerprint, data] of fingerprints) {\n if (data.names.length >= minCount) {\n // Generate a semantic name if it's an error schema, otherwise use first occurrence\n const name = data.errorCode\n ? generateCommonErrorSchemaName(data.errorCode)\n : data.names[0]!;\n\n commonSchemas.push({\n name,\n schema: data.schema,\n fingerprint,\n count: data.names.length,\n });\n }\n }\n\n // Sort by count descending (most common first)\n return commonSchemas.sort((a, b) => b.count - a.count);\n}\n","/**\n * Convert an OpenAPI v3 boolean schema to a Zod schema string\n */\nexport function convertOpenAPIBooleanToZod(_: { type: \"boolean\" }): string {\n return \"z.boolean()\";\n}\n","/**\n * Convert an OpenAPI v3 number/integer schema to a Zod schema string\n */\nexport function convertOpenAPINumberToZod(schema: {\n type: \"number\" | \"integer\";\n minimum?: number;\n maximum?: number;\n}): string {\n let result = \"z.number()\";\n if (schema.type === \"integer\") {\n result += \".int()\";\n }\n if (typeof schema.minimum === \"number\") {\n result += `.min(${schema.minimum})`;\n }\n if (typeof schema.maximum === \"number\") {\n result += `.max(${schema.maximum})`;\n }\n return result;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst SUPPORTED_STRING_FORMATS_MAP = {\n \"color-hex\": 1,\n date: 1,\n \"date-time\": 1,\n email: 1,\n \"iso-date\": 1,\n \"iso-date-time\": 1,\n objectid: 1,\n uri: 1,\n url: 1,\n uuid: 1,\n} as const;\n\nexport const SUPPORTED_STRING_FORMATS = Object.keys(\n SUPPORTED_STRING_FORMATS_MAP,\n) as unknown as keyof typeof SUPPORTED_STRING_FORMATS_MAP;\n\ntype SupportedStringFormat = typeof SUPPORTED_STRING_FORMATS;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ZodOpenApiRegistrationString<\n F extends SupportedStringFormat = SupportedStringFormat,\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n format: F;\n};\n\nexport type ZodOpenApiRegistrationStrings<\n Fs extends\n readonly SupportedStringFormat[] = readonly SupportedStringFormat[],\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n formats: Fs;\n};\n\nexport type ZodOpenApiRegistrationPrimitive = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n description?: string;\n type: \"number\" | \"integer\" | \"boolean\";\n};\n\nexport type ZodOpenApiRegistration =\n | ZodOpenApiRegistrationString\n | ZodOpenApiRegistrationStrings\n | ZodOpenApiRegistrationPrimitive;\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isStringRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationString {\n return reg.type === \"string\" && \"format\" in reg;\n}\n\nfunction isStringsRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationStrings {\n return reg.type === \"string\" && \"formats\" in reg;\n}\n\nfunction isSupportedStringFormat(\n format: string,\n): format is SupportedStringFormat {\n return Object.prototype.hasOwnProperty.call(SUPPORTED_STRING_FORMATS_MAP, format);\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\ntype TypeFormatPair = { type: string; format: string | undefined };\n\nfunction getTypeFormatPairs(reg: ZodOpenApiRegistration): TypeFormatPair[] {\n if (isStringRegistration(reg)) {\n return [{ type: \"string\", format: reg.format }];\n }\n\n if (isStringsRegistration(reg)) {\n return reg.formats.map((f) => ({ type: \"string\", format: f }));\n }\n\n return [];\n}\n\n// ============================================================================\n// Registry Class\n// ============================================================================\n\n/**\n * Global registry for mapping Zod schemas to OpenAPI schema representations\n */\nclass ZodSchemaRegistry {\n private readonly map = new Map<z.ZodTypeAny, ZodOpenApiRegistration>();\n\n /**\n * Register a Zod schema with its OpenAPI representation\n */\n register<F extends SupportedStringFormat>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationString<F>,\n ): void;\n register<Fs extends readonly SupportedStringFormat[]>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationStrings<Fs>,\n ): void;\n register(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationPrimitive,\n ): void;\n register(schema: z.ZodTypeAny, registration: ZodOpenApiRegistration): void {\n const newPairs = getTypeFormatPairs(registration);\n\n if (newPairs.length > 0) {\n for (const [existingSchema, existingRegistration] of this.map.entries()) {\n if (existingSchema === schema) continue;\n\n const existingPairs = getTypeFormatPairs(existingRegistration);\n for (const { type, format } of newPairs) {\n if (\n existingPairs.some((p) => p.type === type && p.format === format)\n ) {\n throw new Error(\n `duplicate Zod OpenAPI registration for (type, format)=('${type}', '${format as string}')`,\n );\n }\n }\n }\n }\n\n this.map.set(schema, registration);\n }\n\n /**\n * Get the OpenAPI schema for a given Zod schema\n */\n getOpenApiSchema(schema: z.ZodTypeAny): ZodOpenApiRegistration | undefined {\n return this.map.get(schema);\n }\n\n /**\n * Check if a Zod schema is registered\n */\n isRegistered(schema: z.ZodTypeAny): boolean {\n return this.map.has(schema);\n }\n\n /**\n * Clear all registered schemas\n */\n clear(): void {\n this.map.clear();\n }\n\n /**\n * Reverse-lookup helper: given a string format, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n ): string | undefined {\n if (!isSupportedStringFormat(format)) return undefined;\n for (const registration of this.map.values()) {\n if (registration.type !== \"string\") continue;\n\n if (\n isStringRegistration(registration) &&\n registration.format === format\n ) {\n return registration.schemaExportedVariableName;\n }\n\n if (\n isStringsRegistration(registration) &&\n registration.formats.includes(format)\n ) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n\n /**\n * Reverse-lookup helper: given a primitive type, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n ): string | undefined {\n for (const registration of this.map.values()) {\n if (registration.type === type) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n}\n\n// ============================================================================\n// Global Registry Instance\n// ============================================================================\n\nexport const schemaRegistry = new ZodSchemaRegistry();\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Helper function to register a Zod schema with its OpenAPI representation\n */\nexport function registerZodSchemaToOpenApiSchema(\n schema: z.ZodTypeAny,\n openApiSchema: ZodOpenApiRegistration,\n): void {\n schemaRegistry.register(schema, openApiSchema as any);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given string format\n */\nexport function getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForStringFormat(format);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given primitive type\n */\nexport function getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForPrimitiveType(type);\n}\n\n/**\n * Clear all registered schemas in the global registry\n */\nexport function clearZodSchemaToOpenApiSchemaRegistry(): void {\n schemaRegistry.clear();\n}\n","import {\n getSchemaExportedVariableNameForStringFormat,\n SUPPORTED_STRING_FORMATS,\n} from \"../registry\";\n\n/**\n * Convert an OpenAPI v3 string schema to a Zod schema string\n */\nexport function convertOpenAPIStringToZod(schema: {\n type: \"string\";\n format?: typeof SUPPORTED_STRING_FORMATS;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n enum?: string[];\n}): string {\n // Handle enum values\n if (schema.enum) {\n return `z.enum([${schema.enum.map((value) => `'${value}'`).join(\", \")}])`;\n }\n\n // Check for custom registered format schemas\n if (schema.format && SUPPORTED_STRING_FORMATS.includes(schema.format)) {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema.format,\n );\n\n // Use custom schema if registered (ignores other constraints)\n if (customSchemaName) {\n return customSchemaName;\n }\n }\n\n // Build string schema with format modifiers\n let zodSchema = \"z.string()\";\n\n if (schema.format) {\n zodSchema += getFormatModifier(schema.format);\n }\n\n // Apply length constraints\n if (typeof schema.minLength === \"number\") {\n zodSchema += `.min(${schema.minLength})`;\n }\n\n if (typeof schema.maxLength === \"number\") {\n zodSchema += `.max(${schema.maxLength})`;\n }\n\n // Apply pattern constraint\n if (typeof schema.pattern === \"string\") {\n zodSchema += `.regex(/${schema.pattern}/)`;\n }\n\n return zodSchema;\n}\n\n/**\n * Get the Zod modifier for built-in string formats\n */\nfunction getFormatModifier(format: string): string {\n switch (format) {\n case \"email\":\n return \".email()\";\n case \"url\":\n case \"uri\":\n return \".url()\";\n case \"uuid\":\n return \".uuid()\";\n case \"color-hex\":\n return \".regex(/^[a-fA-F0-9]{6}$/)\";\n default:\n return \"\";\n }\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIArrayToZod(\n schema: {\n type: \"array\";\n items?: any;\n minItems?: number;\n maxItems?: number;\n },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const item = schema.items;\n\n let itemZodString = \"z.unknown()\";\n if (item && typeof item === \"object\") {\n itemZodString = convertSchema(item);\n }\n\n let result = `z.array(${itemZodString})`;\n\n if (typeof schema.minItems === \"number\") {\n result += `.min(${schema.minItems})`;\n }\n if (typeof schema.maxItems === \"number\") {\n result += `.max(${schema.maxItems})`;\n }\n\n return result;\n}\n","import { AnySchema, OpenAPIObjectSchema } from \"./types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nexport function convertOpenAPIObjectToZod(\n schema: OpenAPIObjectSchema,\n convertSchema: (schema: AnySchema) => string,\n): string {\n const properties = schema.properties || {};\n const propertyNames = Object.keys(properties);\n\n if (propertyNames.length === 0) {\n if (schema.additionalProperties === false) {\n return \"z.object({}).strict()\";\n }\n return \"z.record(z.string(), z.unknown())\";\n }\n\n const requiredSet = new Set(schema.required || []);\n\n const entries: string[] = [];\n for (const [propName, propSchema] of Object.entries(properties)) {\n let zodProp = \"z.unknown()\";\n\n if (propSchema && typeof propSchema === \"object\") {\n zodProp = convertSchema(propSchema);\n }\n\n if (!requiredSet.has(propName)) {\n zodProp += \".optional()\";\n }\n\n entries.push(`${quotePropertyName(propName)}: ${zodProp}`);\n }\n\n let result = `z.object({ ${entries.join(\", \")} })`;\n\n if (schema.additionalProperties === false) {\n result += \".strict()\";\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIUnionToZod(\n schema: { oneOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.oneOf.map((item) => convertSchema(item));\n return `z.union([${items.join(\", \")}])`;\n}\n\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIIntersectionToZod(\n schema: { allOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.allOf.map((item) => convertSchema(item));\n\n if (schema.allOf.length === 0) return \"z.unknown()\";\n if (schema.allOf.length === 1) return convertSchema(schema.allOf[0]!);\n\n return `z.intersection(${items.join(\", \")})`;\n}\n\n","import { convertOpenAPIBooleanToZod } from \"./types/boolean\";\nimport { convertOpenAPINumberToZod } from \"./types/number\";\nimport { convertOpenAPIStringToZod } from \"./types/string\";\nimport { convertOpenAPIArrayToZod } from \"./types/array\";\nimport { convertOpenAPIObjectToZod } from \"./types/object\";\nimport { convertOpenAPIUnionToZod } from \"./types/union\";\nimport { convertOpenAPIIntersectionToZod } from \"./types/intersection\";\nimport type { AnySchema } from \"./types/types\";\n\nexport function convertSchemaToZodString(schema: AnySchema): string {\n if (!schema || typeof schema !== \"object\") return \"z.unknown()\";\n\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"z.unknown()\";\n if (match && match[1]) {\n result = `${match[1]}Schema`;\n }\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n return result;\n }\n let result: string = \"z.unknown()\";\n\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n result = convertOpenAPIUnionToZod(\n schema as { oneOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n result = convertOpenAPIIntersectionToZod(\n schema as { allOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else {\n switch (schema[\"type\"]) {\n case \"string\":\n result = convertOpenAPIStringToZod({\n enum: schema[\"enum\"],\n format: schema[\"format\"],\n maxLength: schema[\"maxLength\"],\n minLength: schema[\"minLength\"],\n pattern: schema[\"pattern\"],\n type: \"string\",\n });\n break;\n case \"number\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"number\",\n });\n break;\n case \"integer\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"integer\",\n });\n break;\n case \"boolean\":\n result = convertOpenAPIBooleanToZod({ type: \"boolean\" });\n break;\n case \"array\":\n result = convertOpenAPIArrayToZod(\n {\n items: schema[\"items\"],\n maxItems: schema[\"maxItems\"],\n minItems: schema[\"minItems\"],\n type: \"array\",\n },\n convertSchemaToZodString,\n );\n break;\n case \"object\":\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n break;\n default:\n if (schema[\"properties\"]) {\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n } else {\n result = \"z.unknown()\";\n }\n break;\n }\n }\n\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types/types\";\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"HEAD\" | \"OPTIONS\";\n\nexport interface RouteParameter {\n name: string;\n in: \"path\" | \"query\" | \"header\" | \"cookie\";\n required: boolean;\n schema: AnySchema;\n}\n\nexport interface RouteInfo {\n path: string;\n method: HttpMethod;\n parameters: RouteParameter[];\n requestBody?: AnySchema;\n responses: Record<string, AnySchema>;\n}\n\nexport interface RouteSchemaNames {\n paramsSchemaName?: string;\n querySchemaName?: string;\n headersSchemaName?: string;\n bodySchemaName?: string;\n responseSchemaName?: string;\n}\n\nfunction toUpperCaseMethod(method: string): HttpMethod {\n const upper = method.toUpperCase();\n if (\n upper === \"GET\" ||\n upper === \"POST\" ||\n upper === \"PUT\" ||\n upper === \"PATCH\" ||\n upper === \"DELETE\" ||\n upper === \"HEAD\" ||\n upper === \"OPTIONS\"\n ) {\n return upper as HttpMethod;\n }\n return \"GET\";\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: HttpMethod,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map(toPascalCase);\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\nexport function parseOpenApiPaths(\n openapi: Record<string, unknown>,\n): RouteInfo[] {\n const paths = (openapi as AnySchema)[\"paths\"] as\n | Record<string, AnySchema>\n | undefined;\n if (!paths) {\n return [];\n }\n\n const routes: RouteInfo[] = [];\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem || typeof pathItem !== \"object\") continue;\n\n const methods = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"head\",\n \"options\",\n ] as const;\n\n for (const method of methods) {\n const operation = pathItem[method] as AnySchema | undefined;\n if (!operation) continue;\n\n const parameters: RouteParameter[] = [];\n const responses: Record<string, AnySchema> = {};\n\n if (Array.isArray(pathItem[\"parameters\"])) {\n for (const param of pathItem[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n if (Array.isArray(operation[\"parameters\"])) {\n for (const param of operation[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n let requestBody: AnySchema | undefined;\n if (operation[\"requestBody\"]) {\n const rb = operation[\"requestBody\"];\n if (rb && typeof rb === \"object\") {\n const content = rb[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n requestBody = jsonContent[\"schema\"] || {};\n }\n }\n }\n }\n\n if (operation[\"responses\"] && typeof operation[\"responses\"] === \"object\") {\n for (const [statusCode, response] of Object.entries(\n operation[\"responses\"],\n )) {\n if (response && typeof response === \"object\") {\n const responseSchema = response as AnySchema;\n const content = responseSchema[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n const schema = jsonContent[\"schema\"];\n if (schema) {\n responses[statusCode] = schema;\n }\n }\n }\n }\n }\n }\n\n routes.push({\n path,\n method: toUpperCaseMethod(method),\n parameters,\n requestBody,\n responses,\n });\n }\n }\n\n return routes;\n}\n\nexport function generateRouteSchemaNames(\n route: RouteInfo,\n): RouteSchemaNames {\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n const successStatuses = Object.keys(route.responses).filter((s) =>\n s.startsWith(\"2\"),\n );\n\n const result: RouteSchemaNames = {\n responseSchemaName: successStatuses.length > 0\n ? generateRouteSchemaName(\n route.path,\n route.method,\n \"Response\",\n )\n : undefined,\n };\n\n if (pathParams.length > 0) {\n result.paramsSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Params\",\n );\n }\n\n if (queryParams.length > 0) {\n result.querySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Query\",\n );\n }\n\n if (headerParams.length > 0) {\n result.headersSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Headers\",\n );\n }\n\n if (route.requestBody) {\n result.bodySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Body\",\n );\n }\n\n return result;\n}\n\n","/**\n * Generates TypeScript interface/type strings from OpenAPI schemas.\n *\n * This produces concrete types that appear directly in .d.ts files,\n * rather than requiring z.infer<> resolution at the type level.\n */\n\nimport {\n getSchemaExportedVariableNameForPrimitiveType,\n getSchemaExportedVariableNameForStringFormat,\n} from \"./registry\";\nimport type { AnySchema } from \"./types/types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\ntype SchemaToTypeOptions = {\n outputSchemaNames?: Set<string>;\n};\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction toPascalCase(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\nexport function schemaExportNameToOutputAlias(name: string): string {\n return `${toPascalCase(name)}Output`;\n}\n\nfunction registerOutputSchemaName(\n schemaName: string,\n options?: SchemaToTypeOptions,\n): string {\n options?.outputSchemaNames?.add(schemaName);\n return schemaExportNameToOutputAlias(schemaName);\n}\n\nfunction getRegisteredOutputAlias(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string | undefined {\n if (!schema || typeof schema !== \"object\") return undefined;\n\n if (schema[\"type\"] === \"string\" && typeof schema[\"format\"] === \"string\") {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema[\"format\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n if (\n schema[\"type\"] === \"number\" ||\n schema[\"type\"] === \"integer\" ||\n schema[\"type\"] === \"boolean\"\n ) {\n const customSchemaName = getSchemaExportedVariableNameForPrimitiveType(\n schema[\"type\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n return undefined;\n}\n\n/**\n * Converts an OpenAPI schema to a TypeScript type string.\n *\n * @example\n * schemaToTypeString({ type: 'string' }) // => 'string'\n * schemaToTypeString({ type: 'object', properties: { id: { type: 'string' } } }) // => '{ id?: string }'\n */\nexport function schemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n if (!schema || typeof schema !== \"object\") return \"unknown\";\n\n // Handle $ref\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"unknown\";\n if (match && match[1]) {\n // Decode URI-encoded schema names (e.g., %20 -> space)\n result = decodeURIComponent(match[1]);\n }\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n return result;\n }\n\n let result: string = \"unknown\";\n\n // Handle oneOf (union)\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n const unionMembers = (schema[\"oneOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle allOf (intersection)\n else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n const intersectionMembers = (schema[\"allOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = intersectionMembers.length > 1\n ? `(${intersectionMembers.join(\" & \")})`\n : intersectionMembers[0] ?? \"unknown\";\n }\n // Handle anyOf (union, similar to oneOf)\n else if (\"anyOf\" in schema && Array.isArray(schema[\"anyOf\"])) {\n const unionMembers = (schema[\"anyOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle type-based schemas\n else {\n switch (schema[\"type\"]) {\n case \"string\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // String enum\n result = (schema[\"enum\"] as string[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"string\";\n }\n break;\n }\n case \"number\":\n case \"integer\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Numeric enum\n result = (schema[\"enum\"] as number[]).map((v) => String(v)).join(\" | \");\n } else {\n result = \"number\";\n }\n break;\n }\n case \"boolean\":\n result = getRegisteredOutputAlias(schema, options) ?? \"boolean\";\n break;\n case \"null\":\n result = \"null\";\n break;\n case \"array\":\n if (schema[\"items\"]) {\n const itemType = schemaToTypeString(schema[\"items\"] as AnySchema, options);\n result = `Array<${itemType}>`;\n } else {\n result = \"unknown[]\";\n }\n break;\n case \"object\":\n result = objectSchemaToTypeString(schema, options);\n break;\n default:\n // Try to detect object from properties\n if (schema[\"properties\"]) {\n result = objectSchemaToTypeString(schema, options);\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Untyped enum\n result = (schema[\"enum\"] as unknown[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"unknown\";\n }\n break;\n }\n }\n\n // Handle nullable\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n\n return result;\n}\n\n/**\n * Converts an OpenAPI object schema to a TypeScript object type string.\n */\nfunction objectSchemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n const additionalProperties = schema[\"additionalProperties\"];\n\n if (!properties && !additionalProperties) {\n return \"Record<string, unknown>\";\n }\n\n const propertyStrings: string[] = [];\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n propertyStrings.push(\n `${quotedName}${isRequired ? \"\" : \"?\"}: ${propType}`,\n );\n }\n }\n\n // Handle additionalProperties\n if (additionalProperties === true) {\n propertyStrings.push(\"[key: string]: unknown\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n propertyStrings.push(`[key: string]: ${additionalType}`);\n }\n\n return `{ ${propertyStrings.join(\"; \")} }`;\n}\n\n/**\n * Generates a full TypeScript interface declaration.\n *\n * @example\n * generateInterface('User', { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] })\n * // => 'export interface User { id: string; }'\n */\nexport function generateInterface(\n name: string,\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n\n // For non-object types, use type alias instead of interface\n if (schema[\"type\"] !== \"object\" && !properties) {\n return `export type ${name} = ${schemaToTypeString(schema, options)};`;\n }\n\n const lines: string[] = [];\n lines.push(`export interface ${name} {`);\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n lines.push(` ${quotedName}${isRequired ? \"\" : \"?\"}: ${propType};`);\n }\n }\n\n // Handle additionalProperties\n const additionalProperties = schema[\"additionalProperties\"];\n if (additionalProperties === true) {\n lines.push(\" [key: string]: unknown;\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n lines.push(` [key: string]: ${additionalType};`);\n }\n\n lines.push(\"}\");\n return lines.join(\"\\n\");\n}\n","import { topologicalSortSchemas } from \"./dependencies\";\nimport {\n createSchemaRegistry,\n findCommonSchemas,\n getSchemaFingerprint,\n preRegisterSchema,\n registerSchema,\n type SchemaRegistry,\n} from \"./schema-dedup\";\nimport { convertSchemaToZodString } from \"./to-zod\";\nimport type { AnySchema } from \"./types/types\";\nimport {\n parseOpenApiPaths,\n generateRouteSchemaNames,\n type RouteInfo,\n} from \"./routes\";\nimport { generateInterface, schemaExportNameToOutputAlias } from \"./interface-generator\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: string,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map((word) => {\n // Convert hyphenated words to PascalCase (e.g., \"timer-drafts\" -> \"TimerDrafts\")\n return word\n .split(/[-_]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase())\n .join(\"\");\n });\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\n/**\n * Result of route schema generation including declarations and name mappings.\n */\ninterface RouteSchemaResult {\n /** Schema declarations to be emitted */\n declarations: string[];\n /** Maps route-specific schema name to its canonical name (for deduplication) */\n schemaNameToCanonical: Map<string, string>;\n}\n\nfunction generateRouteSchemas(\n routes: RouteInfo[],\n convertSchema: (schema: AnySchema) => string,\n registry: SchemaRegistry,\n): RouteSchemaResult {\n const declarations: string[] = [];\n const schemaNameToCanonical = new Map<string, string>();\n const generatedNames = new Set<string>();\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n // Generate params schema with deduplication\n if (names.paramsSchemaName && pathParams.length > 0) {\n const paramsSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n pathParams.map((p) => [p.name, p.schema]),\n ),\n required: pathParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.paramsSchemaName,\n paramsSchema,\n );\n schemaNameToCanonical.set(names.paramsSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n const properties: string[] = [];\n for (const param of pathParams) {\n const zodExpr = convertSchema(param.schema);\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.paramsSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.paramsSchemaName !== canonicalName) {\n if (!generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n declarations.push(\n `export const ${names.paramsSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate query schema with deduplication\n if (names.querySchemaName && queryParams.length > 0) {\n const querySchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n queryParams.map((p) => [p.name, p.schema]),\n ),\n required: queryParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.querySchemaName,\n querySchema,\n );\n schemaNameToCanonical.set(names.querySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n const properties: string[] = [];\n for (const param of queryParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.querySchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.querySchemaName !== canonicalName) {\n if (!generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n declarations.push(\n `export const ${names.querySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate headers schema with deduplication\n if (names.headersSchemaName && headerParams.length > 0) {\n const headersSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n headerParams.map((p) => [p.name, p.schema]),\n ),\n required: headerParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.headersSchemaName,\n headersSchema,\n );\n schemaNameToCanonical.set(names.headersSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n const properties: string[] = [];\n for (const param of headerParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.headersSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.headersSchemaName !== canonicalName) {\n if (!generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n declarations.push(\n `export const ${names.headersSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate body schema with deduplication\n if (names.bodySchemaName && route.requestBody) {\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.bodySchemaName,\n route.requestBody,\n );\n schemaNameToCanonical.set(names.bodySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n const zodExpr = convertSchema(route.requestBody);\n declarations.push(`export const ${names.bodySchemaName} = ${zodExpr};`);\n } else if (!isNew && names.bodySchemaName !== canonicalName) {\n if (!generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n declarations.push(\n `export const ${names.bodySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate schemas for ALL status codes with deduplication\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n responseSchemaName,\n responseSchema,\n );\n schemaNameToCanonical.set(responseSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n const zodExpr = convertSchema(responseSchema);\n declarations.push(`export const ${responseSchemaName} = ${zodExpr};`);\n } else if (!isNew && responseSchemaName !== canonicalName) {\n if (!generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n declarations.push(\n `export const ${responseSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n }\n\n return { declarations, schemaNameToCanonical };\n}\n\nfunction generateRequestResponseObjects(\n routes: RouteInfo[],\n schemaNameToCanonical: Map<string, string>,\n): string[] {\n const lines: string[] = [];\n const requestPaths: Record<string, Record<string, string[]>> = {};\n const responsePaths: Record<\n string,\n Record<string, Record<string, string>>\n > = {};\n\n /**\n * Resolves a schema name to its canonical name if it exists,\n * otherwise returns the original name.\n */\n const resolveSchemaName = (name: string): string => {\n return schemaNameToCanonical.get(name) ?? name;\n };\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n if (!requestPaths[route.path]) {\n requestPaths[route.path] = {};\n }\n const requestMethodObj = requestPaths[route.path]!;\n if (!requestMethodObj[route.method]) {\n requestMethodObj[route.method] = [];\n }\n\n const requestParts: string[] = [];\n if (names.paramsSchemaName && pathParams.length > 0) {\n requestParts.push(\n `params: ${resolveSchemaName(names.paramsSchemaName)}`,\n );\n }\n if (names.querySchemaName && queryParams.length > 0) {\n requestParts.push(`query: ${resolveSchemaName(names.querySchemaName)}`);\n }\n if (names.headersSchemaName && headerParams.length > 0) {\n requestParts.push(\n `headers: ${resolveSchemaName(names.headersSchemaName)}`,\n );\n }\n if (names.bodySchemaName && route.requestBody) {\n requestParts.push(`body: ${resolveSchemaName(names.bodySchemaName)}`);\n }\n\n if (requestParts.length > 0) {\n requestMethodObj[route.method] = requestParts;\n }\n\n // Store all status codes in nested structure\n if (!responsePaths[route.path]) {\n responsePaths[route.path] = {};\n }\n const responseMethodObj = responsePaths[route.path]!;\n if (!responseMethodObj[route.method]) {\n responseMethodObj[route.method] = {};\n }\n\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n // Use canonical name for the Response object\n responseMethodObj[route.method]![statusCode] =\n resolveSchemaName(responseSchemaName);\n }\n }\n\n lines.push(\"export const Request = {\");\n for (const [path, methods] of Object.entries(requestPaths)) {\n const methodEntries = Object.entries(methods).filter(\n ([, parts]) => parts.length > 0,\n );\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, parts] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const part of parts) {\n lines.push(` ${part},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n lines.push(\"\");\n\n lines.push(\"export const Response = {\");\n for (const [path, methods] of Object.entries(responsePaths)) {\n const methodEntries = Object.entries(methods);\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, statusCodes] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const [statusCode, schemaName] of Object.entries(statusCodes)) {\n lines.push(` '${statusCode}': ${schemaName},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n\n return lines;\n}\n\n/**\n * Collects all response schemas from routes for common schema detection.\n */\nfunction collectRouteSchemas(\n routes: RouteInfo[],\n): Array<{ name: string; schema: AnySchema }> {\n const collected: Array<{ name: string; schema: AnySchema }> = [];\n\n for (const route of routes) {\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n collected.push({ name: responseSchemaName, schema: responseSchema });\n }\n }\n\n return collected;\n}\n\nexport const openApiToZodTsCode = (\n openapi: Record<string, unknown>,\n customImportLines?: string[],\n options?: { includeRoutes?: boolean },\n): string => {\n const components = (openapi as AnySchema)[\"components\"] as\n | AnySchema\n | undefined;\n const schemas: Record<string, AnySchema> =\n (components?.[\"schemas\"] as Record<string, AnySchema>) ?? {};\n\n const lines: string[] = [];\n lines.push(\"/**\");\n lines.push(\" * This file was automatically generated from OpenAPI schema\");\n lines.push(\" * Do not manually edit this file\");\n lines.push(\" */\");\n lines.push(\"\");\n lines.push(\"import { z } from 'zod';\");\n lines.push(...(customImportLines ?? []));\n lines.push(\"\");\n\n // Type assertion helper for compile-time verification\n lines.push(\"// Type assertion helper - verifies interface matches schema at compile time\");\n lines.push(\"type _AssertEqual<T, U> = [T] extends [U] ? ([U] extends [T] ? true : never) : never;\");\n lines.push(\"\");\n\n // Create registry for schema deduplication\n const registry = createSchemaRegistry();\n\n const sortedSchemaNames = topologicalSortSchemas(schemas);\n\n // Collect all type assertions to emit after all schemas\n const typeAssertions: string[] = [];\n const outputSchemaNames = new Set<string>();\n const schemaBlocks: string[] = [];\n\n for (const name of sortedSchemaNames) {\n const schema = schemas[name];\n if (schema) {\n const zodExpr = convertSchemaToZodString(schema);\n const schemaName = `${name}Schema`;\n const typeName = name;\n\n // Generate interface (concrete type in .d.ts)\n schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));\n\n // Generate schema with ZodType<T> annotation (simple type in .d.ts)\n schemaBlocks.push(`export const ${schemaName}: z.ZodType<${typeName}> = ${zodExpr};`);\n schemaBlocks.push(\"\");\n\n // Add type assertion to verify interface matches schema\n typeAssertions.push(`type _Assert${typeName} = _AssertEqual<${typeName}, z.infer<typeof ${schemaName}>>;`);\n\n // Register component schemas so they can be referenced by route schemas\n const fingerprint = getSchemaFingerprint(schema);\n preRegisterSchema(registry, schemaName, fingerprint);\n }\n }\n\n if (outputSchemaNames.size > 0) {\n lines.push(\"// Zod output aliases for registered schemas\");\n for (const schemaName of outputSchemaNames) {\n const aliasName = schemaExportNameToOutputAlias(schemaName);\n lines.push(`type ${aliasName} = z.output<typeof ${schemaName}>;`);\n }\n lines.push(\"\");\n }\n\n lines.push(...schemaBlocks);\n\n // Emit all type assertions\n if (typeAssertions.length > 0) {\n lines.push(\"// Compile-time type assertions - ensure interfaces match schemas\");\n lines.push(typeAssertions.join(\"\\n\"));\n lines.push(\"\");\n }\n\n if (options?.includeRoutes) {\n const routes = parseOpenApiPaths(openapi);\n if (routes.length > 0) {\n // Find common schemas that appear multiple times (for error responses, etc.)\n const routeSchemaList = collectRouteSchemas(routes);\n const commonSchemas = findCommonSchemas(routeSchemaList, 2);\n\n // Generate common schemas first (e.g., UnauthorizedErrorSchema, NotFoundErrorSchema)\n if (commonSchemas.length > 0) {\n lines.push(\"// Common Error Schemas (deduplicated)\");\n for (const common of commonSchemas) {\n const zodExpr = convertSchemaToZodString(common.schema);\n lines.push(`export const ${common.name} = ${zodExpr};`);\n // Pre-register so route schemas reference this instead of duplicating\n preRegisterSchema(registry, common.name, common.fingerprint);\n }\n lines.push(\"\");\n }\n\n // Generate route schemas with deduplication\n const { declarations, schemaNameToCanonical } = generateRouteSchemas(\n routes,\n convertSchemaToZodString,\n registry,\n );\n\n if (declarations.length > 0) {\n lines.push(\"// Route Schemas\");\n lines.push(...declarations);\n lines.push(\"\");\n\n // Generate Request/Response objects using canonical names\n const requestResponseObjs = generateRequestResponseObjects(\n routes,\n schemaNameToCanonical,\n );\n lines.push(...requestResponseObjs);\n }\n }\n }\n\n return lines.join(\"\\n\");\n};\n"],"mappings":"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","names":["result","validIdentifierRegex","quotePropertyName","toPascalCase","result","validIdentifierRegex","quotePropertyName","generateRouteSchemaName"]}
|
|
1
|
+
{"version":3,"sources":["../src/dependencies.ts","../src/schema-dedup.ts","../src/types/boolean.ts","../src/types/number.ts","../src/registry.ts","../src/types/string.ts","../src/types/array.ts","../src/types/object.ts","../src/types/union.ts","../src/types/intersection.ts","../src/to-zod.ts","../src/routes.ts","../src/interface-generator.ts","../src/to-typescript.ts"],"sourcesContent":["import type { AnySchema } from \"./types/types\";\n\n/**\n * Extracts all schema references ($ref) from an OpenAPI schema by recursively\n * traversing its structure.\n *\n * This function is used during the OpenAPI-to-Zod conversion process to identify\n * which schemas a given schema depends on. It traverses all OpenAPI schema\n * structures including objects, arrays, unions (oneOf), intersections (allOf),\n * conditionals (if/then/else), and discriminator mappings to find all $ref\n * references that point to other schemas in the components/schemas section.\n *\n * The extracted dependency names are used by `topologicalSortSchemas` to build\n * a dependency graph and determine the correct order for generating Zod schemas,\n * ensuring that referenced schemas are defined before they are used in the\n * generated TypeScript code.\n *\n * @param schema - The OpenAPI schema to extract dependencies from\n * @returns An array of schema names that this schema references (via $ref)\n */\nexport function extractSchemaDependencies(schema: AnySchema): string[] {\n const dependencies: Set<string> = new Set();\n const visited = new WeakSet();\n\n function traverse(obj: any): void {\n if (!obj || typeof obj !== \"object\") return;\n\n if (visited.has(obj)) return;\n visited.add(obj);\n\n if (obj[\"$ref\"] && typeof obj[\"$ref\"] === \"string\") {\n const match = (obj[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n if (match && match[1]) {\n dependencies.add(decodeURIComponent(match[1]));\n }\n return;\n }\n\n if (Array.isArray(obj)) {\n obj.forEach(traverse);\n return;\n }\n\n if (obj.properties && typeof obj.properties === \"object\") {\n for (const propValue of Object.values(obj.properties)) {\n traverse(propValue);\n }\n }\n\n const schemaKeys = [\n \"items\",\n \"oneOf\",\n \"allOf\",\n \"anyOf\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n \"prefixItems\",\n \"contains\",\n \"propertyNames\",\n \"dependentSchemas\",\n ];\n\n for (const key of schemaKeys) {\n if (obj[key]) {\n traverse(obj[key]);\n }\n }\n\n if (\n obj.additionalProperties &&\n typeof obj.additionalProperties === \"object\"\n ) {\n traverse(obj.additionalProperties);\n }\n\n if (obj.discriminator?.mapping) {\n Object.values(obj.discriminator.mapping).forEach(traverse);\n }\n }\n\n traverse(schema);\n return Array.from(dependencies);\n}\n\n/**\n * Sorts OpenAPI schemas topologically based on their dependencies to ensure\n * correct generation order.\n *\n * When converting OpenAPI schemas to Zod schemas and generating TypeScript code,\n * schemas must be defined before they are referenced. For example, if `UserSchema`\n * references `ProfileSchema` (via $ref), then `ProfileSchema` must be generated\n * before `UserSchema` to avoid \"undefined variable\" errors in the generated code.\n *\n * This function uses Kahn's algorithm for topological sorting to order schemas\n * such that all dependencies come before their dependents. It:\n * 1. Extracts dependencies for each schema using `extractSchemaDependencies`\n * 2. Builds a dependency graph and computes in-degrees\n * 3. Sorts schemas starting with those that have no dependencies (in-degree 0)\n * 4. Handles circular dependencies gracefully by appending any remaining schemas\n * that couldn't be sorted (though this indicates a problematic schema structure)\n *\n * This function is called by `openApiToZodTsCode` to determine the order in which\n * schemas should be converted and emitted in the generated TypeScript file.\n *\n * @param schemas - A record mapping schema names to their OpenAPI schema definitions\n * @returns An array of schema names sorted in topological order (dependencies before dependents)\n */\nexport function topologicalSortSchemas(\n schemas: Record<string, AnySchema>,\n): string[] {\n const schemaNames = Object.keys(schemas);\n const dependencies: Map<string, string[]> = new Map();\n const inDegree: Map<string, number> = new Map();\n const sorted: string[] = [];\n const queue: string[] = [];\n const dependents: Map<string, string[]> = new Map();\n\n for (const name of schemaNames) {\n dependencies.set(name, []);\n dependents.set(name, []);\n inDegree.set(name, 0);\n }\n\n for (const name of schemaNames) {\n const schemaValue = schemas[name];\n if (schemaValue) {\n const deps = extractSchemaDependencies(schemaValue);\n const validDeps = deps.filter((dep) => schemaNames.includes(dep));\n dependencies.set(name, validDeps);\n\n for (const dep of validDeps) {\n const currentDependents = dependents.get(dep) || [];\n currentDependents.push(name);\n dependents.set(dep, currentDependents);\n }\n }\n }\n\n for (const [name, deps] of dependencies.entries()) {\n inDegree.set(name, deps.length);\n }\n\n for (const [name, degree] of inDegree.entries()) {\n if (degree === 0) {\n queue.push(name);\n }\n }\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n sorted.push(current);\n\n const currentDependents = dependents.get(current) || [];\n for (const dependent of currentDependents) {\n const newDegree = (inDegree.get(dependent) || 0) - 1;\n inDegree.set(dependent, newDegree);\n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n if (sorted.length !== schemaNames.length) {\n for (const name of schemaNames) {\n if (!sorted.includes(name)) {\n sorted.push(name);\n }\n }\n }\n\n return sorted;\n}\n","import type { AnySchema } from \"./types/types\";\n\n/**\n * Schema deduplication utilities for optimizing generated TypeScript types.\n *\n * This module provides fingerprinting and registry functionality to detect\n * structurally identical schemas and generate them only once, reducing\n * memory usage in consuming TypeScript projects.\n */\n\n/**\n * Recursively sorts an object's keys to create a stable representation.\n * This ensures that {a: 1, b: 2} and {b: 2, a: 1} produce the same fingerprint.\n */\nfunction sortObjectDeep(obj: unknown): unknown {\n if (obj === null || typeof obj !== \"object\") return obj;\n if (Array.isArray(obj)) return obj.map(sortObjectDeep);\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj as Record<string, unknown>).sort();\n for (const key of keys) {\n sorted[key] = sortObjectDeep((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n}\n\n/**\n * Generates a canonical fingerprint for an OpenAPI schema.\n * Identical schemas will produce identical fingerprints.\n */\nexport function getSchemaFingerprint(schema: AnySchema): string {\n return JSON.stringify(sortObjectDeep(schema));\n}\n\n/**\n * Registry for tracking unique schemas and their canonical names.\n */\nexport interface SchemaRegistry {\n /** Map from fingerprint to the first schema name that used it */\n fingerprintToName: Map<string, string>;\n /** Map from schema name to its fingerprint (for reverse lookup) */\n nameToFingerprint: Map<string, string>;\n}\n\n/**\n * Creates a new empty schema registry.\n */\nexport function createSchemaRegistry(): SchemaRegistry {\n return {\n fingerprintToName: new Map(),\n nameToFingerprint: new Map(),\n };\n}\n\n/**\n * Result of registering a schema.\n */\nexport interface RegisterSchemaResult {\n /** Whether this is a new unique schema */\n isNew: boolean;\n /** The canonical name for this schema (may be different from input name if duplicate) */\n canonicalName: string;\n}\n\n/**\n * Registers a schema in the registry. If an identical schema already exists,\n * returns the existing canonical name instead.\n */\nexport function registerSchema(\n registry: SchemaRegistry,\n name: string,\n schema: AnySchema,\n): RegisterSchemaResult {\n const fingerprint = getSchemaFingerprint(schema);\n\n const existing = registry.fingerprintToName.get(fingerprint);\n if (existing) {\n return { isNew: false, canonicalName: existing };\n }\n\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n return { isNew: true, canonicalName: name };\n}\n\n/**\n * Pre-registers a schema with a specific fingerprint.\n * Used for common schemas that should take priority.\n */\nexport function preRegisterSchema(\n registry: SchemaRegistry,\n name: string,\n fingerprint: string,\n): void {\n registry.fingerprintToName.set(fingerprint, name);\n registry.nameToFingerprint.set(name, fingerprint);\n}\n\n/**\n * Extracts the error code from an OpenAPI error schema.\n * Looks for patterns like: { error: { code: enum(['UNAUTHORIZED']) } }\n */\nexport function extractErrorCode(schema: AnySchema): string | null {\n const properties = schema?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const errorObj = properties?.[\"error\"] as AnySchema | undefined;\n const errorProps = errorObj?.[\"properties\"] as Record<string, AnySchema> | undefined;\n const codeSchema = errorProps?.[\"code\"] as AnySchema | undefined;\n const codeEnum = codeSchema?.[\"enum\"] as string[] | undefined;\n\n if (Array.isArray(codeEnum) && codeEnum.length === 1) {\n return codeEnum[0]!;\n }\n return null;\n}\n\n/**\n * Converts an error code like UNAUTHORIZED or NOT_FOUND to PascalCase.\n * UNAUTHORIZED -> Unauthorized\n * NOT_FOUND -> NotFound\n */\nexport function errorCodeToPascalCase(code: string): string {\n return code\n .split(\"_\")\n .map((part) => part.charAt(0) + part.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Generates a common error schema name from an error code.\n * UNAUTHORIZED -> UnauthorizedErrorSchema\n */\nexport function generateCommonErrorSchemaName(errorCode: string): string {\n return `${errorCodeToPascalCase(errorCode)}ErrorSchema`;\n}\n\n/**\n * Represents a common schema that appears multiple times.\n */\nexport interface CommonSchema {\n /** The canonical name for this schema */\n name: string;\n /** The schema definition */\n schema: AnySchema;\n /** The fingerprint for deduplication */\n fingerprint: string;\n /** Number of times this schema appears */\n count: number;\n}\n\n/**\n * Scans schemas and identifies those that appear multiple times.\n * Returns common schemas sorted by count (most common first).\n */\nexport function findCommonSchemas(\n schemas: Array<{ name: string; schema: AnySchema }>,\n minCount: number = 2,\n): CommonSchema[] {\n const fingerprints = new Map<\n string,\n { schema: AnySchema; names: string[]; errorCode: string | null }\n >();\n\n // Count occurrences of each unique schema\n for (const { name, schema } of schemas) {\n const fingerprint = getSchemaFingerprint(schema);\n const existing = fingerprints.get(fingerprint);\n\n if (existing) {\n existing.names.push(name);\n } else {\n fingerprints.set(fingerprint, {\n schema,\n names: [name],\n errorCode: extractErrorCode(schema),\n });\n }\n }\n\n // Filter to schemas appearing minCount+ times\n const commonSchemas: CommonSchema[] = [];\n for (const [fingerprint, data] of fingerprints) {\n if (data.names.length >= minCount) {\n // Generate a semantic name if it's an error schema, otherwise use first occurrence\n const name = data.errorCode\n ? generateCommonErrorSchemaName(data.errorCode)\n : data.names[0]!;\n\n commonSchemas.push({\n name,\n schema: data.schema,\n fingerprint,\n count: data.names.length,\n });\n }\n }\n\n // Sort by count descending (most common first)\n return commonSchemas.sort((a, b) => b.count - a.count);\n}\n","/**\n * Convert an OpenAPI v3 boolean schema to a Zod schema string\n */\nexport function convertOpenAPIBooleanToZod(_: { type: \"boolean\" }): string {\n return \"z.boolean()\";\n}\n","/**\n * Convert an OpenAPI v3 number/integer schema to a Zod schema string\n */\nexport function convertOpenAPINumberToZod(schema: {\n type: \"number\" | \"integer\";\n minimum?: number;\n maximum?: number;\n}): string {\n let result = \"z.number()\";\n if (schema.type === \"integer\") {\n result += \".int()\";\n }\n if (typeof schema.minimum === \"number\") {\n result += `.min(${schema.minimum})`;\n }\n if (typeof schema.maximum === \"number\") {\n result += `.max(${schema.maximum})`;\n }\n return result;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst SUPPORTED_STRING_FORMATS_MAP = {\n \"color-hex\": 1,\n date: 1,\n \"date-time\": 1,\n email: 1,\n \"iso-date\": 1,\n \"iso-date-time\": 1,\n objectid: 1,\n uri: 1,\n url: 1,\n uuid: 1,\n} as const;\n\nexport const SUPPORTED_STRING_FORMATS = Object.keys(\n SUPPORTED_STRING_FORMATS_MAP,\n) as unknown as keyof typeof SUPPORTED_STRING_FORMATS_MAP;\n\ntype SupportedStringFormat = typeof SUPPORTED_STRING_FORMATS;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ZodOpenApiRegistrationString<\n F extends SupportedStringFormat = SupportedStringFormat,\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n format: F;\n};\n\nexport type ZodOpenApiRegistrationStrings<\n Fs extends\n readonly SupportedStringFormat[] = readonly SupportedStringFormat[],\n> = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n type: \"string\";\n description?: string;\n formats: Fs;\n};\n\nexport type ZodOpenApiRegistrationPrimitive = {\n /** The name of the schema variable, IMPORTANT: must be named the same as the variable name */\n schemaExportedVariableName: string;\n description?: string;\n type: \"number\" | \"integer\" | \"boolean\";\n};\n\nexport type ZodOpenApiRegistration =\n | ZodOpenApiRegistrationString\n | ZodOpenApiRegistrationStrings\n | ZodOpenApiRegistrationPrimitive;\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isStringRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationString {\n return reg.type === \"string\" && \"format\" in reg;\n}\n\nfunction isStringsRegistration(\n reg: ZodOpenApiRegistration,\n): reg is ZodOpenApiRegistrationStrings {\n return reg.type === \"string\" && \"formats\" in reg;\n}\n\nfunction isSupportedStringFormat(\n format: string,\n): format is SupportedStringFormat {\n return Object.prototype.hasOwnProperty.call(SUPPORTED_STRING_FORMATS_MAP, format);\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\ntype TypeFormatPair = { type: string; format: string | undefined };\n\nfunction getTypeFormatPairs(reg: ZodOpenApiRegistration): TypeFormatPair[] {\n if (isStringRegistration(reg)) {\n return [{ type: \"string\", format: reg.format }];\n }\n\n if (isStringsRegistration(reg)) {\n return reg.formats.map((f) => ({ type: \"string\", format: f }));\n }\n\n return [];\n}\n\n// ============================================================================\n// Registry Class\n// ============================================================================\n\n/**\n * Global registry for mapping Zod schemas to OpenAPI schema representations\n */\nclass ZodSchemaRegistry {\n private readonly map = new Map<z.ZodTypeAny, ZodOpenApiRegistration>();\n\n /**\n * Register a Zod schema with its OpenAPI representation\n */\n register<F extends SupportedStringFormat>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationString<F>,\n ): void;\n register<Fs extends readonly SupportedStringFormat[]>(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationStrings<Fs>,\n ): void;\n register(\n schema: z.ZodTypeAny,\n registration: ZodOpenApiRegistrationPrimitive,\n ): void;\n register(schema: z.ZodTypeAny, registration: ZodOpenApiRegistration): void {\n const newPairs = getTypeFormatPairs(registration);\n\n if (newPairs.length > 0) {\n for (const [existingSchema, existingRegistration] of this.map.entries()) {\n if (existingSchema === schema) continue;\n\n const existingPairs = getTypeFormatPairs(existingRegistration);\n for (const { type, format } of newPairs) {\n if (\n existingPairs.some((p) => p.type === type && p.format === format)\n ) {\n throw new Error(\n `duplicate Zod OpenAPI registration for (type, format)=('${type}', '${format as string}')`,\n );\n }\n }\n }\n }\n\n this.map.set(schema, registration);\n }\n\n /**\n * Get the OpenAPI schema for a given Zod schema\n */\n getOpenApiSchema(schema: z.ZodTypeAny): ZodOpenApiRegistration | undefined {\n return this.map.get(schema);\n }\n\n /**\n * Check if a Zod schema is registered\n */\n isRegistered(schema: z.ZodTypeAny): boolean {\n return this.map.has(schema);\n }\n\n /**\n * Clear all registered schemas\n */\n clear(): void {\n this.map.clear();\n }\n\n /**\n * Reverse-lookup helper: given a string format, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n ): string | undefined {\n if (!isSupportedStringFormat(format)) return undefined;\n for (const registration of this.map.values()) {\n if (registration.type !== \"string\") continue;\n\n if (\n isStringRegistration(registration) &&\n registration.format === format\n ) {\n return registration.schemaExportedVariableName;\n }\n\n if (\n isStringsRegistration(registration) &&\n registration.formats.includes(format)\n ) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n\n /**\n * Reverse-lookup helper: given a primitive type, return the registered schema's exported variable name\n */\n getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n ): string | undefined {\n for (const registration of this.map.values()) {\n if (registration.type === type) {\n return registration.schemaExportedVariableName;\n }\n }\n return undefined;\n }\n}\n\n// ============================================================================\n// Global Registry Instance\n// ============================================================================\n\nexport const schemaRegistry = new ZodSchemaRegistry();\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Helper function to register a Zod schema with its OpenAPI representation\n */\nexport function registerZodSchemaToOpenApiSchema(\n schema: z.ZodTypeAny,\n openApiSchema: ZodOpenApiRegistration,\n): void {\n schemaRegistry.register(schema, openApiSchema as any);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given string format\n */\nexport function getSchemaExportedVariableNameForStringFormat(\n format: SupportedStringFormat | string,\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForStringFormat(format);\n}\n\n/**\n * Convenience helper to get an exported schema variable name for a given primitive type\n */\nexport function getSchemaExportedVariableNameForPrimitiveType(\n type: ZodOpenApiRegistrationPrimitive[\"type\"],\n): string | undefined {\n return schemaRegistry.getSchemaExportedVariableNameForPrimitiveType(type);\n}\n\n/**\n * Clear all registered schemas in the global registry\n */\nexport function clearZodSchemaToOpenApiSchemaRegistry(): void {\n schemaRegistry.clear();\n}\n","import {\n getSchemaExportedVariableNameForStringFormat,\n SUPPORTED_STRING_FORMATS,\n} from \"../registry\";\n\n/**\n * Convert an OpenAPI v3 string schema to a Zod schema string\n */\nexport function convertOpenAPIStringToZod(schema: {\n type: \"string\";\n format?: typeof SUPPORTED_STRING_FORMATS;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n enum?: string[];\n}): string {\n // Handle enum values\n if (schema.enum) {\n return `z.enum([${schema.enum.map((value) => `'${value}'`).join(\", \")}])`;\n }\n\n // Check for custom registered format schemas\n if (schema.format && SUPPORTED_STRING_FORMATS.includes(schema.format)) {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema.format,\n );\n\n // Use custom schema if registered (ignores other constraints)\n if (customSchemaName) {\n return customSchemaName;\n }\n }\n\n // Build string schema with format modifiers\n let zodSchema = \"z.string()\";\n\n if (schema.format) {\n zodSchema += getFormatModifier(schema.format);\n }\n\n // Apply length constraints\n if (typeof schema.minLength === \"number\") {\n zodSchema += `.min(${schema.minLength})`;\n }\n\n if (typeof schema.maxLength === \"number\") {\n zodSchema += `.max(${schema.maxLength})`;\n }\n\n // Apply pattern constraint\n if (typeof schema.pattern === \"string\") {\n zodSchema += `.regex(/${schema.pattern}/)`;\n }\n\n return zodSchema;\n}\n\n/**\n * Get the Zod modifier for built-in string formats\n */\nfunction getFormatModifier(format: string): string {\n switch (format) {\n case \"email\":\n return \".email()\";\n case \"url\":\n case \"uri\":\n return \".url()\";\n case \"uuid\":\n return \".uuid()\";\n case \"color-hex\":\n return \".regex(/^[a-fA-F0-9]{6}$/)\";\n default:\n return \"\";\n }\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIArrayToZod(\n schema: {\n type: \"array\";\n items?: any;\n minItems?: number;\n maxItems?: number;\n },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const item = schema.items;\n\n let itemZodString = \"z.unknown()\";\n if (item && typeof item === \"object\") {\n itemZodString = convertSchema(item);\n }\n\n let result = `z.array(${itemZodString})`;\n\n if (typeof schema.minItems === \"number\") {\n result += `.min(${schema.minItems})`;\n }\n if (typeof schema.maxItems === \"number\") {\n result += `.max(${schema.maxItems})`;\n }\n\n return result;\n}\n","import { AnySchema, OpenAPIObjectSchema } from \"./types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nexport function convertOpenAPIObjectToZod(\n schema: OpenAPIObjectSchema,\n convertSchema: (schema: AnySchema) => string,\n): string {\n const properties = schema.properties || {};\n const propertyNames = Object.keys(properties);\n\n if (propertyNames.length === 0) {\n if (schema.additionalProperties === false) {\n return \"z.object({}).strict()\";\n }\n return \"z.record(z.string(), z.unknown())\";\n }\n\n const requiredSet = new Set(schema.required || []);\n\n const entries: string[] = [];\n for (const [propName, propSchema] of Object.entries(properties)) {\n let zodProp = \"z.unknown()\";\n\n if (propSchema && typeof propSchema === \"object\") {\n zodProp = convertSchema(propSchema);\n }\n\n if (!requiredSet.has(propName)) {\n zodProp += \".optional()\";\n }\n\n entries.push(`${quotePropertyName(propName)}: ${zodProp}`);\n }\n\n let result = `z.object({ ${entries.join(\", \")} })`;\n\n if (schema.additionalProperties === false) {\n result += \".strict()\";\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIUnionToZod(\n schema: { oneOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.oneOf.map((item) => convertSchema(item));\n return `z.union([${items.join(\", \")}])`;\n}\n\n","import type { AnySchema } from \"./types\";\n\nexport function convertOpenAPIIntersectionToZod(\n schema: { allOf: AnySchema[] },\n convertSchema: (schema: AnySchema) => string,\n): string {\n const items = schema.allOf.map((item) => convertSchema(item));\n\n if (schema.allOf.length === 0) return \"z.unknown()\";\n if (schema.allOf.length === 1) return convertSchema(schema.allOf[0]!);\n\n return `z.intersection(${items.join(\", \")})`;\n}\n\n","import { convertOpenAPIBooleanToZod } from \"./types/boolean\";\nimport { convertOpenAPINumberToZod } from \"./types/number\";\nimport { convertOpenAPIStringToZod } from \"./types/string\";\nimport { convertOpenAPIArrayToZod } from \"./types/array\";\nimport { convertOpenAPIObjectToZod } from \"./types/object\";\nimport { convertOpenAPIUnionToZod } from \"./types/union\";\nimport { convertOpenAPIIntersectionToZod } from \"./types/intersection\";\nimport type { AnySchema } from \"./types/types\";\n\nexport function convertSchemaToZodString(schema: AnySchema): string {\n if (!schema || typeof schema !== \"object\") return \"z.unknown()\";\n\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"z.unknown()\";\n if (match && match[1]) {\n result = `${match[1]}Schema`;\n }\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n return result;\n }\n let result: string = \"z.unknown()\";\n\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n result = convertOpenAPIUnionToZod(\n schema as { oneOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n result = convertOpenAPIIntersectionToZod(\n schema as { allOf: AnySchema[] },\n convertSchemaToZodString,\n );\n } else {\n switch (schema[\"type\"]) {\n case \"string\":\n result = convertOpenAPIStringToZod({\n enum: schema[\"enum\"],\n format: schema[\"format\"],\n maxLength: schema[\"maxLength\"],\n minLength: schema[\"minLength\"],\n pattern: schema[\"pattern\"],\n type: \"string\",\n });\n break;\n case \"number\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"number\",\n });\n break;\n case \"integer\":\n result = convertOpenAPINumberToZod({\n maximum: schema[\"maximum\"],\n minimum: schema[\"minimum\"],\n type: \"integer\",\n });\n break;\n case \"boolean\":\n result = convertOpenAPIBooleanToZod({ type: \"boolean\" });\n break;\n case \"array\":\n result = convertOpenAPIArrayToZod(\n {\n items: schema[\"items\"],\n maxItems: schema[\"maxItems\"],\n minItems: schema[\"minItems\"],\n type: \"array\",\n },\n convertSchemaToZodString,\n );\n break;\n case \"object\":\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n break;\n default:\n if (schema[\"properties\"]) {\n result = convertOpenAPIObjectToZod(\n {\n additionalProperties: schema[\"additionalProperties\"],\n properties: schema[\"properties\"],\n required: schema[\"required\"],\n type: \"object\",\n },\n convertSchemaToZodString,\n );\n } else {\n result = \"z.unknown()\";\n }\n break;\n }\n }\n\n if (schema[\"nullable\"] === true) {\n result = `z.union([${result}, z.null()])`;\n }\n\n return result;\n}\n","import type { AnySchema } from \"./types/types\";\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"HEAD\" | \"OPTIONS\";\n\nexport interface RouteParameter {\n name: string;\n in: \"path\" | \"query\" | \"header\" | \"cookie\";\n required: boolean;\n schema: AnySchema;\n}\n\nexport interface RouteInfo {\n path: string;\n method: HttpMethod;\n parameters: RouteParameter[];\n requestBody?: AnySchema;\n responses: Record<string, AnySchema>;\n}\n\nexport interface RouteSchemaNames {\n paramsSchemaName?: string;\n querySchemaName?: string;\n headersSchemaName?: string;\n bodySchemaName?: string;\n responseSchemaName?: string;\n}\n\nfunction toUpperCaseMethod(method: string): HttpMethod {\n const upper = method.toUpperCase();\n if (\n upper === \"GET\" ||\n upper === \"POST\" ||\n upper === \"PUT\" ||\n upper === \"PATCH\" ||\n upper === \"DELETE\" ||\n upper === \"HEAD\" ||\n upper === \"OPTIONS\"\n ) {\n return upper as HttpMethod;\n }\n return \"GET\";\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: HttpMethod,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map(toPascalCase);\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\nexport function parseOpenApiPaths(\n openapi: Record<string, unknown>,\n): RouteInfo[] {\n const paths = (openapi as AnySchema)[\"paths\"] as\n | Record<string, AnySchema>\n | undefined;\n if (!paths) {\n return [];\n }\n\n const routes: RouteInfo[] = [];\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem || typeof pathItem !== \"object\") continue;\n\n const methods = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"head\",\n \"options\",\n ] as const;\n\n for (const method of methods) {\n const operation = pathItem[method] as AnySchema | undefined;\n if (!operation) continue;\n\n const parameters: RouteParameter[] = [];\n const responses: Record<string, AnySchema> = {};\n\n if (Array.isArray(pathItem[\"parameters\"])) {\n for (const param of pathItem[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n if (Array.isArray(operation[\"parameters\"])) {\n for (const param of operation[\"parameters\"]) {\n if (param && typeof param === \"object\") {\n parameters.push({\n name: String(param[\"name\"] || \"\"),\n in: param[\"in\"] || \"query\",\n required: Boolean(param[\"required\"]),\n schema: param[\"schema\"] || {},\n });\n }\n }\n }\n\n let requestBody: AnySchema | undefined;\n if (operation[\"requestBody\"]) {\n const rb = operation[\"requestBody\"];\n if (rb && typeof rb === \"object\") {\n const content = rb[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n requestBody = jsonContent[\"schema\"] || {};\n }\n }\n }\n }\n\n if (operation[\"responses\"] && typeof operation[\"responses\"] === \"object\") {\n for (const [statusCode, response] of Object.entries(\n operation[\"responses\"],\n )) {\n if (response && typeof response === \"object\") {\n const responseSchema = response as AnySchema;\n const content = responseSchema[\"content\"];\n if (content && typeof content === \"object\") {\n const jsonContent = content[\"application/json\"];\n if (jsonContent && typeof jsonContent === \"object\") {\n const schema = jsonContent[\"schema\"];\n if (schema) {\n responses[statusCode] = schema;\n }\n }\n }\n }\n }\n }\n\n routes.push({\n path,\n method: toUpperCaseMethod(method),\n parameters,\n requestBody,\n responses,\n });\n }\n }\n\n return routes;\n}\n\nexport function generateRouteSchemaNames(\n route: RouteInfo,\n): RouteSchemaNames {\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n const successStatuses = Object.keys(route.responses).filter((s) =>\n s.startsWith(\"2\"),\n );\n\n const result: RouteSchemaNames = {\n responseSchemaName: successStatuses.length > 0\n ? generateRouteSchemaName(\n route.path,\n route.method,\n \"Response\",\n )\n : undefined,\n };\n\n if (pathParams.length > 0) {\n result.paramsSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Params\",\n );\n }\n\n if (queryParams.length > 0) {\n result.querySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Query\",\n );\n }\n\n if (headerParams.length > 0) {\n result.headersSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Headers\",\n );\n }\n\n if (route.requestBody) {\n result.bodySchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n \"Body\",\n );\n }\n\n return result;\n}\n\n","/**\n * Generates TypeScript interface/type strings from OpenAPI schemas.\n *\n * This produces concrete types that appear directly in .d.ts files,\n * rather than requiring z.infer<> resolution at the type level.\n */\n\nimport {\n getSchemaExportedVariableNameForPrimitiveType,\n getSchemaExportedVariableNameForStringFormat,\n} from \"./registry\";\nimport type { AnySchema } from \"./types/types\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\ntype SchemaToTypeOptions = {\n outputSchemaNames?: Set<string>;\n};\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction toPascalCase(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[^a-zA-Z0-9]/g, \" \")\n .split(\" \")\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\nexport function schemaExportNameToOutputAlias(name: string): string {\n return `${toPascalCase(name)}Output`;\n}\n\nfunction registerOutputSchemaName(\n schemaName: string,\n options?: SchemaToTypeOptions,\n): string {\n options?.outputSchemaNames?.add(schemaName);\n return schemaExportNameToOutputAlias(schemaName);\n}\n\nfunction getRegisteredOutputAlias(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string | undefined {\n if (!schema || typeof schema !== \"object\") return undefined;\n\n if (schema[\"type\"] === \"string\" && typeof schema[\"format\"] === \"string\") {\n const customSchemaName = getSchemaExportedVariableNameForStringFormat(\n schema[\"format\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n if (\n schema[\"type\"] === \"number\" ||\n schema[\"type\"] === \"integer\" ||\n schema[\"type\"] === \"boolean\"\n ) {\n const customSchemaName = getSchemaExportedVariableNameForPrimitiveType(\n schema[\"type\"],\n );\n if (customSchemaName) {\n return registerOutputSchemaName(customSchemaName, options);\n }\n }\n\n return undefined;\n}\n\n/**\n * Converts an OpenAPI schema to a TypeScript type string.\n *\n * @example\n * schemaToTypeString({ type: 'string' }) // => 'string'\n * schemaToTypeString({ type: 'object', properties: { id: { type: 'string' } } }) // => '{ id?: string }'\n */\nexport function schemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n if (!schema || typeof schema !== \"object\") return \"unknown\";\n\n // Handle $ref\n if (schema[\"$ref\"] && typeof schema[\"$ref\"] === \"string\") {\n const match = (schema[\"$ref\"] as string).match(\n /#\\/components\\/schemas\\/(.+)/,\n );\n let result = \"unknown\";\n if (match && match[1]) {\n // Decode URI-encoded schema names (e.g., %20 -> space)\n result = decodeURIComponent(match[1]);\n }\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n return result;\n }\n\n let result: string = \"unknown\";\n\n // Handle oneOf (union)\n if (\"oneOf\" in schema && Array.isArray(schema[\"oneOf\"])) {\n const unionMembers = (schema[\"oneOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle allOf (intersection)\n else if (\"allOf\" in schema && Array.isArray(schema[\"allOf\"])) {\n const intersectionMembers = (schema[\"allOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = intersectionMembers.length > 1\n ? `(${intersectionMembers.join(\" & \")})`\n : intersectionMembers[0] ?? \"unknown\";\n }\n // Handle anyOf (union, similar to oneOf)\n else if (\"anyOf\" in schema && Array.isArray(schema[\"anyOf\"])) {\n const unionMembers = (schema[\"anyOf\"] as AnySchema[]).map((s) =>\n schemaToTypeString(s, options),\n );\n result = unionMembers.length > 1 ? `(${unionMembers.join(\" | \")})` : unionMembers[0] ?? \"unknown\";\n }\n // Handle type-based schemas\n else {\n switch (schema[\"type\"]) {\n case \"string\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // String enum\n result = (schema[\"enum\"] as string[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"string\";\n }\n break;\n }\n case \"number\":\n case \"integer\": {\n const registeredAlias = getRegisteredOutputAlias(schema, options);\n if (registeredAlias) {\n result = registeredAlias;\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Numeric enum\n result = (schema[\"enum\"] as number[]).map((v) => String(v)).join(\" | \");\n } else {\n result = \"number\";\n }\n break;\n }\n case \"boolean\":\n result = getRegisteredOutputAlias(schema, options) ?? \"boolean\";\n break;\n case \"null\":\n result = \"null\";\n break;\n case \"array\":\n if (schema[\"items\"]) {\n const itemType = schemaToTypeString(schema[\"items\"] as AnySchema, options);\n result = `Array<${itemType}>`;\n } else {\n result = \"unknown[]\";\n }\n break;\n case \"object\":\n result = objectSchemaToTypeString(schema, options);\n break;\n default:\n // Try to detect object from properties\n if (schema[\"properties\"]) {\n result = objectSchemaToTypeString(schema, options);\n } else if (schema[\"enum\"] && Array.isArray(schema[\"enum\"])) {\n // Untyped enum\n result = (schema[\"enum\"] as unknown[])\n .map((v) => JSON.stringify(v))\n .join(\" | \");\n } else {\n result = \"unknown\";\n }\n break;\n }\n }\n\n // Handle nullable\n if (schema[\"nullable\"] === true) {\n result = `(${result} | null)`;\n }\n\n return result;\n}\n\n/**\n * Converts an OpenAPI object schema to a TypeScript object type string.\n */\nfunction objectSchemaToTypeString(\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n const additionalProperties = schema[\"additionalProperties\"];\n\n if (!properties && !additionalProperties) {\n return \"Record<string, unknown>\";\n }\n\n const propertyStrings: string[] = [];\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n propertyStrings.push(\n `${quotedName}${isRequired ? \"\" : \"?\"}: ${propType}`,\n );\n }\n }\n\n // Handle additionalProperties\n if (additionalProperties === true) {\n propertyStrings.push(\"[key: string]: unknown\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n propertyStrings.push(`[key: string]: ${additionalType}`);\n }\n\n return `{ ${propertyStrings.join(\"; \")} }`;\n}\n\n/**\n * Generates a full TypeScript interface declaration.\n *\n * @example\n * generateInterface('User', { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] })\n * // => 'export interface User { id: string; }'\n */\nexport function generateInterface(\n name: string,\n schema: AnySchema,\n options?: SchemaToTypeOptions,\n): string {\n const properties = schema[\"properties\"] as Record<string, AnySchema> | undefined;\n const required = new Set((schema[\"required\"] as string[]) ?? []);\n\n // For non-object types, use type alias instead of interface\n if (schema[\"type\"] !== \"object\" && !properties) {\n return `export type ${name} = ${schemaToTypeString(schema, options)};`;\n }\n\n const lines: string[] = [];\n lines.push(`export interface ${name} {`);\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.has(propName);\n const propType = schemaToTypeString(propSchema, options);\n const quotedName = quotePropertyName(propName);\n lines.push(` ${quotedName}${isRequired ? \"\" : \"?\"}: ${propType};`);\n }\n }\n\n // Handle additionalProperties\n const additionalProperties = schema[\"additionalProperties\"];\n if (additionalProperties === true) {\n lines.push(\" [key: string]: unknown;\");\n } else if (\n typeof additionalProperties === \"object\" &&\n additionalProperties !== null\n ) {\n const additionalType = schemaToTypeString(additionalProperties as AnySchema, options);\n lines.push(` [key: string]: ${additionalType};`);\n }\n\n lines.push(\"}\");\n return lines.join(\"\\n\");\n}\n","import { topologicalSortSchemas } from \"./dependencies\";\nimport {\n createSchemaRegistry,\n findCommonSchemas,\n getSchemaFingerprint,\n preRegisterSchema,\n registerSchema,\n type SchemaRegistry,\n} from \"./schema-dedup\";\nimport { convertSchemaToZodString } from \"./to-zod\";\nimport type { AnySchema } from \"./types/types\";\nimport {\n parseOpenApiPaths,\n generateRouteSchemaNames,\n type RouteInfo,\n} from \"./routes\";\nimport { generateInterface, schemaExportNameToOutputAlias } from \"./interface-generator\";\n\nconst validIdentifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;\n\nfunction quotePropertyName(name: string): string {\n return validIdentifierRegex.test(name) ? name : `'${name}'`;\n}\n\nfunction generateRouteSchemaName(\n path: string,\n method: string,\n suffix: string,\n): string {\n const pathParts = path\n .split(\"/\")\n .filter((p) => p)\n .map((p) => {\n if (p.startsWith(\"{\") && p.endsWith(\"}\")) {\n return p.slice(1, -1);\n }\n return p;\n })\n .map((word) => {\n // Convert hyphenated words to PascalCase (e.g., \"timer-drafts\" -> \"TimerDrafts\")\n return word\n .split(/[-_]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase())\n .join(\"\");\n });\n const methodPrefix = method.charAt(0) + method.slice(1).toLowerCase();\n const parts = [methodPrefix, ...pathParts, suffix];\n return parts.join(\"\");\n}\n\n/**\n * Result of route schema generation including declarations and name mappings.\n */\ninterface RouteSchemaResult {\n /** Schema declarations to be emitted */\n declarations: string[];\n /** Maps route-specific schema name to its canonical name (for deduplication) */\n schemaNameToCanonical: Map<string, string>;\n}\n\nfunction generateRouteSchemas(\n routes: RouteInfo[],\n convertSchema: (schema: AnySchema) => string,\n registry: SchemaRegistry,\n): RouteSchemaResult {\n const declarations: string[] = [];\n const schemaNameToCanonical = new Map<string, string>();\n const generatedNames = new Set<string>();\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n // Generate params schema with deduplication\n if (names.paramsSchemaName && pathParams.length > 0) {\n const paramsSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n pathParams.map((p) => [p.name, p.schema]),\n ),\n required: pathParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.paramsSchemaName,\n paramsSchema,\n );\n schemaNameToCanonical.set(names.paramsSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n const properties: string[] = [];\n for (const param of pathParams) {\n const zodExpr = convertSchema(param.schema);\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.paramsSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.paramsSchemaName !== canonicalName) {\n if (!generatedNames.has(names.paramsSchemaName)) {\n generatedNames.add(names.paramsSchemaName);\n declarations.push(\n `export const ${names.paramsSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate query schema with deduplication\n if (names.querySchemaName && queryParams.length > 0) {\n const querySchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n queryParams.map((p) => [p.name, p.schema]),\n ),\n required: queryParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.querySchemaName,\n querySchema,\n );\n schemaNameToCanonical.set(names.querySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n const properties: string[] = [];\n for (const param of queryParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.querySchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.querySchemaName !== canonicalName) {\n if (!generatedNames.has(names.querySchemaName)) {\n generatedNames.add(names.querySchemaName);\n declarations.push(\n `export const ${names.querySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate headers schema with deduplication\n if (names.headersSchemaName && headerParams.length > 0) {\n const headersSchema: AnySchema = {\n type: \"object\",\n properties: Object.fromEntries(\n headerParams.map((p) => [p.name, p.schema]),\n ),\n required: headerParams.filter((p) => p.required).map((p) => p.name),\n };\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.headersSchemaName,\n headersSchema,\n );\n schemaNameToCanonical.set(names.headersSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n const properties: string[] = [];\n for (const param of headerParams) {\n let zodExpr = convertSchema(param.schema);\n if (!param.required) {\n zodExpr += \".optional()\";\n }\n properties.push(`${quotePropertyName(param.name)}: ${zodExpr}`);\n }\n declarations.push(\n `export const ${names.headersSchemaName} = z.object({ ${properties.join(\", \")} });`,\n );\n } else if (!isNew && names.headersSchemaName !== canonicalName) {\n if (!generatedNames.has(names.headersSchemaName)) {\n generatedNames.add(names.headersSchemaName);\n declarations.push(\n `export const ${names.headersSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate body schema with deduplication\n if (names.bodySchemaName && route.requestBody) {\n const { isNew, canonicalName } = registerSchema(\n registry,\n names.bodySchemaName,\n route.requestBody,\n );\n schemaNameToCanonical.set(names.bodySchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n const zodExpr = convertSchema(route.requestBody);\n declarations.push(`export const ${names.bodySchemaName} = ${zodExpr};`);\n } else if (!isNew && names.bodySchemaName !== canonicalName) {\n if (!generatedNames.has(names.bodySchemaName)) {\n generatedNames.add(names.bodySchemaName);\n declarations.push(\n `export const ${names.bodySchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n\n // Generate schemas for ALL status codes with deduplication\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n const { isNew, canonicalName } = registerSchema(\n registry,\n responseSchemaName,\n responseSchema,\n );\n schemaNameToCanonical.set(responseSchemaName, canonicalName);\n\n if (isNew && !generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n const zodExpr = convertSchema(responseSchema);\n declarations.push(`export const ${responseSchemaName} = ${zodExpr};`);\n } else if (!isNew && responseSchemaName !== canonicalName) {\n if (!generatedNames.has(responseSchemaName)) {\n generatedNames.add(responseSchemaName);\n declarations.push(\n `export const ${responseSchemaName} = ${canonicalName};`,\n );\n }\n }\n }\n }\n\n return { declarations, schemaNameToCanonical };\n}\n\nfunction generateRequestResponseObjects(\n routes: RouteInfo[],\n schemaNameToCanonical: Map<string, string>,\n): string[] {\n const lines: string[] = [];\n const requestPaths: Record<string, Record<string, string[]>> = {};\n const responsePaths: Record<\n string,\n Record<string, Record<string, string>>\n > = {};\n\n /**\n * Resolves a schema name to its canonical name if it exists,\n * otherwise returns the original name.\n */\n const resolveSchemaName = (name: string): string => {\n return schemaNameToCanonical.get(name) ?? name;\n };\n\n for (const route of routes) {\n const names = generateRouteSchemaNames(route);\n const pathParams = route.parameters.filter((p) => p.in === \"path\");\n const queryParams = route.parameters.filter((p) => p.in === \"query\");\n const headerParams = route.parameters.filter((p) => p.in === \"header\");\n\n if (!requestPaths[route.path]) {\n requestPaths[route.path] = {};\n }\n const requestMethodObj = requestPaths[route.path]!;\n if (!requestMethodObj[route.method]) {\n requestMethodObj[route.method] = [];\n }\n\n const requestParts: string[] = [];\n if (names.paramsSchemaName && pathParams.length > 0) {\n requestParts.push(\n `params: ${resolveSchemaName(names.paramsSchemaName)}`,\n );\n }\n if (names.querySchemaName && queryParams.length > 0) {\n requestParts.push(`query: ${resolveSchemaName(names.querySchemaName)}`);\n }\n if (names.headersSchemaName && headerParams.length > 0) {\n requestParts.push(\n `headers: ${resolveSchemaName(names.headersSchemaName)}`,\n );\n }\n if (names.bodySchemaName && route.requestBody) {\n requestParts.push(`body: ${resolveSchemaName(names.bodySchemaName)}`);\n }\n\n if (requestParts.length > 0) {\n requestMethodObj[route.method] = requestParts;\n }\n\n // Store all status codes in nested structure\n if (!responsePaths[route.path]) {\n responsePaths[route.path] = {};\n }\n const responseMethodObj = responsePaths[route.path]!;\n if (!responseMethodObj[route.method]) {\n responseMethodObj[route.method] = {};\n }\n\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n // Use canonical name for the Response object\n responseMethodObj[route.method]![statusCode] =\n resolveSchemaName(responseSchemaName);\n }\n }\n\n lines.push(\"export const Request = {\");\n for (const [path, methods] of Object.entries(requestPaths)) {\n const methodEntries = Object.entries(methods).filter(\n ([, parts]) => parts.length > 0,\n );\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, parts] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const part of parts) {\n lines.push(` ${part},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n lines.push(\"\");\n\n lines.push(\"export const Response = {\");\n for (const [path, methods] of Object.entries(responsePaths)) {\n const methodEntries = Object.entries(methods);\n if (methodEntries.length > 0) {\n lines.push(` '${path}': {`);\n for (const [method, statusCodes] of methodEntries) {\n lines.push(` ${method}: {`);\n for (const [statusCode, schemaName] of Object.entries(statusCodes)) {\n lines.push(` '${statusCode}': ${schemaName},`);\n }\n lines.push(` },`);\n }\n lines.push(` },`);\n }\n }\n lines.push(\"} as const;\");\n\n return lines;\n}\n\n/**\n * Collects all response schemas from routes for common schema detection.\n */\nfunction collectRouteSchemas(\n routes: RouteInfo[],\n): Array<{ name: string; schema: AnySchema }> {\n const collected: Array<{ name: string; schema: AnySchema }> = [];\n\n for (const route of routes) {\n for (const [statusCode, responseSchema] of Object.entries(\n route.responses,\n )) {\n if (!responseSchema) continue;\n\n const isSuccess = statusCode.startsWith(\"2\");\n const suffix = isSuccess\n ? `${statusCode}Response`\n : `${statusCode}ErrorResponse`;\n const responseSchemaName = generateRouteSchemaName(\n route.path,\n route.method,\n suffix,\n );\n\n collected.push({ name: responseSchemaName, schema: responseSchema });\n }\n }\n\n return collected;\n}\n\nexport const openApiToZodTsCode = (\n openapi: Record<string, unknown>,\n customImportLines?: string[],\n options?: { includeRoutes?: boolean },\n): string => {\n const components = (openapi as AnySchema)[\"components\"] as\n | AnySchema\n | undefined;\n const schemas: Record<string, AnySchema> =\n (components?.[\"schemas\"] as Record<string, AnySchema>) ?? {};\n\n const lines: string[] = [];\n lines.push(\"/**\");\n lines.push(\" * This file was automatically generated from OpenAPI schema\");\n lines.push(\" * Do not manually edit this file\");\n lines.push(\" */\");\n lines.push(\"\");\n lines.push(\"import { z } from 'zod';\");\n lines.push(...(customImportLines ?? []));\n lines.push(\"\");\n\n // Type assertion helper for compile-time verification\n lines.push(\"// Type assertion helper - verifies interface matches schema at compile time\");\n lines.push(\"type _AssertEqual<T, U> = [T] extends [U] ? ([U] extends [T] ? true : never) : never;\");\n lines.push(\"\");\n\n // Create registry for schema deduplication\n const registry = createSchemaRegistry();\n\n const sortedSchemaNames = topologicalSortSchemas(schemas);\n\n // Collect all type assertions to emit after all schemas\n const typeAssertions: string[] = [];\n const outputSchemaNames = new Set<string>();\n const schemaBlocks: string[] = [];\n\n for (const name of sortedSchemaNames) {\n const schema = schemas[name];\n if (schema) {\n const zodExpr = convertSchemaToZodString(schema);\n const schemaName = `${name}Schema`;\n const typeName = name;\n\n // Generate interface (concrete type in .d.ts)\n schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));\n\n // Generate schema with ZodType<T> annotation (simple type in .d.ts)\n schemaBlocks.push(`export const ${schemaName} = ${zodExpr};`);\n schemaBlocks.push(\"\");\n\n // Add type assertion to verify interface matches schema\n typeAssertions.push(`type _Assert${typeName} = _AssertEqual<${typeName}, z.infer<typeof ${schemaName}>>;`);\n\n // Register component schemas so they can be referenced by route schemas\n const fingerprint = getSchemaFingerprint(schema);\n preRegisterSchema(registry, schemaName, fingerprint);\n }\n }\n\n if (outputSchemaNames.size > 0) {\n lines.push(\"// Zod output aliases for registered schemas\");\n for (const schemaName of outputSchemaNames) {\n const aliasName = schemaExportNameToOutputAlias(schemaName);\n lines.push(`type ${aliasName} = z.output<typeof ${schemaName}>;`);\n }\n lines.push(\"\");\n }\n\n lines.push(...schemaBlocks);\n\n // Emit all type assertions\n if (typeAssertions.length > 0) {\n lines.push(\"// Compile-time type assertions - ensure interfaces match schemas\");\n lines.push(typeAssertions.join(\"\\n\"));\n lines.push(\"\");\n }\n\n if (options?.includeRoutes) {\n const routes = parseOpenApiPaths(openapi);\n if (routes.length > 0) {\n // Find common schemas that appear multiple times (for error responses, etc.)\n const routeSchemaList = collectRouteSchemas(routes);\n const commonSchemas = findCommonSchemas(routeSchemaList, 2);\n\n // Generate common schemas first (e.g., UnauthorizedErrorSchema, NotFoundErrorSchema)\n if (commonSchemas.length > 0) {\n lines.push(\"// Common Error Schemas (deduplicated)\");\n for (const common of commonSchemas) {\n const zodExpr = convertSchemaToZodString(common.schema);\n lines.push(`export const ${common.name} = ${zodExpr};`);\n // Pre-register so route schemas reference this instead of duplicating\n preRegisterSchema(registry, common.name, common.fingerprint);\n }\n lines.push(\"\");\n }\n\n // Generate route schemas with deduplication\n const { declarations, schemaNameToCanonical } = generateRouteSchemas(\n routes,\n convertSchemaToZodString,\n registry,\n );\n\n if (declarations.length > 0) {\n lines.push(\"// Route Schemas\");\n lines.push(...declarations);\n lines.push(\"\");\n\n // Generate Request/Response objects using canonical names\n const requestResponseObjs = generateRequestResponseObjects(\n routes,\n schemaNameToCanonical,\n );\n lines.push(...requestResponseObjs);\n }\n }\n }\n\n return lines.join(\"\\n\");\n};\n"],"mappings":"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","names":["result","validIdentifierRegex","quotePropertyName","toPascalCase","result","validIdentifierRegex","quotePropertyName","generateRouteSchemaName"]}
|
package/package.json
CHANGED
|
@@ -479,7 +479,7 @@ describe("openApiToZodTsCode - optimized .d.ts output", () => {
|
|
|
479
479
|
).toBe(1);
|
|
480
480
|
});
|
|
481
481
|
|
|
482
|
-
it("should generate
|
|
482
|
+
it("should generate schema without explicit type annotation", () => {
|
|
483
483
|
const spec = {
|
|
484
484
|
components: {
|
|
485
485
|
schemas: {
|
|
@@ -493,7 +493,8 @@ describe("openApiToZodTsCode - optimized .d.ts output", () => {
|
|
|
493
493
|
};
|
|
494
494
|
|
|
495
495
|
const code = openApiToZodTsCode(spec);
|
|
496
|
-
expect(code).toContain("export const UserSchema
|
|
496
|
+
expect(code).toContain("export const UserSchema = z.object({");
|
|
497
|
+
expect(code).not.toContain("z.ZodType<User>");
|
|
497
498
|
});
|
|
498
499
|
|
|
499
500
|
it("should generate type assertions", () => {
|
|
@@ -605,9 +606,9 @@ describe(".d.ts output verification", () => {
|
|
|
605
606
|
expect(code).toContain("export interface User {");
|
|
606
607
|
expect(code).toContain("export interface Product {");
|
|
607
608
|
|
|
608
|
-
// 2. Should have
|
|
609
|
-
expect(code).toContain("export const UserSchema
|
|
610
|
-
expect(code).toContain("export const ProductSchema
|
|
609
|
+
// 2. Should have schemas without explicit type annotations (TypeScript infers the type)
|
|
610
|
+
expect(code).toContain("export const UserSchema = z.object({");
|
|
611
|
+
expect(code).toContain("export const ProductSchema = z.object({");
|
|
611
612
|
|
|
612
613
|
// 3. Should NOT have z.infer type aliases (would require resolution in .d.ts)
|
|
613
614
|
expect(code).not.toContain("export type User = z.infer<");
|
package/src/to-typescript.ts
CHANGED
|
@@ -456,7 +456,7 @@ export const openApiToZodTsCode = (
|
|
|
456
456
|
schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));
|
|
457
457
|
|
|
458
458
|
// Generate schema with ZodType<T> annotation (simple type in .d.ts)
|
|
459
|
-
schemaBlocks.push(`export const ${schemaName}
|
|
459
|
+
schemaBlocks.push(`export const ${schemaName} = ${zodExpr};`);
|
|
460
460
|
schemaBlocks.push("");
|
|
461
461
|
|
|
462
462
|
// Add type assertion to verify interface matches schema
|
package/src/to-zod.spec.ts
CHANGED
|
@@ -289,10 +289,9 @@ describe("openApiToZodTsCode", () => {
|
|
|
289
289
|
|
|
290
290
|
const result = openApiToZodTsCode(openapi);
|
|
291
291
|
expect(result).toContain("import { z } from 'zod';");
|
|
292
|
-
// New format: interface +
|
|
292
|
+
// New format: interface + schema without explicit type annotation
|
|
293
293
|
expect(result).toContain("export interface User {");
|
|
294
|
-
expect(result).toContain("export const UserSchema: z.
|
|
295
|
-
expect(result).toContain("z.object({ name: z.string() })");
|
|
294
|
+
expect(result).toContain("export const UserSchema = z.object({ name: z.string() })");
|
|
296
295
|
// Type assertion for compile-time verification
|
|
297
296
|
expect(result).toContain("type _AssertUser = _AssertEqual<User, z.infer<typeof UserSchema>>;");
|
|
298
297
|
});
|
|
@@ -320,11 +319,11 @@ describe("openApiToZodTsCode", () => {
|
|
|
320
319
|
};
|
|
321
320
|
|
|
322
321
|
const result = openApiToZodTsCode(openapi);
|
|
323
|
-
// New format: interface +
|
|
322
|
+
// New format: interface + schema without explicit type annotation
|
|
324
323
|
expect(result).toContain("export interface User {");
|
|
325
324
|
expect(result).toContain("export interface Product {");
|
|
326
|
-
expect(result).toContain("export const UserSchema: z.
|
|
327
|
-
expect(result).toContain("export const ProductSchema: z.
|
|
325
|
+
expect(result).toContain("export const UserSchema = z.object({ name: z.string() })");
|
|
326
|
+
expect(result).toContain("export const ProductSchema = z.object({ id: z.number() })");
|
|
328
327
|
});
|
|
329
328
|
|
|
330
329
|
it("should include file header comment", () => {
|