@contractspec/lib.contracts-transformers 0.0.0-canary-20260113173657 → 0.0.0-canary-20260119222405

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../../../src/openapi/importer/events.ts"],"sourcesContent":["import type { ParsedEvent } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@contractspec/lib.contracts';\n\n/**\n * Generate code for an event.\n */\nexport function generateEventCode(\n event: ParsedEvent,\n options: ContractsrcConfig\n): string {\n const eventName = toValidIdentifier(event.name);\n const modelName = toPascalCase(eventName) + 'Payload';\n\n const schemaFormat = options.schemaFormat || 'contractspec';\n // Generate payload model inline or referenced?\n // Let's generate the payload schema definition first\n const payloadModel = generateSchemaModelCode(\n event.payload,\n modelName,\n schemaFormat,\n options\n );\n\n const imports = new Set<string>();\n imports.add(\n \"import { defineEvent, type EventSpec } from '@contractspec/lib.contracts';\"\n );\n\n if (payloadModel.imports && payloadModel.imports.length > 0) {\n payloadModel.imports.forEach((i) => imports.add(i));\n } else if (payloadModel.fields && payloadModel.fields.length > 0) {\n const modelImports = generateImports(payloadModel.fields, options);\n // Merge imports - this is a bit hacky string manipulation but works for now\n modelImports\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => imports.add(i));\n }\n\n // If payloadModel is a reference (empty fields and different name), import it\n if (payloadModel.name !== modelName) {\n const modelsDir = `../${options.conventions.models}`;\n const kebabName = payloadModel.name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(\n `import { ${payloadModel.name} } from '${modelsDir}/${kebabName}';`\n );\n }\n\n const allImports = Array.from(imports).join('\\n');\n\n return `\n${allImports}\n\n${payloadModel.code}\n\nexport const ${eventName} = defineEvent({\n meta: {\n key: '${event.name}',\n version: '1.0.0',\n description: ${JSON.stringify(event.description ?? '')},\n },\n payload: ${payloadModel.name},\n});\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,OACA,SACQ;CACR,MAAM,YAAY,kBAAkB,MAAM,KAAK;CAC/C,MAAM,YAAY,aAAa,UAAU,GAAG;CAE5C,MAAM,eAAe,QAAQ,gBAAgB;CAG7C,MAAM,eAAe,wBACnB,MAAM,SACN,WACA,cACA,QACD;CAED,MAAM,0BAAU,IAAI,KAAa;AACjC,SAAQ,IACN,6EACD;AAED,KAAI,aAAa,WAAW,aAAa,QAAQ,SAAS,EACxD,cAAa,QAAQ,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;UAC1C,aAAa,UAAU,aAAa,OAAO,SAAS,EAG7D,CAFqB,gBAAgB,aAAa,QAAQ,QAAQ,CAG/D,MAAM,KAAK,CACX,OAAO,QAAQ,CACf,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;AAInC,KAAI,aAAa,SAAS,WAAW;EACnC,MAAM,YAAY,MAAM,QAAQ,YAAY;EAC5C,MAAM,YAAY,aAAa,KAC5B,QAAQ,sBAAsB,QAAQ,CACtC,aAAa;AAChB,UAAQ,IACN,YAAY,aAAa,KAAK,WAAW,UAAU,GAAG,UAAU,IACjE;;AAKH,QAAO;EAFY,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAGtC;;EAEX,aAAa,KAAK;;eAEL,UAAU;;YAEb,MAAM,KAAK;;mBAEJ,KAAK,UAAU,MAAM,eAAe,GAAG,CAAC;;aAE9C,aAAa,KAAK;;EAE7B,MAAM"}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../../src/openapi/importer/events.ts"],"sourcesContent":["import type { ParsedEvent } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ResolvedContractsrcConfig } from '@contractspec/lib.contracts';\n\n/**\n * Generate code for an event.\n */\nexport function generateEventCode(\n event: ParsedEvent,\n options: ResolvedContractsrcConfig\n): string {\n const eventName = toValidIdentifier(event.name);\n const modelName = toPascalCase(eventName) + 'Payload';\n\n const schemaFormat = options.schemaFormat || 'contractspec';\n // Generate payload model inline or referenced?\n // Let's generate the payload schema definition first\n const payloadModel = generateSchemaModelCode(\n event.payload,\n modelName,\n schemaFormat,\n options\n );\n\n const imports = new Set<string>();\n imports.add(\n \"import { defineEvent, type EventSpec } from '@contractspec/lib.contracts';\"\n );\n\n if (payloadModel.imports && payloadModel.imports.length > 0) {\n payloadModel.imports.forEach((i) => imports.add(i));\n } else if (payloadModel.fields && payloadModel.fields.length > 0) {\n const modelImports = generateImports(payloadModel.fields, options);\n // Merge imports - this is a bit hacky string manipulation but works for now\n modelImports\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => imports.add(i));\n }\n\n // If payloadModel is a reference (empty fields and different name), import it\n if (payloadModel.name !== modelName) {\n const modelsDir = `../${options.conventions.models}`;\n const kebabName = payloadModel.name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(\n `import { ${payloadModel.name} } from '${modelsDir}/${kebabName}';`\n );\n }\n\n const allImports = Array.from(imports).join('\\n');\n\n return `\n${allImports}\n\n${payloadModel.code}\n\nexport const ${eventName} = defineEvent({\n meta: {\n key: '${event.name}',\n version: '1.0.0',\n description: ${JSON.stringify(event.description ?? '')},\n },\n payload: ${payloadModel.name},\n});\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,OACA,SACQ;CACR,MAAM,YAAY,kBAAkB,MAAM,KAAK;CAC/C,MAAM,YAAY,aAAa,UAAU,GAAG;CAE5C,MAAM,eAAe,QAAQ,gBAAgB;CAG7C,MAAM,eAAe,wBACnB,MAAM,SACN,WACA,cACA,QACD;CAED,MAAM,0BAAU,IAAI,KAAa;AACjC,SAAQ,IACN,6EACD;AAED,KAAI,aAAa,WAAW,aAAa,QAAQ,SAAS,EACxD,cAAa,QAAQ,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;UAC1C,aAAa,UAAU,aAAa,OAAO,SAAS,EAG7D,CAFqB,gBAAgB,aAAa,QAAQ,QAAQ,CAG/D,MAAM,KAAK,CACX,OAAO,QAAQ,CACf,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;AAInC,KAAI,aAAa,SAAS,WAAW;EACnC,MAAM,YAAY,MAAM,QAAQ,YAAY;EAC5C,MAAM,YAAY,aAAa,KAC5B,QAAQ,sBAAsB,QAAQ,CACtC,aAAa;AAChB,UAAQ,IACN,YAAY,aAAa,KAAK,WAAW,UAAU,GAAG,UAAU,IACjE;;AAKH,QAAO;EAFY,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAGtC;;EAEX,aAAa,KAAK;;eAEL,UAAU;;YAEb,MAAM,KAAK;;mBAEJ,KAAK,UAAU,MAAM,eAAe,GAAG,CAAC;;aAE9C,aAAa,KAAK;;EAE7B,MAAM"}
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","names":[],"sources":["../../../src/openapi/importer/generator.ts"],"sourcesContent":["import type { ParsedOperation } from '../types';\nimport { toPascalCase, toSpecKey, toValidIdentifier } from '../../common/utils';\nimport { type GeneratedModel, generateImports } from '../schema-converter';\nimport { inferAuthLevel, inferOpKind } from './analyzer';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@contractspec/lib.contracts';\n\n/**\n * Generate ContractSpec TypeScript code for an operation.\n */\nexport function generateSpecCode(\n operation: ParsedOperation,\n contractspecConfig: ContractsrcConfig,\n options: Partial<OpenApiSourceConfig> = {},\n inputModel: GeneratedModel | null,\n outputModel: GeneratedModel | null,\n queryModel: GeneratedModel | null = null,\n paramsModel: GeneratedModel | null = null,\n headersModel: GeneratedModel | null = null\n): string {\n const specKey = toSpecKey(operation.operationId, options.prefix);\n const kind = inferOpKind(operation.method);\n const auth = inferAuthLevel(operation, options.defaultAuth ?? 'user');\n\n const lines: string[] = [];\n\n // Imports\n lines.push(\n \"import { defineCommand, defineQuery } from '@contractspec/lib.contracts';\"\n );\n if (inputModel || outputModel || queryModel || paramsModel || headersModel) {\n const collectedImports = new Set<string>();\n const models = [\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel,\n ].filter((m): m is GeneratedModel => !!m);\n\n // Add explicit imports from generators (e.g. Zod, JsonSchema)\n models.forEach((m) => {\n if (m.imports && m.imports.length > 0) {\n m.imports.forEach((i) => collectedImports.add(i));\n }\n });\n\n // Add legacy fields-based imports (ContractSpec format)\n const legacyModels = models.filter(\n (m) => !m.imports || m.imports.length === 0\n );\n const legacyFields = legacyModels.flatMap((m) => m.fields);\n\n if (legacyFields.length > 0) {\n const legacyImportStr = generateImports(\n legacyFields,\n contractspecConfig,\n false\n );\n legacyImportStr\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => collectedImports.add(i));\n }\n\n if (collectedImports.size > 0) {\n lines.push(Array.from(collectedImports).sort().join('\\n'));\n }\n }\n lines.push('');\n\n // Generate schemas\n const schemaSections = [\n { label: 'Input schema', model: inputModel },\n { label: 'Query schema', model: queryModel },\n { label: 'Path schema', model: paramsModel },\n { label: 'Header schema', model: headersModel },\n { label: 'Output schema', model: outputModel },\n ];\n\n for (const section of schemaSections) {\n if (section.model && section.model.code) {\n lines.push(`// ${section.label}`);\n lines.push(section.model.code);\n lines.push('');\n }\n }\n\n // Generate spec\n const defineFunc = kind === 'command' ? 'defineCommand' : 'defineQuery';\n const safeName = toValidIdentifier(toPascalCase(operation.operationId));\n\n lines.push(`/**`);\n lines.push(` * ${operation.summary ?? operation.operationId}`);\n if (operation.description) {\n lines.push(` *`);\n lines.push(` * ${operation.description}`);\n }\n lines.push(` *`);\n lines.push(\n ` * @source OpenAPI: ${operation.method.toUpperCase()} ${operation.path}`\n );\n lines.push(` */`);\n lines.push(`export const ${safeName}Spec = ${defineFunc}({`);\n\n // Meta\n lines.push(' meta: {');\n lines.push(` key: '${specKey}',`);\n lines.push(\" version: '1.0.0',\");\n lines.push(` stability: '${options.defaultStability ?? 'stable'}',`);\n lines.push(\n ` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(', ')}],`\n );\n lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(', ')}],`);\n lines.push(\n ` description: ${JSON.stringify(operation.summary ?? operation.operationId)},`\n );\n lines.push(\n ` goal: ${JSON.stringify(operation.description ?? 'Imported from OpenAPI')},`\n );\n lines.push(\n ` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`\n );\n lines.push(' },');\n\n // IO\n lines.push(' io: {');\n lines.push(` input: ${inputModel?.name ?? 'null'},`);\n if (queryModel) lines.push(` query: ${queryModel.name},`);\n if (paramsModel) lines.push(` params: ${paramsModel.name},`);\n if (headersModel) lines.push(` headers: ${headersModel.name},`);\n\n if (outputModel) {\n lines.push(` output: ${outputModel.name},`);\n } else {\n lines.push(' output: null, // TODO: Define output schema');\n }\n lines.push(' },');\n\n // Policy\n lines.push(' policy: {');\n lines.push(` auth: '${auth}',`);\n lines.push(' },');\n\n // Transport hints\n const httpMethod = operation.method.toUpperCase();\n const restMethod = httpMethod === 'GET' ? 'GET' : 'POST';\n lines.push(' transport: {');\n lines.push(' rest: {');\n lines.push(` method: '${restMethod}',`);\n lines.push(` path: '${operation.path}',`);\n lines.push(' },');\n lines.push(' },');\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","names":[],"sources":["../../../src/openapi/importer/generator.ts"],"sourcesContent":["import type { ParsedOperation } from '../types';\nimport { toPascalCase, toSpecKey, toValidIdentifier } from '../../common/utils';\nimport { type GeneratedModel, generateImports } from '../schema-converter';\nimport { inferAuthLevel, inferOpKind } from './analyzer';\nimport type {\n ResolvedContractsrcConfig,\n OpenApiSourceConfig,\n} from '@contractspec/lib.contracts';\n\n/**\n * Generate ContractSpec TypeScript code for an operation.\n */\nexport function generateSpecCode(\n operation: ParsedOperation,\n contractspecConfig: ResolvedContractsrcConfig,\n options: Partial<OpenApiSourceConfig> = {},\n inputModel: GeneratedModel | null,\n outputModel: GeneratedModel | null,\n queryModel: GeneratedModel | null = null,\n paramsModel: GeneratedModel | null = null,\n headersModel: GeneratedModel | null = null\n): string {\n const specKey = toSpecKey(operation.operationId, options.prefix);\n const kind = inferOpKind(operation.method);\n const auth = inferAuthLevel(operation, options.defaultAuth ?? 'user');\n\n const lines: string[] = [];\n\n // Imports\n lines.push(\n \"import { defineCommand, defineQuery } from '@contractspec/lib.contracts';\"\n );\n if (inputModel || outputModel || queryModel || paramsModel || headersModel) {\n const collectedImports = new Set<string>();\n const models = [\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel,\n ].filter((m): m is GeneratedModel => !!m);\n\n // Add explicit imports from generators (e.g. Zod, JsonSchema)\n models.forEach((m) => {\n if (m.imports && m.imports.length > 0) {\n m.imports.forEach((i) => collectedImports.add(i));\n }\n });\n\n // Add legacy fields-based imports (ContractSpec format)\n const legacyModels = models.filter(\n (m) => !m.imports || m.imports.length === 0\n );\n const legacyFields = legacyModels.flatMap((m) => m.fields);\n\n if (legacyFields.length > 0) {\n const legacyImportStr = generateImports(\n legacyFields,\n contractspecConfig,\n false\n );\n legacyImportStr\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => collectedImports.add(i));\n }\n\n if (collectedImports.size > 0) {\n lines.push(Array.from(collectedImports).sort().join('\\n'));\n }\n }\n lines.push('');\n\n // Generate schemas\n const schemaSections = [\n { label: 'Input schema', model: inputModel },\n { label: 'Query schema', model: queryModel },\n { label: 'Path schema', model: paramsModel },\n { label: 'Header schema', model: headersModel },\n { label: 'Output schema', model: outputModel },\n ];\n\n for (const section of schemaSections) {\n if (section.model && section.model.code) {\n lines.push(`// ${section.label}`);\n lines.push(section.model.code);\n lines.push('');\n }\n }\n\n // Generate spec\n const defineFunc = kind === 'command' ? 'defineCommand' : 'defineQuery';\n const safeName = toValidIdentifier(toPascalCase(operation.operationId));\n\n lines.push(`/**`);\n lines.push(` * ${operation.summary ?? operation.operationId}`);\n if (operation.description) {\n lines.push(` *`);\n lines.push(` * ${operation.description}`);\n }\n lines.push(` *`);\n lines.push(\n ` * @source OpenAPI: ${operation.method.toUpperCase()} ${operation.path}`\n );\n lines.push(` */`);\n lines.push(`export const ${safeName}Spec = ${defineFunc}({`);\n\n // Meta\n lines.push(' meta: {');\n lines.push(` key: '${specKey}',`);\n lines.push(\" version: '1.0.0',\");\n lines.push(` stability: '${options.defaultStability ?? 'stable'}',`);\n lines.push(\n ` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(', ')}],`\n );\n lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(', ')}],`);\n lines.push(\n ` description: ${JSON.stringify(operation.summary ?? operation.operationId)},`\n );\n lines.push(\n ` goal: ${JSON.stringify(operation.description ?? 'Imported from OpenAPI')},`\n );\n lines.push(\n ` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`\n );\n lines.push(' },');\n\n // IO\n lines.push(' io: {');\n lines.push(` input: ${inputModel?.name ?? 'null'},`);\n if (queryModel) lines.push(` query: ${queryModel.name},`);\n if (paramsModel) lines.push(` params: ${paramsModel.name},`);\n if (headersModel) lines.push(` headers: ${headersModel.name},`);\n\n if (outputModel) {\n lines.push(` output: ${outputModel.name},`);\n } else {\n lines.push(' output: null, // TODO: Define output schema');\n }\n lines.push(' },');\n\n // Policy\n lines.push(' policy: {');\n lines.push(` auth: '${auth}',`);\n lines.push(' },');\n\n // Transport hints\n const httpMethod = operation.method.toUpperCase();\n const restMethod = httpMethod === 'GET' ? 'GET' : 'POST';\n lines.push(' transport: {');\n lines.push(' rest: {');\n lines.push(` method: '${restMethod}',`);\n lines.push(` path: '${operation.path}',`);\n lines.push(' },');\n lines.push(' },');\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"grouping.js","names":[],"sources":["../../../src/openapi/importer/grouping.ts"],"sourcesContent":["/**\n * Grouping utilities for OpenAPI import/export.\n * Determines output folder structure based on configuration.\n */\nimport type { FolderConventions } from '@contractspec/lib.contracts';\nimport type { ParsedOperation } from '../types';\n\n/**\n * Grouping strategy type (matches ContractSpec config).\n */\ntype GroupingStrategy =\n | 'by-tag'\n | 'by-owner'\n | 'by-domain'\n | 'by-url-path-single'\n | 'by-url-path-multi'\n | 'by-feature'\n | 'none';\n\n/**\n * Grouping rule configuration.\n */\ninterface GroupingRule {\n strategy: GroupingStrategy;\n urlPathLevel?: number;\n pattern?: string;\n}\n\n/**\n * Resolve the group folder for an operation based on grouping config.\n */\nexport function resolveOperationGroupFolder(\n operation: ParsedOperation,\n conventions: FolderConventions\n): string {\n const groupingRule = conventions.operationsGrouping as\n | GroupingRule\n | undefined;\n\n if (!groupingRule || groupingRule.strategy === 'none') {\n return '';\n }\n\n return applyGroupingStrategy(groupingRule, {\n name: operation.operationId,\n tags: operation.tags,\n path: operation.path,\n });\n}\n\n/**\n * Resolve the group folder for a model based on grouping config.\n */\nexport function resolveModelGroupFolder(\n modelName: string,\n conventions: FolderConventions,\n relatedPath?: string,\n relatedTags?: string[]\n): string {\n const groupingRule = conventions.modelsGrouping as GroupingRule | undefined;\n\n if (!groupingRule || groupingRule.strategy === 'none') {\n return '';\n }\n\n return applyGroupingStrategy(groupingRule, {\n name: modelName,\n tags: relatedTags ?? [],\n path: relatedPath,\n });\n}\n\n/**\n * Resolve the group folder for an event based on grouping config.\n */\nexport function resolveEventGroupFolder(\n eventName: string,\n conventions: FolderConventions,\n relatedTags?: string[]\n): string {\n const groupingRule = conventions.eventsGrouping as GroupingRule | undefined;\n\n if (!groupingRule || groupingRule.strategy === 'none') {\n return '';\n }\n\n return applyGroupingStrategy(groupingRule, {\n name: eventName,\n tags: relatedTags ?? [],\n });\n}\n\n/**\n * Apply grouping strategy to extract folder name.\n */\nfunction applyGroupingStrategy(\n rule: GroupingRule,\n context: {\n name: string;\n tags?: string[];\n path?: string;\n owners?: string[];\n }\n): string {\n switch (rule.strategy) {\n case 'by-tag':\n return context.tags?.[0] ?? 'untagged';\n\n case 'by-owner':\n return context.owners?.[0] ?? 'unowned';\n\n case 'by-domain':\n return extractDomain(context.name);\n\n case 'by-url-path-single':\n return extractUrlPathLevel(context.path, 1);\n\n case 'by-url-path-multi':\n return extractUrlPathLevel(context.path, rule.urlPathLevel ?? 2);\n\n case 'by-feature':\n // Use domain extraction for feature grouping\n return extractDomain(context.name);\n\n case 'none':\n default:\n return '';\n }\n}\n\n/**\n * Extract domain from operation/model name.\n * e.g., \"users.create\" -> \"users\"\n */\nfunction extractDomain(name: string): string {\n // Handle camelCase/PascalCase names\n if (name.includes('.')) {\n return name.split('.')[0] ?? 'default';\n }\n if (name.includes('_')) {\n return name.split('_')[0] ?? 'default';\n }\n // Extract from camelCase like \"createUser\" -> \"create\"\n const match = name.match(/^([a-z]+)/i);\n return match?.[1]?.toLowerCase() ?? 'default';\n}\n\n/**\n * Extract URL path segments for grouping.\n */\nfunction extractUrlPathLevel(path: string | undefined, level: number): string {\n if (!path) return 'root';\n const segments = path.split('/').filter(Boolean);\n\n // Filter out path parameters like {id}\n const nonParamSegments = segments.filter((s) => !s.startsWith('{'));\n\n if (nonParamSegments.length === 0) return 'root';\n\n return nonParamSegments.slice(0, level).join('/');\n}\n\n/**\n * Build full output path including group folder.\n */\nexport function buildOutputPath(\n baseDir: string,\n surfaceDir: string,\n groupFolder: string,\n fileName: string\n): string {\n const parts = [baseDir, surfaceDir];\n\n if (groupFolder) {\n parts.push(groupFolder);\n }\n\n parts.push(fileName);\n\n return parts.filter(Boolean).join('/');\n}\n\n/**\n * Determine if feature-based grouping should be applied.\n */\nexport function shouldGroupByFeature(conventions: FolderConventions): boolean {\n return conventions.groupByFeature;\n}\n"],"mappings":";;;;AA+BA,SAAgB,4BACd,WACA,aACQ;CACR,MAAM,eAAe,YAAY;AAIjC,KAAI,CAAC,gBAAgB,aAAa,aAAa,OAC7C,QAAO;AAGT,QAAO,sBAAsB,cAAc;EACzC,MAAM,UAAU;EAChB,MAAM,UAAU;EAChB,MAAM,UAAU;EACjB,CAAC;;;;;AAMJ,SAAgB,wBACd,WACA,aACA,aACA,aACQ;CACR,MAAM,eAAe,YAAY;AAEjC,KAAI,CAAC,gBAAgB,aAAa,aAAa,OAC7C,QAAO;AAGT,QAAO,sBAAsB,cAAc;EACzC,MAAM;EACN,MAAM,eAAe,EAAE;EACvB,MAAM;EACP,CAAC;;;;;AAMJ,SAAgB,wBACd,WACA,aACA,aACQ;CACR,MAAM,eAAe,YAAY;AAEjC,KAAI,CAAC,gBAAgB,aAAa,aAAa,OAC7C,QAAO;AAGT,QAAO,sBAAsB,cAAc;EACzC,MAAM;EACN,MAAM,eAAe,EAAE;EACxB,CAAC;;;;;AAMJ,SAAS,sBACP,MACA,SAMQ;AACR,SAAQ,KAAK,UAAb;EACE,KAAK,SACH,QAAO,QAAQ,OAAO,MAAM;EAE9B,KAAK,WACH,QAAO,QAAQ,SAAS,MAAM;EAEhC,KAAK,YACH,QAAO,cAAc,QAAQ,KAAK;EAEpC,KAAK,qBACH,QAAO,oBAAoB,QAAQ,MAAM,EAAE;EAE7C,KAAK,oBACH,QAAO,oBAAoB,QAAQ,MAAM,KAAK,gBAAgB,EAAE;EAElE,KAAK,aAEH,QAAO,cAAc,QAAQ,KAAK;EAEpC,KAAK;EACL,QACE,QAAO;;;;;;;AAQb,SAAS,cAAc,MAAsB;AAE3C,KAAI,KAAK,SAAS,IAAI,CACpB,QAAO,KAAK,MAAM,IAAI,CAAC,MAAM;AAE/B,KAAI,KAAK,SAAS,IAAI,CACpB,QAAO,KAAK,MAAM,IAAI,CAAC,MAAM;AAI/B,QADc,KAAK,MAAM,aAAa,GACvB,IAAI,aAAa,IAAI;;;;;AAMtC,SAAS,oBAAoB,MAA0B,OAAuB;AAC5E,KAAI,CAAC,KAAM,QAAO;CAIlB,MAAM,mBAHW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAGd,QAAQ,MAAM,CAAC,EAAE,WAAW,IAAI,CAAC;AAEnE,KAAI,iBAAiB,WAAW,EAAG,QAAO;AAE1C,QAAO,iBAAiB,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI"}
1
+ {"version":3,"file":"grouping.js","names":[],"sources":["../../../src/openapi/importer/grouping.ts"],"sourcesContent":["/**\n * Grouping utilities for OpenAPI import/export.\n * Determines output folder structure based on configuration.\n */\nimport type { FolderConventions } from '@contractspec/lib.contracts';\nimport type { ParsedOperation } from '../types';\n\n/**\n * Grouping strategy type (matches ContractSpec config).\n */\ntype GroupingStrategy =\n | 'by-tag'\n | 'by-owner'\n | 'by-domain'\n | 'by-url-path-single'\n | 'by-url-path-multi'\n | 'by-feature'\n | 'none';\n\n/**\n * Grouping rule configuration.\n */\ninterface GroupingRule {\n strategy: GroupingStrategy;\n urlPathLevel?: number;\n pattern?: string;\n}\n\n/**\n * Resolve the group folder for an operation based on grouping config.\n */\nexport function resolveOperationGroupFolder(\n operation: ParsedOperation,\n conventions: FolderConventions\n): string {\n const groupingRule = conventions.operationsGrouping as\n | GroupingRule\n | undefined;\n\n if (!groupingRule || groupingRule.strategy === 'none') {\n return '';\n }\n\n return applyGroupingStrategy(groupingRule, {\n name: operation.operationId,\n tags: operation.tags,\n path: operation.path,\n });\n}\n\n/**\n * Resolve the group folder for a model based on grouping config.\n */\nexport function resolveModelGroupFolder(\n modelName: string,\n conventions: FolderConventions,\n relatedPath?: string,\n relatedTags?: string[]\n): string {\n const groupingRule = conventions.modelsGrouping as GroupingRule | undefined;\n\n if (!groupingRule || groupingRule.strategy === 'none') {\n return '';\n }\n\n return applyGroupingStrategy(groupingRule, {\n name: modelName,\n tags: relatedTags ?? [],\n path: relatedPath,\n });\n}\n\n/**\n * Resolve the group folder for an event based on grouping config.\n */\nexport function resolveEventGroupFolder(\n eventName: string,\n conventions: FolderConventions,\n relatedTags?: string[]\n): string {\n const groupingRule = conventions.eventsGrouping as GroupingRule | undefined;\n\n if (!groupingRule || groupingRule.strategy === 'none') {\n return '';\n }\n\n return applyGroupingStrategy(groupingRule, {\n name: eventName,\n tags: relatedTags ?? [],\n });\n}\n\n/**\n * Apply grouping strategy to extract folder name.\n */\nfunction applyGroupingStrategy(\n rule: GroupingRule,\n context: {\n name: string;\n tags?: string[];\n path?: string;\n owners?: string[];\n }\n): string {\n switch (rule.strategy) {\n case 'by-tag':\n return context.tags?.[0] ?? 'untagged';\n\n case 'by-owner':\n return context.owners?.[0] ?? 'unowned';\n\n case 'by-domain':\n return extractDomain(context.name);\n\n case 'by-url-path-single':\n return extractUrlPathLevel(context.path, 1);\n\n case 'by-url-path-multi':\n return extractUrlPathLevel(context.path, rule.urlPathLevel ?? 2);\n\n case 'by-feature':\n // Use domain extraction for feature grouping\n return extractDomain(context.name);\n\n case 'none':\n default:\n return '';\n }\n}\n\n/**\n * Extract domain from operation/model name.\n * e.g., \"users.create\" -> \"users\"\n */\nfunction extractDomain(name: string): string {\n // Handle camelCase/PascalCase names\n if (name.includes('.')) {\n return name.split('.')[0] ?? 'default';\n }\n if (name.includes('_')) {\n return name.split('_')[0] ?? 'default';\n }\n // Extract from camelCase like \"createUser\" -> \"create\"\n const match = name.match(/^([a-z]+)/i);\n return match?.[1]?.toLowerCase() ?? 'default';\n}\n\n/**\n * Extract URL path segments for grouping.\n */\nfunction extractUrlPathLevel(path: string | undefined, level: number): string {\n if (!path) return 'root';\n const segments = path.split('/').filter(Boolean);\n\n // Filter out path parameters like {id}\n const nonParamSegments = segments.filter((s) => !s.startsWith('{'));\n\n if (nonParamSegments.length === 0) return 'root';\n\n return nonParamSegments.slice(0, level).join('/');\n}\n\n/**\n * Build full output path including group folder.\n */\nexport function buildOutputPath(\n baseDir: string,\n surfaceDir: string,\n groupFolder: string,\n fileName: string\n): string {\n const parts = [baseDir, surfaceDir];\n\n if (groupFolder) {\n parts.push(groupFolder);\n }\n\n parts.push(fileName);\n\n return parts.filter(Boolean).join('/');\n}\n\n/**\n * Determine if feature-based grouping should be applied.\n */\nexport function shouldGroupByFeature(conventions: FolderConventions): boolean {\n return conventions.groupByFeature ?? false;\n}\n"],"mappings":";;;;AA+BA,SAAgB,4BACd,WACA,aACQ;CACR,MAAM,eAAe,YAAY;AAIjC,KAAI,CAAC,gBAAgB,aAAa,aAAa,OAC7C,QAAO;AAGT,QAAO,sBAAsB,cAAc;EACzC,MAAM,UAAU;EAChB,MAAM,UAAU;EAChB,MAAM,UAAU;EACjB,CAAC;;;;;AAMJ,SAAgB,wBACd,WACA,aACA,aACA,aACQ;CACR,MAAM,eAAe,YAAY;AAEjC,KAAI,CAAC,gBAAgB,aAAa,aAAa,OAC7C,QAAO;AAGT,QAAO,sBAAsB,cAAc;EACzC,MAAM;EACN,MAAM,eAAe,EAAE;EACvB,MAAM;EACP,CAAC;;;;;AAMJ,SAAgB,wBACd,WACA,aACA,aACQ;CACR,MAAM,eAAe,YAAY;AAEjC,KAAI,CAAC,gBAAgB,aAAa,aAAa,OAC7C,QAAO;AAGT,QAAO,sBAAsB,cAAc;EACzC,MAAM;EACN,MAAM,eAAe,EAAE;EACxB,CAAC;;;;;AAMJ,SAAS,sBACP,MACA,SAMQ;AACR,SAAQ,KAAK,UAAb;EACE,KAAK,SACH,QAAO,QAAQ,OAAO,MAAM;EAE9B,KAAK,WACH,QAAO,QAAQ,SAAS,MAAM;EAEhC,KAAK,YACH,QAAO,cAAc,QAAQ,KAAK;EAEpC,KAAK,qBACH,QAAO,oBAAoB,QAAQ,MAAM,EAAE;EAE7C,KAAK,oBACH,QAAO,oBAAoB,QAAQ,MAAM,KAAK,gBAAgB,EAAE;EAElE,KAAK,aAEH,QAAO,cAAc,QAAQ,KAAK;EAEpC,KAAK;EACL,QACE,QAAO;;;;;;;AAQb,SAAS,cAAc,MAAsB;AAE3C,KAAI,KAAK,SAAS,IAAI,CACpB,QAAO,KAAK,MAAM,IAAI,CAAC,MAAM;AAE/B,KAAI,KAAK,SAAS,IAAI,CACpB,QAAO,KAAK,MAAM,IAAI,CAAC,MAAM;AAI/B,QADc,KAAK,MAAM,aAAa,GACvB,IAAI,aAAa,IAAI;;;;;AAMtC,SAAS,oBAAoB,MAA0B,OAAuB;AAC5E,KAAI,CAAC,KAAM,QAAO;CAIlB,MAAM,mBAHW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAGd,QAAQ,MAAM,CAAC,EAAE,WAAW,IAAI,CAAC;AAEnE,KAAI,iBAAiB,WAAW,EAAG,QAAO;AAE1C,QAAO,iBAAiB,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI"}
@@ -1,17 +1,17 @@
1
1
  import { ImportResult } from "../../common/types.js";
2
2
  import { ParseResult, ParsedOperation } from "../types.js";
3
- import { ContractsrcConfig, OpenApiSourceConfig } from "@contractspec/lib.contracts";
3
+ import { OpenApiSourceConfig, ResolvedContractsrcConfig } from "@contractspec/lib.contracts";
4
4
 
5
5
  //#region src/openapi/importer/index.d.ts
6
6
 
7
7
  /**
8
8
  * Import operations from a parsed OpenAPI document.
9
9
  */
10
- declare const importFromOpenApi: (parseResult: ParseResult, contractspecOptions: ContractsrcConfig, importOptions?: Partial<OpenApiSourceConfig>) => ImportResult;
10
+ declare const importFromOpenApi: (parseResult: ParseResult, contractspecOptions: ResolvedContractsrcConfig, importOptions?: Partial<OpenApiSourceConfig>) => ImportResult;
11
11
  /**
12
12
  * Import a single operation to ContractSpec code.
13
13
  */
14
- declare function importOperation(operation: ParsedOperation, options: Partial<OpenApiSourceConfig> | undefined, contractspecOptions: ContractsrcConfig): string;
14
+ declare function importOperation(operation: ParsedOperation, options: Partial<OpenApiSourceConfig> | undefined, contractspecOptions: ResolvedContractsrcConfig): string;
15
15
  //#endregion
16
16
  export { importFromOpenApi, importOperation };
17
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgTgB,cA/QH,iBA+QkB,EAAA,CAAA,WAAA,EA9QhB,WA8QgB,EAAA,mBAAA,EA7QR,iBA6QQ,EAAA,aAAA,CAAA,EA5Qd,OA4Qc,CA5QN,mBA4QM,CAAA,EAAA,GA3Q5B,YA2Q4B;;;;AAGR,iBAHP,eAAA,CAGO,SAAA,EAFV,eAEU,EAAA,OAAA,EADZ,OACY,CADJ,mBACI,CAAA,GAAA,SAAA,EAAA,mBAAA,EAAA,iBAAA,CAAA,EAAA,MAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgTgB,cA/QH,iBA+QkB,EAAA,CAAA,WAAA,EA9QhB,WA8QgB,EAAA,mBAAA,EA7QR,yBA6QQ,EAAA,aAAA,CAAA,EA5Qd,OA4Qc,CA5QN,mBA4QM,CAAA,EAAA,GA3Q5B,YA2Q4B;;;;AAGR,iBAHP,eAAA,CAGO,SAAA,EAFV,eAEU,EAAA,OAAA,EADZ,OACY,CADJ,mBACI,CAAA,GAAA,SAAA,EAAA,mBAAA,EAAA,yBAAA,CAAA,EAAA,MAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":["import type {\n OpenApiSource,\n OpenApiTransportHints,\n ParsedOperation,\n ParseResult,\n} from '../types';\nimport type { ImportedOperationSpec, ImportResult } from '../../common/types';\nimport { toFileName, toSpecKey } from '../../common/utils';\nimport { generateSchemaModelCode } from '../schema-converter';\nimport { buildInputSchemas, getOutputSchema } from './schemas';\nimport { generateSpecCode } from './generator';\nimport { generateModelCode } from './models';\nimport { generateEventCode } from './events';\nimport {\n resolveEventGroupFolder,\n resolveModelGroupFolder,\n resolveOperationGroupFolder,\n} from './grouping';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@contractspec/lib.contracts';\n\nexport * from './analyzer';\nexport * from './schemas';\nexport * from './generator';\nexport * from './models';\nexport * from './events';\nexport * from './grouping';\n\n/**\n * Import operations from a parsed OpenAPI document.\n */\nexport const importFromOpenApi = (\n parseResult: ParseResult,\n contractspecOptions: ContractsrcConfig,\n importOptions: Partial<OpenApiSourceConfig> = {}\n): ImportResult => {\n const { tags, exclude = [], include } = importOptions;\n const specs: ImportedOperationSpec[] = [];\n const skipped: ImportResult['skipped'] = [];\n const errors: ImportResult['errors'] = [];\n\n for (const operation of parseResult.operations) {\n // Filter by tags if specified\n if (tags && tags.length > 0) {\n const hasMatchingTag = operation.tags.some((t) => tags.includes(t));\n if (!hasMatchingTag) {\n skipped.push({\n sourceId: operation.operationId,\n reason: `No matching tags (has: ${operation.tags.join(', ')})`,\n });\n continue;\n }\n }\n\n // Filter by include/exclude\n if (include && include.length > 0) {\n if (!include.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Not in include list',\n });\n continue;\n }\n } else if (exclude.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'In exclude list',\n });\n continue;\n }\n\n // Skip deprecated operations by default\n if (\n operation.deprecated &&\n importOptions.defaultStability !== 'deprecated'\n ) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Deprecated operation',\n });\n continue;\n }\n\n try {\n // Build input schemas\n const inputSchemas = buildInputSchemas(operation);\n const schemaFormat =\n importOptions.schemaFormat ||\n contractspecOptions.schemaFormat ||\n 'contractspec';\n\n // Generate models for each input source\n const inputModel = inputSchemas.body\n ? generateSchemaModelCode(\n inputSchemas.body,\n `${operation.operationId}Input`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const queryModel = inputSchemas.query\n ? generateSchemaModelCode(\n inputSchemas.query,\n `${operation.operationId}Query`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const paramsModel = inputSchemas.params\n ? generateSchemaModelCode(\n inputSchemas.params,\n `${operation.operationId}Params`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const headersModel = inputSchemas.headers\n ? generateSchemaModelCode(\n inputSchemas.headers,\n `${operation.operationId}Headers`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n // Get output schema\n const outputSchema = getOutputSchema(operation);\n let outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n // Filter out empty/comment-only output models ONLY for ContractSpec format\n if (\n outputModel &&\n schemaFormat === 'contractspec' &&\n !outputModel.code.includes('defineSchemaModel')\n ) {\n outputModel = null;\n }\n\n // Generate spec code\n const code = generateSpecCode(\n operation,\n contractspecOptions,\n importOptions,\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel\n );\n const specName = toSpecKey(operation.operationId, importOptions.prefix);\n const fileName = toFileName(specName);\n\n // Build transport hints\n const transportHints: OpenApiTransportHints = {\n rest: {\n method:\n operation.method.toUpperCase() as OpenApiTransportHints['rest']['method'],\n path: operation.path,\n params: {\n path: operation.pathParams.map((p) => p.name),\n query: operation.queryParams.map((p) => p.name),\n header: operation.headerParams.map((p) => p.name),\n cookie: operation.cookieParams.map((p) => p.name),\n },\n },\n };\n\n // Build source info\n const source: OpenApiSource = {\n type: 'openapi',\n sourceId: operation.operationId,\n operationId: operation.operationId,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n };\n\n // Resolve group folder based on config\n const groupFolder = resolveOperationGroupFolder(\n operation,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source,\n transportHints,\n });\n } catch (error) {\n errors.push({\n sourceId: operation.operationId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Import standalone models\n for (const [name, schema] of Object.entries(parseResult.schemas)) {\n try {\n const code = generateModelCode(name, schema, {\n ...contractspecOptions,\n schemaFormat:\n importOptions.schemaFormat || contractspecOptions.schemaFormat,\n });\n const fileName = toFileName(toSpecKey(name, importOptions.prefix));\n const groupFolder = resolveModelGroupFolder(\n name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: name,\n operationId: name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: name,\n error:\n error instanceof Error\n ? 'Model conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n // Import events\n for (const event of parseResult.events) {\n try {\n const code = generateEventCode(event, {\n ...contractspecOptions,\n schemaFormat:\n importOptions.schemaFormat || contractspecOptions.schemaFormat,\n });\n const fileName = toFileName(toSpecKey(event.name, importOptions.prefix));\n const groupFolder = resolveEventGroupFolder(\n event.name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: event.name,\n operationId: event.name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: event.name,\n error:\n error instanceof Error\n ? 'Event conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n return {\n operationSpecs: specs,\n skipped,\n errors,\n summary: {\n total:\n parseResult.operations.length +\n Object.keys(parseResult.schemas).length +\n parseResult.events.length,\n imported: specs.length,\n skipped: skipped.length,\n errors: errors.length,\n },\n };\n};\n\n/**\n * Import a single operation to ContractSpec code.\n */\nexport function importOperation(\n operation: ParsedOperation,\n options: Partial<OpenApiSourceConfig> = {},\n contractspecOptions: ContractsrcConfig\n): string {\n // Build input schemas\n const inputSchemas = buildInputSchemas(operation);\n const schemaFormat =\n options.schemaFormat || contractspecOptions.schemaFormat || 'contractspec';\n\n // Generate models for each input source\n const inputModel = inputSchemas.body\n ? generateSchemaModelCode(\n inputSchemas.body,\n `${operation.operationId}Input`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const queryModel = inputSchemas.query\n ? generateSchemaModelCode(\n inputSchemas.query,\n `${operation.operationId}Query`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const paramsModel = inputSchemas.params\n ? generateSchemaModelCode(\n inputSchemas.params,\n `${operation.operationId}Params`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const headersModel = inputSchemas.headers\n ? generateSchemaModelCode(\n inputSchemas.headers,\n `${operation.operationId}Headers`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const outputSchema = getOutputSchema(operation);\n const outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n return generateSpecCode(\n operation,\n contractspecOptions,\n options,\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":["import type {\n OpenApiSource,\n OpenApiTransportHints,\n ParsedOperation,\n ParseResult,\n} from '../types';\nimport type { ImportedOperationSpec, ImportResult } from '../../common/types';\nimport { toFileName, toSpecKey } from '../../common/utils';\nimport { generateSchemaModelCode } from '../schema-converter';\nimport { buildInputSchemas, getOutputSchema } from './schemas';\nimport { generateSpecCode } from './generator';\nimport { generateModelCode } from './models';\nimport { generateEventCode } from './events';\nimport {\n resolveEventGroupFolder,\n resolveModelGroupFolder,\n resolveOperationGroupFolder,\n} from './grouping';\nimport type {\n ResolvedContractsrcConfig,\n OpenApiSourceConfig,\n} from '@contractspec/lib.contracts';\n\nexport * from './analyzer';\nexport * from './schemas';\nexport * from './generator';\nexport * from './models';\nexport * from './events';\nexport * from './grouping';\n\n/**\n * Import operations from a parsed OpenAPI document.\n */\nexport const importFromOpenApi = (\n parseResult: ParseResult,\n contractspecOptions: ResolvedContractsrcConfig,\n importOptions: Partial<OpenApiSourceConfig> = {}\n): ImportResult => {\n const { tags, exclude = [], include } = importOptions;\n const specs: ImportedOperationSpec[] = [];\n const skipped: ImportResult['skipped'] = [];\n const errors: ImportResult['errors'] = [];\n\n for (const operation of parseResult.operations) {\n // Filter by tags if specified\n if (tags && tags.length > 0) {\n const hasMatchingTag = operation.tags.some((t) => tags.includes(t));\n if (!hasMatchingTag) {\n skipped.push({\n sourceId: operation.operationId,\n reason: `No matching tags (has: ${operation.tags.join(', ')})`,\n });\n continue;\n }\n }\n\n // Filter by include/exclude\n if (include && include.length > 0) {\n if (!include.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Not in include list',\n });\n continue;\n }\n } else if (exclude.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'In exclude list',\n });\n continue;\n }\n\n // Skip deprecated operations by default\n if (\n operation.deprecated &&\n importOptions.defaultStability !== 'deprecated'\n ) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Deprecated operation',\n });\n continue;\n }\n\n try {\n // Build input schemas\n const inputSchemas = buildInputSchemas(operation);\n const schemaFormat =\n importOptions.schemaFormat ||\n contractspecOptions.schemaFormat ||\n 'contractspec';\n\n // Generate models for each input source\n const inputModel = inputSchemas.body\n ? generateSchemaModelCode(\n inputSchemas.body,\n `${operation.operationId}Input`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const queryModel = inputSchemas.query\n ? generateSchemaModelCode(\n inputSchemas.query,\n `${operation.operationId}Query`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const paramsModel = inputSchemas.params\n ? generateSchemaModelCode(\n inputSchemas.params,\n `${operation.operationId}Params`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const headersModel = inputSchemas.headers\n ? generateSchemaModelCode(\n inputSchemas.headers,\n `${operation.operationId}Headers`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n // Get output schema\n const outputSchema = getOutputSchema(operation);\n let outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n // Filter out empty/comment-only output models ONLY for ContractSpec format\n if (\n outputModel &&\n schemaFormat === 'contractspec' &&\n !outputModel.code.includes('defineSchemaModel')\n ) {\n outputModel = null;\n }\n\n // Generate spec code\n const code = generateSpecCode(\n operation,\n contractspecOptions,\n importOptions,\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel\n );\n const specName = toSpecKey(operation.operationId, importOptions.prefix);\n const fileName = toFileName(specName);\n\n // Build transport hints\n const transportHints: OpenApiTransportHints = {\n rest: {\n method:\n operation.method.toUpperCase() as OpenApiTransportHints['rest']['method'],\n path: operation.path,\n params: {\n path: operation.pathParams.map((p) => p.name),\n query: operation.queryParams.map((p) => p.name),\n header: operation.headerParams.map((p) => p.name),\n cookie: operation.cookieParams.map((p) => p.name),\n },\n },\n };\n\n // Build source info\n const source: OpenApiSource = {\n type: 'openapi',\n sourceId: operation.operationId,\n operationId: operation.operationId,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n };\n\n // Resolve group folder based on config\n const groupFolder = resolveOperationGroupFolder(\n operation,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source,\n transportHints,\n });\n } catch (error) {\n errors.push({\n sourceId: operation.operationId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Import standalone models\n for (const [name, schema] of Object.entries(parseResult.schemas)) {\n try {\n const code = generateModelCode(name, schema, {\n ...contractspecOptions,\n schemaFormat:\n importOptions.schemaFormat || contractspecOptions.schemaFormat,\n });\n const fileName = toFileName(toSpecKey(name, importOptions.prefix));\n const groupFolder = resolveModelGroupFolder(\n name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: name,\n operationId: name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: name,\n error:\n error instanceof Error\n ? 'Model conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n // Import events\n for (const event of parseResult.events) {\n try {\n const code = generateEventCode(event, {\n ...contractspecOptions,\n schemaFormat:\n importOptions.schemaFormat || contractspecOptions.schemaFormat,\n });\n const fileName = toFileName(toSpecKey(event.name, importOptions.prefix));\n const groupFolder = resolveEventGroupFolder(\n event.name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: event.name,\n operationId: event.name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: event.name,\n error:\n error instanceof Error\n ? 'Event conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n return {\n operationSpecs: specs,\n skipped,\n errors,\n summary: {\n total:\n parseResult.operations.length +\n Object.keys(parseResult.schemas).length +\n parseResult.events.length,\n imported: specs.length,\n skipped: skipped.length,\n errors: errors.length,\n },\n };\n};\n\n/**\n * Import a single operation to ContractSpec code.\n */\nexport function importOperation(\n operation: ParsedOperation,\n options: Partial<OpenApiSourceConfig> = {},\n contractspecOptions: ResolvedContractsrcConfig\n): string {\n // Build input schemas\n const inputSchemas = buildInputSchemas(operation);\n const schemaFormat =\n options.schemaFormat || contractspecOptions.schemaFormat || 'contractspec';\n\n // Generate models for each input source\n const inputModel = inputSchemas.body\n ? generateSchemaModelCode(\n inputSchemas.body,\n `${operation.operationId}Input`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const queryModel = inputSchemas.query\n ? generateSchemaModelCode(\n inputSchemas.query,\n `${operation.operationId}Query`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const paramsModel = inputSchemas.params\n ? generateSchemaModelCode(\n inputSchemas.params,\n `${operation.operationId}Params`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const headersModel = inputSchemas.headers\n ? generateSchemaModelCode(\n inputSchemas.headers,\n `${operation.operationId}Headers`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const outputSchema = getOutputSchema(operation);\n const outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n return generateSpecCode(\n operation,\n contractspecOptions,\n options,\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","names":[],"sources":["../../../src/openapi/importer/models.ts"],"sourcesContent":["import type { OpenApiSchema } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@contractspec/lib.contracts';\n\n/**\n * Generate code for a standalone model.\n */\nexport function generateModelCode(\n name: string,\n schema: OpenApiSchema,\n options: ContractsrcConfig\n): string {\n const modelName = toPascalCase(toValidIdentifier(name));\n const schemaFormat = options.schemaFormat || 'contractspec';\n\n const model = generateSchemaModelCode(\n schema,\n modelName,\n schemaFormat,\n options\n );\n\n let imports = '';\n if (model.imports && model.imports.length > 0) {\n imports = model.imports.join('\\n');\n } else if (model.fields.length > 0) {\n imports = generateImports(model.fields, options);\n }\n\n return `\n${imports}\n\n${model.code}\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,MACA,QACA,SACQ;CAIR,MAAM,QAAQ,wBACZ,QAJgB,aAAa,kBAAkB,KAAK,CAAC,EAClC,QAAQ,gBAAgB,gBAM3C,QACD;CAED,IAAI,UAAU;AACd,KAAI,MAAM,WAAW,MAAM,QAAQ,SAAS,EAC1C,WAAU,MAAM,QAAQ,KAAK,KAAK;UACzB,MAAM,OAAO,SAAS,EAC/B,WAAU,gBAAgB,MAAM,QAAQ,QAAQ;AAGlD,QAAO;EACP,QAAQ;;EAER,MAAM,KAAK;EACX,MAAM"}
1
+ {"version":3,"file":"models.js","names":[],"sources":["../../../src/openapi/importer/models.ts"],"sourcesContent":["import type { OpenApiSchema } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ResolvedContractsrcConfig } from '@contractspec/lib.contracts';\n\n/**\n * Generate code for a standalone model.\n */\nexport function generateModelCode(\n name: string,\n schema: OpenApiSchema,\n options: ResolvedContractsrcConfig\n): string {\n const modelName = toPascalCase(toValidIdentifier(name));\n const schemaFormat = options.schemaFormat || 'contractspec';\n\n const model = generateSchemaModelCode(\n schema,\n modelName,\n schemaFormat,\n options\n );\n\n let imports = '';\n if (model.imports && model.imports.length > 0) {\n imports = model.imports.join('\\n');\n } else if (model.fields.length > 0) {\n imports = generateImports(model.fields, options);\n }\n\n return `\n${imports}\n\n${model.code}\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,MACA,QACA,SACQ;CAIR,MAAM,QAAQ,wBACZ,QAJgB,aAAa,kBAAkB,KAAK,CAAC,EAClC,QAAQ,gBAAgB,gBAM3C,QACD;CAED,IAAI,UAAU;AACd,KAAI,MAAM,WAAW,MAAM,QAAQ,SAAS,EAC1C,WAAU,MAAM,QAAQ,KAAK,KAAK;UACzB,MAAM,OAAO,SAAS,EAC/B,WAAU,gBAAgB,MAAM,QAAQ,QAAQ;AAGlD,QAAO;EACP,QAAQ;;EAER,MAAM,KAAK;EACX,MAAM"}
@@ -1,5 +1,5 @@
1
1
  import { OpenApiSchema } from "./types.js";
2
- import { ContractsrcConfig, SchemaFormat } from "@contractspec/lib.contracts";
2
+ import { ResolvedContractsrcConfig, SchemaFormat } from "@contractspec/lib.contracts";
3
3
 
4
4
  //#region src/openapi/schema-converter.d.ts
5
5
 
@@ -61,11 +61,11 @@ declare function getScalarType(schema: OpenApiSchema): string | undefined;
61
61
  /**
62
62
  * Generate code for a schema model using the specified format.
63
63
  */
64
- declare function generateSchemaModelCode(schema: OpenApiSchema, modelName: string, schemaFormat?: SchemaFormat, config?: ContractsrcConfig): GeneratedModel;
64
+ declare function generateSchemaModelCode(schema: OpenApiSchema, modelName: string, schemaFormat?: SchemaFormat, config?: ResolvedContractsrcConfig): GeneratedModel;
65
65
  /**
66
66
  * Generate import statements for a SchemaModel.
67
67
  */
68
- declare function generateImports(fields: SchemaField[], options: ContractsrcConfig, sameDirectory?: boolean): string;
68
+ declare function generateImports(fields: SchemaField[], options: ResolvedContractsrcConfig, sameDirectory?: boolean): string;
69
69
  //#endregion
70
70
  export { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToType };
71
71
  //# sourceMappingURL=schema-converter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-converter.d.ts","names":[],"sources":["../../src/openapi/schema-converter.ts"],"sourcesContent":[],"mappings":";;;;;AAkEA;AA+BA;AAiHA;AA2BgB,UA7MC,cAAA,CA6MsB;EAC7B;EAEM,IAAA,EAAA,MAAA;EACL;EACR,QAAA,EAAA,OAAA;EAAc;EAkBD,KAAA,EAAA,OAAA;;;;;;;;;;;UAlNC,WAAA;;;;QAIT;;;;;;gBAMQ;;;;;UAMC,cAAA;;;;;;UAMP;;;;;;;;;iBAyBM,gBAAA,SACN,+BAEP;;;;iBA8Ga,aAAA,SAAsB;;;;iBA2BtB,uBAAA,SACN,iDAEM,uBACL,oBACR;;;;iBAkBa,eAAA,SACN,wBACC"}
1
+ {"version":3,"file":"schema-converter.d.ts","names":[],"sources":["../../src/openapi/schema-converter.ts"],"sourcesContent":[],"mappings":";;;;;AAkEA;AA+BA;AAiHA;AA2BgB,UA7MC,cAAA,CA6MsB;EAC7B;EAEM,IAAA,EAAA,MAAA;EACL;EACR,QAAA,EAAA,OAAA;EAAc;EAkBD,KAAA,EAAA,OAAA;;;;;;;;;;;UAlNC,WAAA;;;;QAIT;;;;;;gBAMQ;;;;;UAMC,cAAA;;;;;;UAMP;;;;;;;;;iBAyBM,gBAAA,SACN,+BAEP;;;;iBA8Ga,aAAA,SAAsB;;;;iBA2BtB,uBAAA,SACN,iDAEM,uBACL,4BACR;;;;iBAkBa,eAAA,SACN,wBACC"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema-converter.js","names":[],"sources":["../../src/openapi/schema-converter.ts"],"sourcesContent":["/**\n * JSON Schema to SchemaModel conversion utilities.\n * Converts OpenAPI JSON Schema to ContractSpec SchemaModel definitions.\n */\n\nimport { createSchemaGenerator } from './schema-generators';\nimport type {\n SchemaFormat,\n ContractsrcConfig,\n} from '@contractspec/lib.contracts';\nimport type { OpenApiSchema } from './types';\nimport { toPascalCase } from '../common/utils';\n\n/**\n * Map JSON Schema types to ContractSpec ScalarTypeEnum values.\n */\nconst JSON_SCHEMA_TO_SCALAR: Record<string, string> = {\n string: 'ScalarTypeEnum.String_unsecure',\n integer: 'ScalarTypeEnum.Int_unsecure',\n number: 'ScalarTypeEnum.Float_unsecure',\n boolean: 'ScalarTypeEnum.Boolean',\n // Special formats\n 'string:date': 'ScalarTypeEnum.Date',\n 'string:date-time': 'ScalarTypeEnum.DateTime',\n 'string:email': 'ScalarTypeEnum.EmailAddress',\n 'string:uri': 'ScalarTypeEnum.URL',\n 'string:uuid': 'ScalarTypeEnum.ID',\n};\n\n/**\n * TypeScript type representation for code generation.\n */\nexport interface TypescriptType {\n /** The type expression (e.g., \"string\", \"number\", \"MyModel\") */\n type: string;\n /** Whether the type is optional */\n optional: boolean;\n /** Whether the type is an array */\n array: boolean;\n /** Whether this is a primitive type */\n primitive: boolean;\n /** Description for documentation */\n description?: string;\n /** Whether this type is a reference to another schema (needs import) vs inline */\n isReference?: boolean;\n}\n\n/**\n * SchemaModel field representation for code generation.\n */\nexport interface SchemaField {\n /** Field name */\n name: string;\n /** Field type */\n type: TypescriptType;\n /** Scalar type enum value (for FieldType) */\n scalarType?: string;\n /** Enum values if this is an enum type */\n enumValues?: string[];\n /** Nested model if this is an object type */\n nestedModel?: GeneratedModel;\n}\n\n/**\n * Generated model representation.\n */\nexport interface GeneratedModel {\n /** Model name (PascalCase) */\n name: string;\n /** Model description */\n description?: string;\n /** Fields */\n fields: SchemaField[];\n /** Generated TypeScript code */\n code: string;\n /** Required imports */\n imports?: string[];\n}\n\n/**\n * Check if a schema is a reference object.\n */\nfunction isReference(schema: OpenApiSchema): schema is { $ref: string } {\n return typeof schema === 'object' && schema !== null && '$ref' in schema;\n}\n\n/**\n * Extract type name from a $ref.\n */\nfunction typeNameFromRef(ref: string): string {\n const parts = ref.split('/');\n return parts[parts.length - 1] ?? 'Unknown';\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type representation.\n */\nexport function jsonSchemaToType(\n schema: OpenApiSchema,\n name?: string\n): TypescriptType {\n if (isReference(schema)) {\n return {\n type: toPascalCase(typeNameFromRef(schema.$ref)),\n optional: false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n // Check if this schema was dereferenced from a $ref - use the original type name\n const originalTypeName = schemaObj['_originalTypeName'] as string | undefined;\n if (originalTypeName) {\n return {\n type: toPascalCase(originalTypeName),\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle arrays\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n const itemType = jsonSchemaToType(items, name);\n return {\n ...itemType,\n array: true,\n optional: nullable ?? false,\n };\n }\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: true,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle objects\n if (type === 'object' || schemaObj['properties']) {\n return {\n type: name ? toPascalCase(name) : 'Record<string, unknown>',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle enums\n if (schemaObj['enum']) {\n return {\n type: name ? toPascalCase(name) : 'string',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle primitives\n const scalarKey = format ? `${type}:${format}` : type;\n if (scalarKey === 'string') {\n return {\n type: 'string',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'integer' || type === 'number') {\n return {\n type: 'number',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'boolean') {\n return {\n type: 'boolean',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n\n // Default to unknown\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n}\n\n/**\n * Get the ScalarTypeEnum value for a JSON Schema type.\n */\nexport function getScalarType(schema: OpenApiSchema): string | undefined {\n if (isReference(schema)) {\n return undefined;\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n\n if (!type) return undefined;\n\n // For arrays, get the scalar type of the items\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n return getScalarType(items);\n }\n return undefined;\n }\n\n const key = format ? `${type}:${format}` : type;\n return JSON_SCHEMA_TO_SCALAR[key] ?? JSON_SCHEMA_TO_SCALAR[type] ?? undefined;\n}\n\n/**\n * Generate code for a schema model using the specified format.\n */\nexport function generateSchemaModelCode(\n schema: OpenApiSchema,\n modelName: string,\n schemaFormat: SchemaFormat = 'contractspec',\n config?: ContractsrcConfig\n): GeneratedModel {\n const generator = createSchemaGenerator(schemaFormat, config);\n const result = generator.generateModel(schema, modelName, {\n description: (schema as Record<string, unknown>)['description'] as string,\n });\n\n return {\n name: result.name,\n description: (schema as Record<string, unknown>)['description'] as string,\n fields: [], // fields are processed internally by generators now\n code: result.code,\n imports: result.imports,\n };\n}\n\n/**\n * Generate import statements for a SchemaModel.\n */\nexport function generateImports(\n fields: SchemaField[],\n options: ContractsrcConfig,\n sameDirectory = true\n): string {\n const imports = new Set<string>();\n const modelsDir = sameDirectory ? '.' : `../${options.conventions.models}`;\n\n imports.add(\n \"import { defineSchemaModel, ScalarTypeEnum, EnumType } from '@contractspec/lib.schema';\"\n );\n\n for (const field of fields) {\n // Only import fields that are actual references to other schemas (not inline types)\n if (\n field.type.isReference &&\n !field.type.primitive &&\n !field.enumValues &&\n !field.scalarType &&\n !field.nestedModel\n ) {\n // This is a reference to another schema model\n const modelName = field.type.type;\n const kebabName = modelName\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(`import { ${modelName} } from '${modelsDir}/${kebabName}';`);\n }\n }\n\n return Array.from(imports).join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema-converter.js","names":[],"sources":["../../src/openapi/schema-converter.ts"],"sourcesContent":["/**\n * JSON Schema to SchemaModel conversion utilities.\n * Converts OpenAPI JSON Schema to ContractSpec SchemaModel definitions.\n */\n\nimport { createSchemaGenerator } from './schema-generators';\nimport type {\n SchemaFormat,\n ResolvedContractsrcConfig,\n} from '@contractspec/lib.contracts';\nimport type { OpenApiSchema } from './types';\nimport { toPascalCase } from '../common/utils';\n\n/**\n * Map JSON Schema types to ContractSpec ScalarTypeEnum values.\n */\nconst JSON_SCHEMA_TO_SCALAR: Record<string, string> = {\n string: 'ScalarTypeEnum.String_unsecure',\n integer: 'ScalarTypeEnum.Int_unsecure',\n number: 'ScalarTypeEnum.Float_unsecure',\n boolean: 'ScalarTypeEnum.Boolean',\n // Special formats\n 'string:date': 'ScalarTypeEnum.Date',\n 'string:date-time': 'ScalarTypeEnum.DateTime',\n 'string:email': 'ScalarTypeEnum.EmailAddress',\n 'string:uri': 'ScalarTypeEnum.URL',\n 'string:uuid': 'ScalarTypeEnum.ID',\n};\n\n/**\n * TypeScript type representation for code generation.\n */\nexport interface TypescriptType {\n /** The type expression (e.g., \"string\", \"number\", \"MyModel\") */\n type: string;\n /** Whether the type is optional */\n optional: boolean;\n /** Whether the type is an array */\n array: boolean;\n /** Whether this is a primitive type */\n primitive: boolean;\n /** Description for documentation */\n description?: string;\n /** Whether this type is a reference to another schema (needs import) vs inline */\n isReference?: boolean;\n}\n\n/**\n * SchemaModel field representation for code generation.\n */\nexport interface SchemaField {\n /** Field name */\n name: string;\n /** Field type */\n type: TypescriptType;\n /** Scalar type enum value (for FieldType) */\n scalarType?: string;\n /** Enum values if this is an enum type */\n enumValues?: string[];\n /** Nested model if this is an object type */\n nestedModel?: GeneratedModel;\n}\n\n/**\n * Generated model representation.\n */\nexport interface GeneratedModel {\n /** Model name (PascalCase) */\n name: string;\n /** Model description */\n description?: string;\n /** Fields */\n fields: SchemaField[];\n /** Generated TypeScript code */\n code: string;\n /** Required imports */\n imports?: string[];\n}\n\n/**\n * Check if a schema is a reference object.\n */\nfunction isReference(schema: OpenApiSchema): schema is { $ref: string } {\n return typeof schema === 'object' && schema !== null && '$ref' in schema;\n}\n\n/**\n * Extract type name from a $ref.\n */\nfunction typeNameFromRef(ref: string): string {\n const parts = ref.split('/');\n return parts[parts.length - 1] ?? 'Unknown';\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type representation.\n */\nexport function jsonSchemaToType(\n schema: OpenApiSchema,\n name?: string\n): TypescriptType {\n if (isReference(schema)) {\n return {\n type: toPascalCase(typeNameFromRef(schema.$ref)),\n optional: false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n // Check if this schema was dereferenced from a $ref - use the original type name\n const originalTypeName = schemaObj['_originalTypeName'] as string | undefined;\n if (originalTypeName) {\n return {\n type: toPascalCase(originalTypeName),\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle arrays\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n const itemType = jsonSchemaToType(items, name);\n return {\n ...itemType,\n array: true,\n optional: nullable ?? false,\n };\n }\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: true,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle objects\n if (type === 'object' || schemaObj['properties']) {\n return {\n type: name ? toPascalCase(name) : 'Record<string, unknown>',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle enums\n if (schemaObj['enum']) {\n return {\n type: name ? toPascalCase(name) : 'string',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle primitives\n const scalarKey = format ? `${type}:${format}` : type;\n if (scalarKey === 'string') {\n return {\n type: 'string',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'integer' || type === 'number') {\n return {\n type: 'number',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'boolean') {\n return {\n type: 'boolean',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n\n // Default to unknown\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n}\n\n/**\n * Get the ScalarTypeEnum value for a JSON Schema type.\n */\nexport function getScalarType(schema: OpenApiSchema): string | undefined {\n if (isReference(schema)) {\n return undefined;\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n\n if (!type) return undefined;\n\n // For arrays, get the scalar type of the items\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n return getScalarType(items);\n }\n return undefined;\n }\n\n const key = format ? `${type}:${format}` : type;\n return JSON_SCHEMA_TO_SCALAR[key] ?? JSON_SCHEMA_TO_SCALAR[type] ?? undefined;\n}\n\n/**\n * Generate code for a schema model using the specified format.\n */\nexport function generateSchemaModelCode(\n schema: OpenApiSchema,\n modelName: string,\n schemaFormat: SchemaFormat = 'contractspec',\n config?: ResolvedContractsrcConfig\n): GeneratedModel {\n const generator = createSchemaGenerator(schemaFormat, config);\n const result = generator.generateModel(schema, modelName, {\n description: (schema as Record<string, unknown>)['description'] as string,\n });\n\n return {\n name: result.name,\n description: (schema as Record<string, unknown>)['description'] as string,\n fields: [], // fields are processed internally by generators now\n code: result.code,\n imports: result.imports,\n };\n}\n\n/**\n * Generate import statements for a SchemaModel.\n */\nexport function generateImports(\n fields: SchemaField[],\n options: ResolvedContractsrcConfig,\n sameDirectory = true\n): string {\n const imports = new Set<string>();\n const modelsDir = sameDirectory ? '.' : `../${options.conventions.models}`;\n\n imports.add(\n \"import { defineSchemaModel, ScalarTypeEnum, EnumType } from '@contractspec/lib.schema';\"\n );\n\n for (const field of fields) {\n // Only import fields that are actual references to other schemas (not inline types)\n if (\n field.type.isReference &&\n !field.type.primitive &&\n !field.enumValues &&\n !field.scalarType &&\n !field.nestedModel\n ) {\n // This is a reference to another schema model\n const modelName = field.type.type;\n const kebabName = modelName\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(`import { ${modelName} } from '${modelsDir}/${kebabName}';`);\n }\n }\n\n return Array.from(imports).join('\\n');\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["safeModelName"],"sources":["../../../src/openapi/schema-generators/index.ts"],"sourcesContent":["/**\n * Schema generator factory for multi-format code generation.\n *\n * Provides format-specific generators for OpenAPI to ContractSpec conversion.\n *\n * @module schema-generators\n */\n\nimport type {\n ContractsrcConfig,\n SchemaFormat,\n} from '@contractspec/lib.contracts';\nimport type { OpenApiSchema } from '../types';\nimport {\n type GeneratedModel,\n generateImports,\n getScalarType,\n jsonSchemaToType,\n type SchemaField,\n} from '../schema-converter';\nimport {\n toKebabCase,\n toPascalCase,\n toValidIdentifier,\n} from '../../common/utils';\n\nconst JSON_SCHEMA_TO_SCALAR: Record<string, string> = {\n string: 'ScalarTypeEnum.String_unsecure',\n integer: 'ScalarTypeEnum.Int_unsecure',\n number: 'ScalarTypeEnum.Float_unsecure',\n boolean: 'ScalarTypeEnum.Boolean',\n 'string:date': 'ScalarTypeEnum.Date',\n 'string:date-time': 'ScalarTypeEnum.DateTime',\n 'string:email': 'ScalarTypeEnum.EmailAddress',\n 'string:uri': 'ScalarTypeEnum.URL',\n 'string:uuid': 'ScalarTypeEnum.ID',\n};\n\nfunction isReference(schema: OpenApiSchema): schema is { $ref: string } {\n return typeof schema === 'object' && schema !== null && '$ref' in schema;\n}\n\nfunction typeNameFromRef(ref: string): string {\n const parts = ref.split('/');\n return parts[parts.length - 1] ?? 'Unknown';\n}\n\n/**\n * Generated code output for a model.\n */\nexport interface GeneratedCode {\n /** The generated TypeScript/JSON code */\n code: string;\n /** File name for the generated code */\n fileName: string;\n /** Required imports */\n imports: string[];\n /** The name of the exported symbol */\n name: string;\n}\n\n/**\n * Generated code output for a field.\n */\nexport interface GeneratedFieldCode {\n /** The field code snippet */\n code: string;\n /** Type reference for the field */\n typeRef: string;\n /** Whether this is an optional field */\n isOptional: boolean;\n /** Whether this is an array field */\n isArray: boolean;\n}\n\n/**\n * Interface for format-specific schema generators.\n */\nexport interface SchemaGenerator {\n /** Format this generator produces */\n format: SchemaFormat;\n\n /**\n * Generate code for a complete model/schema.\n */\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode;\n\n /**\n * Generate code for a single field.\n */\n generateField(\n schema: OpenApiSchema,\n fieldName: string,\n required: boolean\n ): GeneratedFieldCode;\n\n /**\n * Get import statements needed for this generator's output.\n */\n getBaseImports(): string[];\n}\n\n/**\n * Factory function to create a format-specific schema generator.\n *\n * @param format - The target output format\n * @param config - ContractSpec configuration\n * @returns A schema generator for the specified format\n *\n * @example\n * ```typescript\n * const generator = createSchemaGenerator('zod', config);\n * const model = generator.generateModel(openApiSchema, 'User');\n * ```\n */\nexport function createSchemaGenerator(\n format: SchemaFormat,\n config?: ContractsrcConfig\n): SchemaGenerator {\n switch (format) {\n case 'zod':\n return new ZodSchemaGenerator(config);\n case 'json-schema':\n return new JsonSchemaGenerator(config);\n case 'graphql':\n return new GraphQLSchemaGenerator(config);\n case 'contractspec':\n default:\n return new ContractSpecSchemaGenerator(config);\n }\n}\n\n// ============================================================================\n// ContractSpec Generator (default)\n// ============================================================================\n\nexport class ContractSpecSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'contractspec';\n config?: ContractsrcConfig;\n\n constructor(config?: ContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(schema: OpenApiSchema, name: string): GeneratedCode {\n const model = this.generateContractSpecSchema(schema, name);\n\n // Calculate imports for dependencies\n const dependencyImports = this.config\n ? generateImports(model.fields, this.config, false)\n .split('\\n')\n .filter(Boolean)\n : [];\n\n // Add nested model imports?\n // Nested models are inlined in code, but might have refs.\n // generateImports handles fields recursively? No, generateImports iterates top-level fields.\n // But nested models are hoisted, so their fields are not in 'fields' array of parent directly?\n // Wait, GeneratedModel.fields contains 'nestedModel'.\n // generateImports should traverse nested models?\n // The original generateImports does NOT traverse nested models.\n // However, the original code worked, so maybe simple traversal is enough.\n\n return {\n code: model.code,\n fileName: toKebabCase(name) + '.ts',\n imports: [...this.getBaseImports(), ...dependencyImports],\n name: model.name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const field = this.convertField(schema, fieldName, required);\n\n return {\n code: field.scalarType\n ? `${field.scalarType}()`\n : 'ScalarTypeEnum.String_unsecure()',\n typeRef: field.type.type,\n isOptional: field.type.optional,\n isArray: field.type.array,\n };\n }\n\n getBaseImports(): string[] {\n return [\n \"import { defineSchemaModel, ScalarTypeEnum, EnumType } from '@contractspec/lib.schema';\",\n ];\n }\n\n // Ported logic\n private generateContractSpecSchema(\n schema: OpenApiSchema,\n modelName: string,\n indent = 0\n ): GeneratedModel {\n const spaces = ' '.repeat(indent);\n const fields: SchemaField[] = [];\n\n if (isReference(schema)) {\n return {\n name: toPascalCase(typeNameFromRef(schema.$ref)),\n fields: [],\n code: `// Reference to ${schema.$ref}`,\n };\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const description = schemaObj['description'] as string | undefined;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const required = (schemaObj['required'] as string[]) ?? [];\n\n // Handle enum types\n const enumValues = schemaObj['enum'] as unknown[] | undefined;\n if (enumValues && enumValues.length > 0) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const enumCode = [\n `${spaces}/**`,\n `${spaces} * Enum type: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = new EnumType('${safeModelName}', [${enumValues.map((v) => `'${String(v)}'`).join(', ')}]);`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: enumCode,\n };\n }\n\n // Handle primitive types alias\n const schemaType = schemaObj['type'] as string | undefined;\n if (schemaType && !properties && !enumValues) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const format = schemaObj['format'] as string | undefined;\n const scalarKey = format ? `${schemaType}:${format}` : schemaType;\n const scalarType =\n JSON_SCHEMA_TO_SCALAR[scalarKey] ?? JSON_SCHEMA_TO_SCALAR[schemaType];\n\n if (scalarType) {\n const aliasCode = [\n `${spaces}/**`,\n `${spaces} * Type alias: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} * Underlying type: ${scalarType}`,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = defineSchemaModel({`,\n `${spaces} name: '${safeModelName}',`,\n description\n ? `${spaces} description: ${JSON.stringify(description)},`\n : null,\n `${spaces} fields: {`,\n `${spaces} value: {`,\n `${spaces} type: ${scalarType}(),`,\n `${spaces} isOptional: false,`,\n `${spaces} },`,\n `${spaces} },`,\n `${spaces}});`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: aliasCode,\n };\n }\n }\n\n // Handle additionalProperties (dictionary)\n const additionalProperties = schemaObj['additionalProperties'];\n if (additionalProperties && !properties) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n\n const dictCode = [\n `${spaces}/**`,\n `${spaces} * Dictionary/Record type: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} * Use as: Record<string, unknown> - access via record[key]`,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = ScalarTypeEnum.JSONObject();`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: dictCode,\n };\n }\n\n if (!properties) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const emptyModelCode = [\n `${spaces}export const ${safeModelName} = defineSchemaModel({`,\n `${spaces} name: '${safeModelName}',`,\n description\n ? `${spaces} description: ${JSON.stringify(description)},`\n : null,\n `${spaces} fields: {},`,\n `${spaces}});`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: emptyModelCode,\n };\n }\n\n // Generate fields\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.includes(propName);\n fields.push(\n this.convertField(propSchema, propName, isRequired, safeModelName)\n );\n }\n\n // Generate code\n const lines: string[] = [];\n\n // Prepend nested models\n for (const field of fields) {\n if (field.nestedModel) {\n lines.push(field.nestedModel.code);\n lines.push('');\n }\n }\n\n // Model definition\n lines.push(`${spaces}export const ${safeModelName} = defineSchemaModel({`);\n lines.push(`${spaces} name: '${safeModelName}',`);\n if (description) {\n lines.push(`${spaces} description: ${JSON.stringify(description)},`);\n }\n lines.push(`${spaces} fields: {`);\n\n for (const field of fields) {\n const fieldLines = this.generateFieldCodeHelper(field, indent + 2);\n lines.push(fieldLines);\n }\n\n lines.push(`${spaces} },`);\n lines.push(`${spaces}});`);\n\n return {\n name: safeModelName,\n description,\n fields,\n code: lines.join('\\n'),\n imports: [],\n };\n }\n\n private convertField(\n schema: OpenApiSchema,\n fieldName: string,\n required: boolean,\n parentName?: string\n ): SchemaField {\n const type = jsonSchemaToType(schema, fieldName);\n const scalarType = getScalarType(schema);\n\n let enumValues: string[] | undefined;\n let nestedModel: GeneratedModel | undefined;\n\n if (!isReference(schema)) {\n const schemaObj = schema as Record<string, unknown>;\n const enumArr = schemaObj['enum'] as unknown[] | undefined;\n if (enumArr) {\n enumValues = enumArr.map(String);\n }\n\n // Handle nested objects\n if (\n schemaObj['type'] === 'object' &&\n !scalarType &&\n schemaObj['properties'] &&\n !enumValues\n ) {\n const nestedName =\n (parentName ? parentName : '') + toPascalCase(fieldName);\n nestedModel = this.generateContractSpecSchema(schema, nestedName);\n\n type.type = nestedModel.name;\n type.isReference = true;\n }\n }\n\n return {\n name: fieldName,\n type: {\n ...type,\n optional: !required || type.optional,\n description: !isReference(schema)\n ? ((schema as Record<string, unknown>)['description'] as string)\n : undefined,\n },\n scalarType,\n enumValues,\n nestedModel,\n };\n }\n\n private generateFieldCodeHelper(field: SchemaField, indent: number): string {\n const spaces = ' '.repeat(indent);\n const lines: string[] = [];\n\n const isIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(field.name);\n const safeKey = isIdentifier ? field.name : `'${field.name}'`;\n lines.push(`${spaces}${safeKey}: {`);\n\n if (field.enumValues) {\n const enumName = toPascalCase(field.name) + 'Enum';\n lines.push(\n `${spaces} type: new EnumType('${enumName}', [${field.enumValues.map((v) => `'${v}'`).join(', ')}]),`\n );\n } else if (field.scalarType) {\n lines.push(`${spaces} type: ${field.scalarType}(),`);\n } else if (field.nestedModel) {\n lines.push(`${spaces} type: ${field.nestedModel.name},`);\n } else if (field.type.primitive) {\n const fallbackScalar =\n field.type.type === 'number'\n ? 'ScalarTypeEnum.Float_unsecure'\n : field.type.type === 'boolean'\n ? 'ScalarTypeEnum.Boolean_unsecure'\n : 'ScalarTypeEnum.String_unsecure';\n lines.push(`${spaces} type: ${fallbackScalar}(),`);\n } else if (field.type.isReference) {\n lines.push(`${spaces} type: ${field.type.type},`);\n } else {\n lines.push(\n `${spaces} type: ScalarTypeEnum.JSONObject(), // TODO: Define nested model for ${field.type.type}`\n );\n }\n\n lines.push(`${spaces} isOptional: ${field.type.optional},`);\n\n if (field.type.array) {\n lines.push(`${spaces} isArray: true,`);\n }\n\n lines.push(`${spaces}},`);\n\n return lines.join('\\n');\n }\n}\n\n// ============================================================================\n// Zod Generator\n// ============================================================================\n\nexport class ZodSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'zod';\n config?: ContractsrcConfig;\n\n constructor(config?: ContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode {\n const schemaObj = schema as Record<string, unknown>;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const _required = (schemaObj['required'] as string[]) ?? [];\n const description = options?.description ?? schemaObj['description'];\n\n const lines: string[] = [];\n\n if (description) {\n lines.push(`/**`);\n lines.push(` * ${description}`);\n lines.push(` */`);\n }\n\n // Generate Zod Schema\n const schemaName = `${name}Schema`;\n let schemaCode;\n\n if (properties) {\n schemaCode = this.generateZodObject(schemaObj);\n } else {\n schemaCode = 'z.object({})';\n }\n\n lines.push(`export const ${schemaName} = ${schemaCode};`);\n lines.push(``);\n\n // Generate ZodSchemaType wrapper for ContractSpec compatibility\n lines.push(\n `export const ${name} = new ZodSchemaType(${schemaName}, { name: '${name}', description: ${JSON.stringify(description)} });`\n );\n lines.push(``);\n\n // Generate Type\n lines.push(`export type ${name} = z.infer<typeof ${schemaName}>;`);\n\n // Dependencies?\n // Zod generator doesn't currently resolve references recursively or import them\n // This is a limitation: if prop is ref, use z.lazy(() => RefSchema) or similar?\n // For now assuming shallow/primitive or using z.unknown/record for complex stuff\n // Or if Contracts-transformers logic for references is ported.\n // Simplifying: Zod generator relies on primitive mapping for now.\n\n return {\n code: lines.join('\\n'),\n fileName: toKebabCase(name) + '.ts',\n imports: this.getBaseImports(), // Todo: Add dependency imports if references used\n name: name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n _fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n let zodType: string;\n\n if (type === 'object' && schemaObj['properties']) {\n zodType = this.generateZodObject(schemaObj);\n } else {\n zodType = this.mapTypeToZod(type, format);\n\n if (schemaObj['enum']) {\n const enumValues = schemaObj['enum'] as string[];\n zodType = `z.enum([${enumValues.map((v) => `'${v}'`).join(', ')}])`;\n }\n\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n const itemField = this.generateField(items, 'item', true);\n zodType = `z.array(${itemField.code.replace('.optional()', '')})`;\n } else {\n zodType = 'z.array(z.unknown())';\n }\n }\n }\n\n // Add constraints\n if (type === 'string') {\n if (schemaObj['minLength'] !== undefined)\n zodType += `.min(${schemaObj['minLength']})`;\n if (schemaObj['maxLength'] !== undefined)\n zodType += `.max(${schemaObj['maxLength']})`;\n if (schemaObj['pattern'] !== undefined)\n zodType += `.regex(/${schemaObj['pattern']}/)`;\n } else if (type === 'integer' || type === 'number') {\n if (schemaObj['minimum'] !== undefined) {\n zodType +=\n schemaObj['exclusiveMinimum'] === true\n ? `.gt(${schemaObj['minimum']})`\n : `.min(${schemaObj['minimum']})`;\n } else if (typeof schemaObj['exclusiveMinimum'] === 'number') {\n zodType += `.gt(${schemaObj['exclusiveMinimum']})`;\n }\n\n if (schemaObj['maximum'] !== undefined) {\n zodType +=\n schemaObj['exclusiveMaximum'] === true\n ? `.lt(${schemaObj['maximum']})`\n : `.max(${schemaObj['maximum']})`;\n } else if (typeof schemaObj['exclusiveMaximum'] === 'number') {\n zodType += `.lt(${schemaObj['exclusiveMaximum']})`;\n }\n\n if (schemaObj['multipleOf'] !== undefined) {\n zodType += `.step(${schemaObj['multipleOf']})`;\n }\n } else if (type === 'array') {\n if (schemaObj['minItems'] !== undefined)\n zodType += `.min(${schemaObj['minItems']})`;\n if (schemaObj['maxItems'] !== undefined)\n zodType += `.max(${schemaObj['maxItems']})`;\n }\n\n if (schemaObj['default'] !== undefined) {\n zodType += `.default(${JSON.stringify(schemaObj['default'])})`;\n }\n\n if (!required || nullable) {\n zodType = `${zodType}.optional()`;\n }\n\n return {\n code: zodType,\n typeRef: type ?? 'unknown',\n isOptional: !required || Boolean(nullable),\n isArray: type === 'array',\n };\n }\n\n getBaseImports(): string[] {\n return [\n \"import * as z from 'zod';\",\n \"import { ZodSchemaType } from '@contractspec/lib.schema';\",\n ];\n }\n\n private generateZodObject(schemaObj: Record<string, unknown>): string {\n const required = (schemaObj['required'] as string[]) ?? [];\n const properties = schemaObj['properties'] as Record<string, OpenApiSchema>;\n const lines: string[] = ['z.object({'];\n\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.includes(propName);\n const field = this.generateField(propSchema, propName, isRequired);\n // If name is not a valid identifier, quote it\n const safeName = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(propName)\n ? propName\n : `'${propName}'`;\n\n lines.push(` ${safeName}: ${field.code},`);\n }\n\n lines.push('})');\n return lines.join('\\n');\n }\n\n private mapTypeToZod(type?: string, format?: string): string {\n if (format === 'date-time') return 'z.string().datetime()';\n if (format === 'date') return 'z.string().date()';\n if (format === 'email') return 'z.string().email()';\n if (format === 'uri' || format === 'url') return 'z.string().url()';\n if (format === 'uuid') return 'z.string().uuid()';\n\n switch (type) {\n case 'string':\n return 'z.string()';\n case 'integer':\n return 'z.number().int()';\n case 'number':\n return 'z.number()';\n case 'boolean':\n return 'z.boolean()';\n case 'object':\n return 'z.record(z.string(), z.unknown())';\n case 'null':\n return 'z.null()';\n default:\n return 'z.unknown()';\n }\n }\n}\n\n// ============================================================================\n// JSON Schema Generator\n// ============================================================================\n\nexport class JsonSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'json-schema';\n config?: ContractsrcConfig;\n\n constructor(config?: ContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode {\n const schemaObj = schema as Record<string, unknown>;\n const description = options?.description ?? schemaObj['description'];\n\n // Create a clean JSON Schema object\n const jsonSchema: Record<string, unknown> = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: name,\n ...schemaObj,\n };\n\n if (description) {\n jsonSchema['description'] = description;\n }\n\n const lines: string[] = [];\n lines.push(`/**`);\n lines.push(` * JSON Schema: ${name}`);\n if (description) {\n lines.push(` * ${description}`);\n }\n lines.push(` */`);\n\n const schemaName = `${name}Schema`;\n lines.push(\n `export const ${schemaName} = ${JSON.stringify(jsonSchema, null, 2)} as const;`\n );\n lines.push(``);\n\n // Generate wrapper\n lines.push(`export const ${name} = new JsonSchemaType(${schemaName});`);\n lines.push(``);\n\n // Type derived from JsonSchemaType or similar?\n // Actually JsonSchemaType doesn't strictly infer TS type from JSON schema at compile time easily without other tools.\n // For now, export type as unknown or rely on library.\n lines.push(\n `export type ${name} = unknown; // JSON Schema type inference not fully supported`\n );\n\n return {\n code: lines.join('\\n'),\n fileName: toKebabCase(name) + '.ts',\n imports: this.getBaseImports(), // dependency imports?\n name: name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n _fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n return {\n code: JSON.stringify(schemaObj),\n typeRef: type ?? 'unknown',\n isOptional: !required || Boolean(nullable),\n isArray: type === 'array',\n };\n }\n\n getBaseImports(): string[] {\n return [\"import { JsonSchemaType } from '@contractspec/lib.schema';\"];\n }\n}\n\n// ============================================================================\n// GraphQL Generator\n// ============================================================================\n\nexport class GraphQLSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'graphql';\n config?: ContractsrcConfig;\n\n constructor(config?: ContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode {\n const schemaObj = schema as Record<string, unknown>;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const required = (schemaObj['required'] as string[]) ?? [];\n const description = options?.description ?? schemaObj['description'];\n\n const lines: string[] = [];\n\n if (description) {\n lines.push(`\"\"\"${description}\"\"\"`);\n }\n\n lines.push(`type ${name} {`);\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.includes(propName);\n const field = this.generateField(propSchema, propName, isRequired);\n const nullMarker = isRequired ? '!' : '';\n lines.push(` ${propName}: ${field.typeRef}${nullMarker}`);\n }\n }\n\n lines.push(`}`);\n\n // Also generate SDL as a string constant\n const sdl = lines.join('\\n');\n const tsLines: string[] = [];\n tsLines.push(`/**`);\n tsLines.push(` * GraphQL type definition: ${name}`);\n tsLines.push(` */`);\n tsLines.push(`export const ${name}TypeDef = \\`${sdl}\\`;`);\n tsLines.push(``);\n tsLines.push(\n `export const ${name} = new GraphQLSchemaType(${name}TypeDef, '${name}');`\n );\n\n return {\n code: tsLines.join('\\n'),\n fileName: toKebabCase(name) + '.ts',\n imports: this.getBaseImports(),\n name: name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n _fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n const gqlType = this.mapTypeToGraphQL(type, format);\n\n return {\n code: gqlType,\n typeRef: gqlType,\n isOptional: !required || Boolean(nullable),\n isArray: type === 'array',\n };\n }\n\n getBaseImports(): string[] {\n return [\"import { GraphQLSchemaType } from '@contractspec/lib.schema';\"];\n }\n\n private mapTypeToGraphQL(type?: string, format?: string): string {\n if (format === 'date-time') return 'DateTime';\n if (format === 'date') return 'Date';\n if (format === 'email') return 'String';\n if (format === 'uri' || format === 'url') return 'String';\n if (format === 'uuid') return 'ID';\n\n switch (type) {\n case 'string':\n return 'String';\n case 'integer':\n return 'Int';\n case 'number':\n return 'Float';\n case 'boolean':\n return 'Boolean';\n case 'object':\n return 'JSON';\n case 'array':\n return '[JSON]';\n default:\n return 'JSON';\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["safeModelName"],"sources":["../../../src/openapi/schema-generators/index.ts"],"sourcesContent":["/**\n * Schema generator factory for multi-format code generation.\n *\n * Provides format-specific generators for OpenAPI to ContractSpec conversion.\n *\n * @module schema-generators\n */\n\nimport type {\n ResolvedContractsrcConfig,\n SchemaFormat,\n} from '@contractspec/lib.contracts';\nimport type { OpenApiSchema } from '../types';\nimport {\n type GeneratedModel,\n generateImports,\n getScalarType,\n jsonSchemaToType,\n type SchemaField,\n} from '../schema-converter';\nimport {\n toKebabCase,\n toPascalCase,\n toValidIdentifier,\n} from '../../common/utils';\n\nconst JSON_SCHEMA_TO_SCALAR: Record<string, string> = {\n string: 'ScalarTypeEnum.String_unsecure',\n integer: 'ScalarTypeEnum.Int_unsecure',\n number: 'ScalarTypeEnum.Float_unsecure',\n boolean: 'ScalarTypeEnum.Boolean',\n 'string:date': 'ScalarTypeEnum.Date',\n 'string:date-time': 'ScalarTypeEnum.DateTime',\n 'string:email': 'ScalarTypeEnum.EmailAddress',\n 'string:uri': 'ScalarTypeEnum.URL',\n 'string:uuid': 'ScalarTypeEnum.ID',\n};\n\nfunction isReference(schema: OpenApiSchema): schema is { $ref: string } {\n return typeof schema === 'object' && schema !== null && '$ref' in schema;\n}\n\nfunction typeNameFromRef(ref: string): string {\n const parts = ref.split('/');\n return parts[parts.length - 1] ?? 'Unknown';\n}\n\n/**\n * Generated code output for a model.\n */\nexport interface GeneratedCode {\n /** The generated TypeScript/JSON code */\n code: string;\n /** File name for the generated code */\n fileName: string;\n /** Required imports */\n imports: string[];\n /** The name of the exported symbol */\n name: string;\n}\n\n/**\n * Generated code output for a field.\n */\nexport interface GeneratedFieldCode {\n /** The field code snippet */\n code: string;\n /** Type reference for the field */\n typeRef: string;\n /** Whether this is an optional field */\n isOptional: boolean;\n /** Whether this is an array field */\n isArray: boolean;\n}\n\n/**\n * Interface for format-specific schema generators.\n */\nexport interface SchemaGenerator {\n /** Format this generator produces */\n format: SchemaFormat;\n\n /**\n * Generate code for a complete model/schema.\n */\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode;\n\n /**\n * Generate code for a single field.\n */\n generateField(\n schema: OpenApiSchema,\n fieldName: string,\n required: boolean\n ): GeneratedFieldCode;\n\n /**\n * Get import statements needed for this generator's output.\n */\n getBaseImports(): string[];\n}\n\n/**\n * Factory function to create a format-specific schema generator.\n *\n * @param format - The target output format\n * @param config - ContractSpec configuration\n * @returns A schema generator for the specified format\n *\n * @example\n * ```typescript\n * const generator = createSchemaGenerator('zod', config);\n * const model = generator.generateModel(openApiSchema, 'User');\n * ```\n */\nexport function createSchemaGenerator(\n format: SchemaFormat,\n config?: ResolvedContractsrcConfig\n): SchemaGenerator {\n switch (format) {\n case 'zod':\n return new ZodSchemaGenerator(config);\n case 'json-schema':\n return new JsonSchemaGenerator(config);\n case 'graphql':\n return new GraphQLSchemaGenerator(config);\n case 'contractspec':\n default:\n return new ContractSpecSchemaGenerator(config);\n }\n}\n\n// ============================================================================\n// ContractSpec Generator (default)\n// ============================================================================\n\nexport class ContractSpecSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'contractspec';\n config?: ResolvedContractsrcConfig;\n\n constructor(config?: ResolvedContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(schema: OpenApiSchema, name: string): GeneratedCode {\n const model = this.generateContractSpecSchema(schema, name);\n\n // Calculate imports for dependencies\n const dependencyImports = this.config\n ? generateImports(model.fields, this.config, false)\n .split('\\n')\n .filter(Boolean)\n : [];\n\n // Add nested model imports?\n // Nested models are inlined in code, but might have refs.\n // generateImports handles fields recursively? No, generateImports iterates top-level fields.\n // But nested models are hoisted, so their fields are not in 'fields' array of parent directly?\n // Wait, GeneratedModel.fields contains 'nestedModel'.\n // generateImports should traverse nested models?\n // The original generateImports does NOT traverse nested models.\n // However, the original code worked, so maybe simple traversal is enough.\n\n return {\n code: model.code,\n fileName: toKebabCase(name) + '.ts',\n imports: [...this.getBaseImports(), ...dependencyImports],\n name: model.name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const field = this.convertField(schema, fieldName, required);\n\n return {\n code: field.scalarType\n ? `${field.scalarType}()`\n : 'ScalarTypeEnum.String_unsecure()',\n typeRef: field.type.type,\n isOptional: field.type.optional,\n isArray: field.type.array,\n };\n }\n\n getBaseImports(): string[] {\n return [\n \"import { defineSchemaModel, ScalarTypeEnum, EnumType } from '@contractspec/lib.schema';\",\n ];\n }\n\n // Ported logic\n private generateContractSpecSchema(\n schema: OpenApiSchema,\n modelName: string,\n indent = 0\n ): GeneratedModel {\n const spaces = ' '.repeat(indent);\n const fields: SchemaField[] = [];\n\n if (isReference(schema)) {\n return {\n name: toPascalCase(typeNameFromRef(schema.$ref)),\n fields: [],\n code: `// Reference to ${schema.$ref}`,\n };\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const description = schemaObj['description'] as string | undefined;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const required = (schemaObj['required'] as string[]) ?? [];\n\n // Handle enum types\n const enumValues = schemaObj['enum'] as unknown[] | undefined;\n if (enumValues && enumValues.length > 0) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const enumCode = [\n `${spaces}/**`,\n `${spaces} * Enum type: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = new EnumType('${safeModelName}', [${enumValues.map((v) => `'${String(v)}'`).join(', ')}]);`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: enumCode,\n };\n }\n\n // Handle primitive types alias\n const schemaType = schemaObj['type'] as string | undefined;\n if (schemaType && !properties && !enumValues) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const format = schemaObj['format'] as string | undefined;\n const scalarKey = format ? `${schemaType}:${format}` : schemaType;\n const scalarType =\n JSON_SCHEMA_TO_SCALAR[scalarKey] ?? JSON_SCHEMA_TO_SCALAR[schemaType];\n\n if (scalarType) {\n const aliasCode = [\n `${spaces}/**`,\n `${spaces} * Type alias: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} * Underlying type: ${scalarType}`,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = defineSchemaModel({`,\n `${spaces} name: '${safeModelName}',`,\n description\n ? `${spaces} description: ${JSON.stringify(description)},`\n : null,\n `${spaces} fields: {`,\n `${spaces} value: {`,\n `${spaces} type: ${scalarType}(),`,\n `${spaces} isOptional: false,`,\n `${spaces} },`,\n `${spaces} },`,\n `${spaces}});`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: aliasCode,\n };\n }\n }\n\n // Handle additionalProperties (dictionary)\n const additionalProperties = schemaObj['additionalProperties'];\n if (additionalProperties && !properties) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n\n const dictCode = [\n `${spaces}/**`,\n `${spaces} * Dictionary/Record type: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} * Use as: Record<string, unknown> - access via record[key]`,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = ScalarTypeEnum.JSONObject();`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: dictCode,\n };\n }\n\n if (!properties) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const emptyModelCode = [\n `${spaces}export const ${safeModelName} = defineSchemaModel({`,\n `${spaces} name: '${safeModelName}',`,\n description\n ? `${spaces} description: ${JSON.stringify(description)},`\n : null,\n `${spaces} fields: {},`,\n `${spaces}});`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: emptyModelCode,\n };\n }\n\n // Generate fields\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.includes(propName);\n fields.push(\n this.convertField(propSchema, propName, isRequired, safeModelName)\n );\n }\n\n // Generate code\n const lines: string[] = [];\n\n // Prepend nested models\n for (const field of fields) {\n if (field.nestedModel) {\n lines.push(field.nestedModel.code);\n lines.push('');\n }\n }\n\n // Model definition\n lines.push(`${spaces}export const ${safeModelName} = defineSchemaModel({`);\n lines.push(`${spaces} name: '${safeModelName}',`);\n if (description) {\n lines.push(`${spaces} description: ${JSON.stringify(description)},`);\n }\n lines.push(`${spaces} fields: {`);\n\n for (const field of fields) {\n const fieldLines = this.generateFieldCodeHelper(field, indent + 2);\n lines.push(fieldLines);\n }\n\n lines.push(`${spaces} },`);\n lines.push(`${spaces}});`);\n\n return {\n name: safeModelName,\n description,\n fields,\n code: lines.join('\\n'),\n imports: [],\n };\n }\n\n private convertField(\n schema: OpenApiSchema,\n fieldName: string,\n required: boolean,\n parentName?: string\n ): SchemaField {\n const type = jsonSchemaToType(schema, fieldName);\n const scalarType = getScalarType(schema);\n\n let enumValues: string[] | undefined;\n let nestedModel: GeneratedModel | undefined;\n\n if (!isReference(schema)) {\n const schemaObj = schema as Record<string, unknown>;\n const enumArr = schemaObj['enum'] as unknown[] | undefined;\n if (enumArr) {\n enumValues = enumArr.map(String);\n }\n\n // Handle nested objects\n if (\n schemaObj['type'] === 'object' &&\n !scalarType &&\n schemaObj['properties'] &&\n !enumValues\n ) {\n const nestedName =\n (parentName ? parentName : '') + toPascalCase(fieldName);\n nestedModel = this.generateContractSpecSchema(schema, nestedName);\n\n type.type = nestedModel.name;\n type.isReference = true;\n }\n }\n\n return {\n name: fieldName,\n type: {\n ...type,\n optional: !required || type.optional,\n description: !isReference(schema)\n ? ((schema as Record<string, unknown>)['description'] as string)\n : undefined,\n },\n scalarType,\n enumValues,\n nestedModel,\n };\n }\n\n private generateFieldCodeHelper(field: SchemaField, indent: number): string {\n const spaces = ' '.repeat(indent);\n const lines: string[] = [];\n\n const isIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(field.name);\n const safeKey = isIdentifier ? field.name : `'${field.name}'`;\n lines.push(`${spaces}${safeKey}: {`);\n\n if (field.enumValues) {\n const enumName = toPascalCase(field.name) + 'Enum';\n lines.push(\n `${spaces} type: new EnumType('${enumName}', [${field.enumValues.map((v) => `'${v}'`).join(', ')}]),`\n );\n } else if (field.scalarType) {\n lines.push(`${spaces} type: ${field.scalarType}(),`);\n } else if (field.nestedModel) {\n lines.push(`${spaces} type: ${field.nestedModel.name},`);\n } else if (field.type.primitive) {\n const fallbackScalar =\n field.type.type === 'number'\n ? 'ScalarTypeEnum.Float_unsecure'\n : field.type.type === 'boolean'\n ? 'ScalarTypeEnum.Boolean_unsecure'\n : 'ScalarTypeEnum.String_unsecure';\n lines.push(`${spaces} type: ${fallbackScalar}(),`);\n } else if (field.type.isReference) {\n lines.push(`${spaces} type: ${field.type.type},`);\n } else {\n lines.push(\n `${spaces} type: ScalarTypeEnum.JSONObject(), // TODO: Define nested model for ${field.type.type}`\n );\n }\n\n lines.push(`${spaces} isOptional: ${field.type.optional},`);\n\n if (field.type.array) {\n lines.push(`${spaces} isArray: true,`);\n }\n\n lines.push(`${spaces}},`);\n\n return lines.join('\\n');\n }\n}\n\n// ============================================================================\n// Zod Generator\n// ============================================================================\n\nexport class ZodSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'zod';\n config?: ResolvedContractsrcConfig;\n\n constructor(config?: ResolvedContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode {\n const schemaObj = schema as Record<string, unknown>;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const _required = (schemaObj['required'] as string[]) ?? [];\n const description = options?.description ?? schemaObj['description'];\n\n const lines: string[] = [];\n\n if (description) {\n lines.push(`/**`);\n lines.push(` * ${description}`);\n lines.push(` */`);\n }\n\n // Generate Zod Schema\n const schemaName = `${name}Schema`;\n let schemaCode;\n\n if (properties) {\n schemaCode = this.generateZodObject(schemaObj);\n } else {\n schemaCode = 'z.object({})';\n }\n\n lines.push(`export const ${schemaName} = ${schemaCode};`);\n lines.push(``);\n\n // Generate ZodSchemaType wrapper for ContractSpec compatibility\n lines.push(\n `export const ${name} = new ZodSchemaType(${schemaName}, { name: '${name}', description: ${JSON.stringify(description)} });`\n );\n lines.push(``);\n\n // Generate Type\n lines.push(`export type ${name} = z.infer<typeof ${schemaName}>;`);\n\n // Dependencies?\n // Zod generator doesn't currently resolve references recursively or import them\n // This is a limitation: if prop is ref, use z.lazy(() => RefSchema) or similar?\n // For now assuming shallow/primitive or using z.unknown/record for complex stuff\n // Or if Contracts-transformers logic for references is ported.\n // Simplifying: Zod generator relies on primitive mapping for now.\n\n return {\n code: lines.join('\\n'),\n fileName: toKebabCase(name) + '.ts',\n imports: this.getBaseImports(), // Todo: Add dependency imports if references used\n name: name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n _fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n let zodType: string;\n\n if (type === 'object' && schemaObj['properties']) {\n zodType = this.generateZodObject(schemaObj);\n } else {\n zodType = this.mapTypeToZod(type, format);\n\n if (schemaObj['enum']) {\n const enumValues = schemaObj['enum'] as string[];\n zodType = `z.enum([${enumValues.map((v) => `'${v}'`).join(', ')}])`;\n }\n\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n const itemField = this.generateField(items, 'item', true);\n zodType = `z.array(${itemField.code.replace('.optional()', '')})`;\n } else {\n zodType = 'z.array(z.unknown())';\n }\n }\n }\n\n // Add constraints\n if (type === 'string') {\n if (schemaObj['minLength'] !== undefined)\n zodType += `.min(${schemaObj['minLength']})`;\n if (schemaObj['maxLength'] !== undefined)\n zodType += `.max(${schemaObj['maxLength']})`;\n if (schemaObj['pattern'] !== undefined)\n zodType += `.regex(/${schemaObj['pattern']}/)`;\n } else if (type === 'integer' || type === 'number') {\n if (schemaObj['minimum'] !== undefined) {\n zodType +=\n schemaObj['exclusiveMinimum'] === true\n ? `.gt(${schemaObj['minimum']})`\n : `.min(${schemaObj['minimum']})`;\n } else if (typeof schemaObj['exclusiveMinimum'] === 'number') {\n zodType += `.gt(${schemaObj['exclusiveMinimum']})`;\n }\n\n if (schemaObj['maximum'] !== undefined) {\n zodType +=\n schemaObj['exclusiveMaximum'] === true\n ? `.lt(${schemaObj['maximum']})`\n : `.max(${schemaObj['maximum']})`;\n } else if (typeof schemaObj['exclusiveMaximum'] === 'number') {\n zodType += `.lt(${schemaObj['exclusiveMaximum']})`;\n }\n\n if (schemaObj['multipleOf'] !== undefined) {\n zodType += `.step(${schemaObj['multipleOf']})`;\n }\n } else if (type === 'array') {\n if (schemaObj['minItems'] !== undefined)\n zodType += `.min(${schemaObj['minItems']})`;\n if (schemaObj['maxItems'] !== undefined)\n zodType += `.max(${schemaObj['maxItems']})`;\n }\n\n if (schemaObj['default'] !== undefined) {\n zodType += `.default(${JSON.stringify(schemaObj['default'])})`;\n }\n\n if (!required || nullable) {\n zodType = `${zodType}.optional()`;\n }\n\n return {\n code: zodType,\n typeRef: type ?? 'unknown',\n isOptional: !required || Boolean(nullable),\n isArray: type === 'array',\n };\n }\n\n getBaseImports(): string[] {\n return [\n \"import * as z from 'zod';\",\n \"import { ZodSchemaType } from '@contractspec/lib.schema';\",\n ];\n }\n\n private generateZodObject(schemaObj: Record<string, unknown>): string {\n const required = (schemaObj['required'] as string[]) ?? [];\n const properties = schemaObj['properties'] as Record<string, OpenApiSchema>;\n const lines: string[] = ['z.object({'];\n\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.includes(propName);\n const field = this.generateField(propSchema, propName, isRequired);\n // If name is not a valid identifier, quote it\n const safeName = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(propName)\n ? propName\n : `'${propName}'`;\n\n lines.push(` ${safeName}: ${field.code},`);\n }\n\n lines.push('})');\n return lines.join('\\n');\n }\n\n private mapTypeToZod(type?: string, format?: string): string {\n if (format === 'date-time') return 'z.string().datetime()';\n if (format === 'date') return 'z.string().date()';\n if (format === 'email') return 'z.string().email()';\n if (format === 'uri' || format === 'url') return 'z.string().url()';\n if (format === 'uuid') return 'z.string().uuid()';\n\n switch (type) {\n case 'string':\n return 'z.string()';\n case 'integer':\n return 'z.number().int()';\n case 'number':\n return 'z.number()';\n case 'boolean':\n return 'z.boolean()';\n case 'object':\n return 'z.record(z.string(), z.unknown())';\n case 'null':\n return 'z.null()';\n default:\n return 'z.unknown()';\n }\n }\n}\n\n// ============================================================================\n// JSON Schema Generator\n// ============================================================================\n\nexport class JsonSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'json-schema';\n config?: ResolvedContractsrcConfig;\n\n constructor(config?: ResolvedContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode {\n const schemaObj = schema as Record<string, unknown>;\n const description = options?.description ?? schemaObj['description'];\n\n // Create a clean JSON Schema object\n const jsonSchema: Record<string, unknown> = {\n $schema: 'https://json-schema.org/draft/2020-12/schema',\n title: name,\n ...schemaObj,\n };\n\n if (description) {\n jsonSchema['description'] = description;\n }\n\n const lines: string[] = [];\n lines.push(`/**`);\n lines.push(` * JSON Schema: ${name}`);\n if (description) {\n lines.push(` * ${description}`);\n }\n lines.push(` */`);\n\n const schemaName = `${name}Schema`;\n lines.push(\n `export const ${schemaName} = ${JSON.stringify(jsonSchema, null, 2)} as const;`\n );\n lines.push(``);\n\n // Generate wrapper\n lines.push(`export const ${name} = new JsonSchemaType(${schemaName});`);\n lines.push(``);\n\n // Type derived from JsonSchemaType or similar?\n // Actually JsonSchemaType doesn't strictly infer TS type from JSON schema at compile time easily without other tools.\n // For now, export type as unknown or rely on library.\n lines.push(\n `export type ${name} = unknown; // JSON Schema type inference not fully supported`\n );\n\n return {\n code: lines.join('\\n'),\n fileName: toKebabCase(name) + '.ts',\n imports: this.getBaseImports(), // dependency imports?\n name: name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n _fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n return {\n code: JSON.stringify(schemaObj),\n typeRef: type ?? 'unknown',\n isOptional: !required || Boolean(nullable),\n isArray: type === 'array',\n };\n }\n\n getBaseImports(): string[] {\n return [\"import { JsonSchemaType } from '@contractspec/lib.schema';\"];\n }\n}\n\n// ============================================================================\n// GraphQL Generator\n// ============================================================================\n\nexport class GraphQLSchemaGenerator implements SchemaGenerator {\n format: SchemaFormat = 'graphql';\n config?: ResolvedContractsrcConfig;\n\n constructor(config?: ResolvedContractsrcConfig) {\n this.config = config;\n }\n\n generateModel(\n schema: OpenApiSchema,\n name: string,\n options?: { description?: string }\n ): GeneratedCode {\n const schemaObj = schema as Record<string, unknown>;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const required = (schemaObj['required'] as string[]) ?? [];\n const description = options?.description ?? schemaObj['description'];\n\n const lines: string[] = [];\n\n if (description) {\n lines.push(`\"\"\"${description}\"\"\"`);\n }\n\n lines.push(`type ${name} {`);\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.includes(propName);\n const field = this.generateField(propSchema, propName, isRequired);\n const nullMarker = isRequired ? '!' : '';\n lines.push(` ${propName}: ${field.typeRef}${nullMarker}`);\n }\n }\n\n lines.push(`}`);\n\n // Also generate SDL as a string constant\n const sdl = lines.join('\\n');\n const tsLines: string[] = [];\n tsLines.push(`/**`);\n tsLines.push(` * GraphQL type definition: ${name}`);\n tsLines.push(` */`);\n tsLines.push(`export const ${name}TypeDef = \\`${sdl}\\`;`);\n tsLines.push(``);\n tsLines.push(\n `export const ${name} = new GraphQLSchemaType(${name}TypeDef, '${name}');`\n );\n\n return {\n code: tsLines.join('\\n'),\n fileName: toKebabCase(name) + '.ts',\n imports: this.getBaseImports(),\n name: name,\n };\n }\n\n generateField(\n schema: OpenApiSchema,\n _fieldName: string,\n required: boolean\n ): GeneratedFieldCode {\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n const gqlType = this.mapTypeToGraphQL(type, format);\n\n return {\n code: gqlType,\n typeRef: gqlType,\n isOptional: !required || Boolean(nullable),\n isArray: type === 'array',\n };\n }\n\n getBaseImports(): string[] {\n return [\"import { GraphQLSchemaType } from '@contractspec/lib.schema';\"];\n }\n\n private mapTypeToGraphQL(type?: string, format?: string): string {\n if (format === 'date-time') return 'DateTime';\n if (format === 'date') return 'Date';\n if (format === 'email') return 'String';\n if (format === 'uri' || format === 'url') return 'String';\n if (format === 'uuid') return 'ID';\n\n switch (type) {\n case 'string':\n return 'String';\n case 'integer':\n return 'Int';\n case 'number':\n return 'Float';\n case 'boolean':\n return 'Boolean';\n case 'object':\n return 'JSON';\n case 'array':\n return '[JSON]';\n default:\n return 'JSON';\n }\n }\n}\n"],"mappings":";;;;AA0BA,MAAM,wBAAgD;CACpD,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,SAAS;CACT,eAAe;CACf,oBAAoB;CACpB,gBAAgB;CAChB,cAAc;CACd,eAAe;CAChB;AAED,SAAS,YAAY,QAAmD;AACtE,QAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,UAAU;;AAGpE,SAAS,gBAAgB,KAAqB;CAC5C,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,QAAO,MAAM,MAAM,SAAS,MAAM;;;;;;;;;;;;;;;AA2EpC,SAAgB,sBACd,QACA,QACiB;AACjB,SAAQ,QAAR;EACE,KAAK,MACH,QAAO,IAAI,mBAAmB,OAAO;EACvC,KAAK,cACH,QAAO,IAAI,oBAAoB,OAAO;EACxC,KAAK,UACH,QAAO,IAAI,uBAAuB,OAAO;EAC3C,KAAK;EACL,QACE,QAAO,IAAI,4BAA4B,OAAO;;;AAQpD,IAAa,8BAAb,MAAoE;CAClE,SAAuB;CACvB;CAEA,YAAY,QAAoC;AAC9C,OAAK,SAAS;;CAGhB,cAAc,QAAuB,MAA6B;EAChE,MAAM,QAAQ,KAAK,2BAA2B,QAAQ,KAAK;EAG3D,MAAM,oBAAoB,KAAK,SAC3B,gBAAgB,MAAM,QAAQ,KAAK,QAAQ,MAAM,CAC9C,MAAM,KAAK,CACX,OAAO,QAAQ,GAClB,EAAE;AAWN,SAAO;GACL,MAAM,MAAM;GACZ,UAAU,YAAY,KAAK,GAAG;GAC9B,SAAS,CAAC,GAAG,KAAK,gBAAgB,EAAE,GAAG,kBAAkB;GACzD,MAAM,MAAM;GACb;;CAGH,cACE,QACA,WACA,UACoB;EACpB,MAAM,QAAQ,KAAK,aAAa,QAAQ,WAAW,SAAS;AAE5D,SAAO;GACL,MAAM,MAAM,aACR,GAAG,MAAM,WAAW,MACpB;GACJ,SAAS,MAAM,KAAK;GACpB,YAAY,MAAM,KAAK;GACvB,SAAS,MAAM,KAAK;GACrB;;CAGH,iBAA2B;AACzB,SAAO,CACL,0FACD;;CAIH,AAAQ,2BACN,QACA,WACA,SAAS,GACO;EAChB,MAAM,SAAS,KAAK,OAAO,OAAO;EAClC,MAAM,SAAwB,EAAE;AAEhC,MAAI,YAAY,OAAO,CACrB,QAAO;GACL,MAAM,aAAa,gBAAgB,OAAO,KAAK,CAAC;GAChD,QAAQ,EAAE;GACV,MAAM,mBAAmB,OAAO;GACjC;EAGH,MAAM,YAAY;EAClB,MAAM,cAAc,UAAU;EAC9B,MAAM,aAAa,UAAU;EAG7B,MAAM,WAAY,UAAU,eAA4B,EAAE;EAG1D,MAAM,aAAa,UAAU;AAC7B,MAAI,cAAc,WAAW,SAAS,GAAG;GACvC,MAAMA,kBAAgB,aAAa,kBAAkB,UAAU,CAAC;AAWhE,UAAO;IACL,MAAMA;IACN;IACA,QAAQ,EAAE;IACV,MAde;KACf,GAAG,OAAO;KACV,GAAG,OAAO,gBAAgBA;KAC1B,cAAc,GAAG,OAAO,KAAK,gBAAgB;KAC7C,GAAG,OAAO;KACV,GAAG,OAAO,eAAeA,gBAAc,mBAAmBA,gBAAc,MAAM,WAAW,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;KAClI,CACE,QAAQ,SAAS,SAAS,KAAK,CAC/B,KAAK,KAAK;IAOZ;;EAIH,MAAM,aAAa,UAAU;AAC7B,MAAI,cAAc,CAAC,cAAc,CAAC,YAAY;GAC5C,MAAMA,kBAAgB,aAAa,kBAAkB,UAAU,CAAC;GAChE,MAAM,SAAS,UAAU;GAEzB,MAAM,aACJ,sBAFgB,SAAS,GAAG,WAAW,GAAG,WAAW,eAEjB,sBAAsB;AAE5D,OAAI,WAuBF,QAAO;IACL,MAAMA;IACN;IACA,QAAQ,EAAE;IACV,MA1BgB;KAChB,GAAG,OAAO;KACV,GAAG,OAAO,iBAAiBA;KAC3B,cAAc,GAAG,OAAO,KAAK,gBAAgB;KAC7C,GAAG,OAAO,sBAAsB;KAChC,GAAG,OAAO;KACV,GAAG,OAAO,eAAeA,gBAAc;KACvC,GAAG,OAAO,WAAWA,gBAAc;KACnC,cACI,GAAG,OAAO,iBAAiB,KAAK,UAAU,YAAY,CAAC,KACvD;KACJ,GAAG,OAAO;KACV,GAAG,OAAO;KACV,GAAG,OAAO,cAAc,WAAW;KACnC,GAAG,OAAO;KACV,GAAG,OAAO;KACV,GAAG,OAAO;KACV,GAAG,OAAO;KACX,CACE,QAAQ,SAAS,SAAS,KAAK,CAC/B,KAAK,KAAK;IAOZ;;AAML,MAD6B,UAAU,2BACX,CAAC,YAAY;GACvC,MAAMA,kBAAgB,aAAa,kBAAkB,UAAU,CAAC;AAahE,UAAO;IACL,MAAMA;IACN;IACA,QAAQ,EAAE;IACV,MAfe;KACf,GAAG,OAAO;KACV,GAAG,OAAO,6BAA6BA;KACvC,cAAc,GAAG,OAAO,KAAK,gBAAgB;KAC7C,GAAG,OAAO;KACV,GAAG,OAAO;KACV,GAAG,OAAO,eAAeA,gBAAc;KACxC,CACE,QAAQ,SAAS,SAAS,KAAK,CAC/B,KAAK,KAAK;IAOZ;;AAGH,MAAI,CAAC,YAAY;GACf,MAAMA,kBAAgB,aAAa,kBAAkB,UAAU,CAAC;AAahE,UAAO;IACL,MAAMA;IACN;IACA,QAAQ,EAAE;IACV,MAhBqB;KACrB,GAAG,OAAO,eAAeA,gBAAc;KACvC,GAAG,OAAO,WAAWA,gBAAc;KACnC,cACI,GAAG,OAAO,iBAAiB,KAAK,UAAU,YAAY,CAAC,KACvD;KACJ,GAAG,OAAO;KACV,GAAG,OAAO;KACX,CACE,QAAQ,SAAS,SAAS,KAAK,CAC/B,KAAK,KAAK;IAOZ;;EAIH,MAAM,gBAAgB,aAAa,kBAAkB,UAAU,CAAC;AAChE,OAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAAQ,WAAW,EAAE;GAC/D,MAAM,aAAa,SAAS,SAAS,SAAS;AAC9C,UAAO,KACL,KAAK,aAAa,YAAY,UAAU,YAAY,cAAc,CACnE;;EAIH,MAAM,QAAkB,EAAE;AAG1B,OAAK,MAAM,SAAS,OAClB,KAAI,MAAM,aAAa;AACrB,SAAM,KAAK,MAAM,YAAY,KAAK;AAClC,SAAM,KAAK,GAAG;;AAKlB,QAAM,KAAK,GAAG,OAAO,eAAe,cAAc,wBAAwB;AAC1E,QAAM,KAAK,GAAG,OAAO,WAAW,cAAc,IAAI;AAClD,MAAI,YACF,OAAM,KAAK,GAAG,OAAO,iBAAiB,KAAK,UAAU,YAAY,CAAC,GAAG;AAEvE,QAAM,KAAK,GAAG,OAAO,aAAa;AAElC,OAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,aAAa,KAAK,wBAAwB,OAAO,SAAS,EAAE;AAClE,SAAM,KAAK,WAAW;;AAGxB,QAAM,KAAK,GAAG,OAAO,MAAM;AAC3B,QAAM,KAAK,GAAG,OAAO,KAAK;AAE1B,SAAO;GACL,MAAM;GACN;GACA;GACA,MAAM,MAAM,KAAK,KAAK;GACtB,SAAS,EAAE;GACZ;;CAGH,AAAQ,aACN,QACA,WACA,UACA,YACa;EACb,MAAM,OAAO,iBAAiB,QAAQ,UAAU;EAChD,MAAM,aAAa,cAAc,OAAO;EAExC,IAAI;EACJ,IAAI;AAEJ,MAAI,CAAC,YAAY,OAAO,EAAE;GACxB,MAAM,YAAY;GAClB,MAAM,UAAU,UAAU;AAC1B,OAAI,QACF,cAAa,QAAQ,IAAI,OAAO;AAIlC,OACE,UAAU,YAAY,YACtB,CAAC,cACD,UAAU,iBACV,CAAC,YACD;IACA,MAAM,cACH,aAAa,aAAa,MAAM,aAAa,UAAU;AAC1D,kBAAc,KAAK,2BAA2B,QAAQ,WAAW;AAEjE,SAAK,OAAO,YAAY;AACxB,SAAK,cAAc;;;AAIvB,SAAO;GACL,MAAM;GACN,MAAM;IACJ,GAAG;IACH,UAAU,CAAC,YAAY,KAAK;IAC5B,aAAa,CAAC,YAAY,OAAO,GAC3B,OAAmC,iBACrC;IACL;GACD;GACA;GACA;GACD;;CAGH,AAAQ,wBAAwB,OAAoB,QAAwB;EAC1E,MAAM,SAAS,KAAK,OAAO,OAAO;EAClC,MAAM,QAAkB,EAAE;EAG1B,MAAM,UADe,6BAA6B,KAAK,MAAM,KAAK,GACnC,MAAM,OAAO,IAAI,MAAM,KAAK;AAC3D,QAAM,KAAK,GAAG,SAAS,QAAQ,KAAK;AAEpC,MAAI,MAAM,YAAY;GACpB,MAAM,WAAW,aAAa,MAAM,KAAK,GAAG;AAC5C,SAAM,KACJ,GAAG,OAAO,wBAAwB,SAAS,MAAM,MAAM,WAAW,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,KACnG;aACQ,MAAM,WACf,OAAM,KAAK,GAAG,OAAO,UAAU,MAAM,WAAW,KAAK;WAC5C,MAAM,YACf,OAAM,KAAK,GAAG,OAAO,UAAU,MAAM,YAAY,KAAK,GAAG;WAChD,MAAM,KAAK,WAAW;GAC/B,MAAM,iBACJ,MAAM,KAAK,SAAS,WAChB,kCACA,MAAM,KAAK,SAAS,YAClB,oCACA;AACR,SAAM,KAAK,GAAG,OAAO,UAAU,eAAe,KAAK;aAC1C,MAAM,KAAK,YACpB,OAAM,KAAK,GAAG,OAAO,UAAU,MAAM,KAAK,KAAK,GAAG;MAElD,OAAM,KACJ,GAAG,OAAO,wEAAwE,MAAM,KAAK,OAC9F;AAGH,QAAM,KAAK,GAAG,OAAO,gBAAgB,MAAM,KAAK,SAAS,GAAG;AAE5D,MAAI,MAAM,KAAK,MACb,OAAM,KAAK,GAAG,OAAO,kBAAkB;AAGzC,QAAM,KAAK,GAAG,OAAO,IAAI;AAEzB,SAAO,MAAM,KAAK,KAAK;;;AAQ3B,IAAa,qBAAb,MAA2D;CACzD,SAAuB;CACvB;CAEA,YAAY,QAAoC;AAC9C,OAAK,SAAS;;CAGhB,cACE,QACA,MACA,SACe;EACf,MAAM,YAAY;EAClB,MAAM,aAAa,UAAU;AAGX,EAAC,UAAU;EAC7B,MAAM,cAAc,SAAS,eAAe,UAAU;EAEtD,MAAM,QAAkB,EAAE;AAE1B,MAAI,aAAa;AACf,SAAM,KAAK,MAAM;AACjB,SAAM,KAAK,MAAM,cAAc;AAC/B,SAAM,KAAK,MAAM;;EAInB,MAAM,aAAa,GAAG,KAAK;EAC3B,IAAI;AAEJ,MAAI,WACF,cAAa,KAAK,kBAAkB,UAAU;MAE9C,cAAa;AAGf,QAAM,KAAK,gBAAgB,WAAW,KAAK,WAAW,GAAG;AACzD,QAAM,KAAK,GAAG;AAGd,QAAM,KACJ,gBAAgB,KAAK,uBAAuB,WAAW,aAAa,KAAK,kBAAkB,KAAK,UAAU,YAAY,CAAC,MACxH;AACD,QAAM,KAAK,GAAG;AAGd,QAAM,KAAK,eAAe,KAAK,oBAAoB,WAAW,IAAI;AASlE,SAAO;GACL,MAAM,MAAM,KAAK,KAAK;GACtB,UAAU,YAAY,KAAK,GAAG;GAC9B,SAAS,KAAK,gBAAgB;GACxB;GACP;;CAGH,cACE,QACA,YACA,UACoB;EACpB,MAAM,YAAY;EAClB,MAAM,OAAO,UAAU;EACvB,MAAM,SAAS,UAAU;EACzB,MAAM,WAAW,UAAU;EAE3B,IAAI;AAEJ,MAAI,SAAS,YAAY,UAAU,cACjC,WAAU,KAAK,kBAAkB,UAAU;OACtC;AACL,aAAU,KAAK,aAAa,MAAM,OAAO;AAEzC,OAAI,UAAU,QAEZ,WAAU,WADS,UAAU,QACG,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC;AAGlE,OAAI,SAAS,SAAS;IACpB,MAAM,QAAQ,UAAU;AACxB,QAAI,MAEF,WAAU,WADQ,KAAK,cAAc,OAAO,QAAQ,KAAK,CAC1B,KAAK,QAAQ,eAAe,GAAG,CAAC;QAE/D,WAAU;;;AAMhB,MAAI,SAAS,UAAU;AACrB,OAAI,UAAU,iBAAiB,OAC7B,YAAW,QAAQ,UAAU,aAAa;AAC5C,OAAI,UAAU,iBAAiB,OAC7B,YAAW,QAAQ,UAAU,aAAa;AAC5C,OAAI,UAAU,eAAe,OAC3B,YAAW,WAAW,UAAU,WAAW;aACpC,SAAS,aAAa,SAAS,UAAU;AAClD,OAAI,UAAU,eAAe,OAC3B,YACE,UAAU,wBAAwB,OAC9B,OAAO,UAAU,WAAW,KAC5B,QAAQ,UAAU,WAAW;YAC1B,OAAO,UAAU,wBAAwB,SAClD,YAAW,OAAO,UAAU,oBAAoB;AAGlD,OAAI,UAAU,eAAe,OAC3B,YACE,UAAU,wBAAwB,OAC9B,OAAO,UAAU,WAAW,KAC5B,QAAQ,UAAU,WAAW;YAC1B,OAAO,UAAU,wBAAwB,SAClD,YAAW,OAAO,UAAU,oBAAoB;AAGlD,OAAI,UAAU,kBAAkB,OAC9B,YAAW,SAAS,UAAU,cAAc;aAErC,SAAS,SAAS;AAC3B,OAAI,UAAU,gBAAgB,OAC5B,YAAW,QAAQ,UAAU,YAAY;AAC3C,OAAI,UAAU,gBAAgB,OAC5B,YAAW,QAAQ,UAAU,YAAY;;AAG7C,MAAI,UAAU,eAAe,OAC3B,YAAW,YAAY,KAAK,UAAU,UAAU,WAAW,CAAC;AAG9D,MAAI,CAAC,YAAY,SACf,WAAU,GAAG,QAAQ;AAGvB,SAAO;GACL,MAAM;GACN,SAAS,QAAQ;GACjB,YAAY,CAAC,YAAY,QAAQ,SAAS;GAC1C,SAAS,SAAS;GACnB;;CAGH,iBAA2B;AACzB,SAAO,CACL,6BACA,4DACD;;CAGH,AAAQ,kBAAkB,WAA4C;EACpE,MAAM,WAAY,UAAU,eAA4B,EAAE;EAC1D,MAAM,aAAa,UAAU;EAC7B,MAAM,QAAkB,CAAC,aAAa;AAEtC,OAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAAQ,WAAW,EAAE;GAC/D,MAAM,aAAa,SAAS,SAAS,SAAS;GAC9C,MAAM,QAAQ,KAAK,cAAc,YAAY,UAAU,WAAW;GAElE,MAAM,WAAW,6BAA6B,KAAK,SAAS,GACxD,WACA,IAAI,SAAS;AAEjB,SAAM,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,GAAG;;AAG7C,QAAM,KAAK,KAAK;AAChB,SAAO,MAAM,KAAK,KAAK;;CAGzB,AAAQ,aAAa,MAAe,QAAyB;AAC3D,MAAI,WAAW,YAAa,QAAO;AACnC,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,WAAW,QAAS,QAAO;AAC/B,MAAI,WAAW,SAAS,WAAW,MAAO,QAAO;AACjD,MAAI,WAAW,OAAQ,QAAO;AAE9B,UAAQ,MAAR;GACE,KAAK,SACH,QAAO;GACT,KAAK,UACH,QAAO;GACT,KAAK,SACH,QAAO;GACT,KAAK,UACH,QAAO;GACT,KAAK,SACH,QAAO;GACT,KAAK,OACH,QAAO;GACT,QACE,QAAO;;;;AASf,IAAa,sBAAb,MAA4D;CAC1D,SAAuB;CACvB;CAEA,YAAY,QAAoC;AAC9C,OAAK,SAAS;;CAGhB,cACE,QACA,MACA,SACe;EACf,MAAM,YAAY;EAClB,MAAM,cAAc,SAAS,eAAe,UAAU;EAGtD,MAAM,aAAsC;GAC1C,SAAS;GACT,OAAO;GACP,GAAG;GACJ;AAED,MAAI,YACF,YAAW,iBAAiB;EAG9B,MAAM,QAAkB,EAAE;AAC1B,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,mBAAmB,OAAO;AACrC,MAAI,YACF,OAAM,KAAK,MAAM,cAAc;AAEjC,QAAM,KAAK,MAAM;EAEjB,MAAM,aAAa,GAAG,KAAK;AAC3B,QAAM,KACJ,gBAAgB,WAAW,KAAK,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC,YACrE;AACD,QAAM,KAAK,GAAG;AAGd,QAAM,KAAK,gBAAgB,KAAK,wBAAwB,WAAW,IAAI;AACvE,QAAM,KAAK,GAAG;AAKd,QAAM,KACJ,eAAe,KAAK,+DACrB;AAED,SAAO;GACL,MAAM,MAAM,KAAK,KAAK;GACtB,UAAU,YAAY,KAAK,GAAG;GAC9B,SAAS,KAAK,gBAAgB;GACxB;GACP;;CAGH,cACE,QACA,YACA,UACoB;EACpB,MAAM,YAAY;EAClB,MAAM,OAAO,UAAU;EACvB,MAAM,WAAW,UAAU;AAE3B,SAAO;GACL,MAAM,KAAK,UAAU,UAAU;GAC/B,SAAS,QAAQ;GACjB,YAAY,CAAC,YAAY,QAAQ,SAAS;GAC1C,SAAS,SAAS;GACnB;;CAGH,iBAA2B;AACzB,SAAO,CAAC,6DAA6D;;;AAQzE,IAAa,yBAAb,MAA+D;CAC7D,SAAuB;CACvB;CAEA,YAAY,QAAoC;AAC9C,OAAK,SAAS;;CAGhB,cACE,QACA,MACA,SACe;EACf,MAAM,YAAY;EAClB,MAAM,aAAa,UAAU;EAG7B,MAAM,WAAY,UAAU,eAA4B,EAAE;EAC1D,MAAM,cAAc,SAAS,eAAe,UAAU;EAEtD,MAAM,QAAkB,EAAE;AAE1B,MAAI,YACF,OAAM,KAAK,MAAM,YAAY,KAAK;AAGpC,QAAM,KAAK,QAAQ,KAAK,IAAI;AAE5B,MAAI,WACF,MAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAAQ,WAAW,EAAE;GAC/D,MAAM,aAAa,SAAS,SAAS,SAAS;GAC9C,MAAM,QAAQ,KAAK,cAAc,YAAY,UAAU,WAAW;GAClE,MAAM,aAAa,aAAa,MAAM;AACtC,SAAM,KAAK,KAAK,SAAS,IAAI,MAAM,UAAU,aAAa;;AAI9D,QAAM,KAAK,IAAI;EAGf,MAAM,MAAM,MAAM,KAAK,KAAK;EAC5B,MAAM,UAAoB,EAAE;AAC5B,UAAQ,KAAK,MAAM;AACnB,UAAQ,KAAK,+BAA+B,OAAO;AACnD,UAAQ,KAAK,MAAM;AACnB,UAAQ,KAAK,gBAAgB,KAAK,cAAc,IAAI,KAAK;AACzD,UAAQ,KAAK,GAAG;AAChB,UAAQ,KACN,gBAAgB,KAAK,2BAA2B,KAAK,YAAY,KAAK,KACvE;AAED,SAAO;GACL,MAAM,QAAQ,KAAK,KAAK;GACxB,UAAU,YAAY,KAAK,GAAG;GAC9B,SAAS,KAAK,gBAAgB;GACxB;GACP;;CAGH,cACE,QACA,YACA,UACoB;EACpB,MAAM,YAAY;EAClB,MAAM,OAAO,UAAU;EACvB,MAAM,SAAS,UAAU;EACzB,MAAM,WAAW,UAAU;EAE3B,MAAM,UAAU,KAAK,iBAAiB,MAAM,OAAO;AAEnD,SAAO;GACL,MAAM;GACN,SAAS;GACT,YAAY,CAAC,YAAY,QAAQ,SAAS;GAC1C,SAAS,SAAS;GACnB;;CAGH,iBAA2B;AACzB,SAAO,CAAC,gEAAgE;;CAG1E,AAAQ,iBAAiB,MAAe,QAAyB;AAC/D,MAAI,WAAW,YAAa,QAAO;AACnC,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,WAAW,QAAS,QAAO;AAC/B,MAAI,WAAW,SAAS,WAAW,MAAO,QAAO;AACjD,MAAI,WAAW,OAAQ,QAAO;AAE9B,UAAQ,MAAR;GACE,KAAK,SACH,QAAO;GACT,KAAK,UACH,QAAO;GACT,KAAK,SACH,QAAO;GACT,KAAK,UACH,QAAO;GACT,KAAK,SACH,QAAO;GACT,KAAK,QACH,QAAO;GACT,QACE,QAAO"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/lib.contracts-transformers",
3
- "version": "0.0.0-canary-20260113173657",
3
+ "version": "0.0.0-canary-20260119222405",
4
4
  "description": "Contract format transformations: import/export between ContractSpec and external formats (OpenAPI, AsyncAPI, etc.)",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -25,16 +25,16 @@
25
25
  "test": "bun test"
26
26
  },
27
27
  "dependencies": {
28
- "@contractspec/lib.contracts": "0.0.0-canary-20260113173657",
29
- "@contractspec/lib.schema": "0.0.0-canary-20260113173657",
28
+ "@contractspec/lib.contracts": "0.0.0-canary-20260119222405",
29
+ "@contractspec/lib.schema": "1.48.0",
30
30
  "compare-versions": "^6.1.1",
31
31
  "openapi-types": "^12.1.3",
32
32
  "yaml": "^2.7.1",
33
33
  "zod": "^4.3.5"
34
34
  },
35
35
  "devDependencies": {
36
- "@contractspec/tool.tsdown": "0.0.0-canary-20260113173657",
37
- "@contractspec/tool.typescript": "0.0.0-canary-20260113173657",
36
+ "@contractspec/tool.tsdown": "1.48.0",
37
+ "@contractspec/tool.typescript": "1.48.0",
38
38
  "tsdown": "^0.19.0",
39
39
  "typescript": "^5.9.3"
40
40
  },