@contractkit/openapi-to-ck 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,12 +7,12 @@ $ tsup src/index.ts src/plugin.ts --format esm --sourcemap --dts && tsc --emitDe
7
7
  ESM Build start
8
8
  ESM dist/index.js 498.00 B
9
9
  ESM dist/plugin.js 2.51 KB
10
- ESM dist/chunk-76CPOLZK.js 51.27 KB
10
+ ESM dist/chunk-JPI3AQ7V.js 51.50 KB
11
11
  ESM dist/index.js.map 71.00 B
12
12
  ESM dist/plugin.js.map 4.95 KB
13
- ESM dist/chunk-76CPOLZK.js.map 119.89 KB
14
- ESM ⚡️ Build success in 277ms
13
+ ESM dist/chunk-JPI3AQ7V.js.map 120.62 KB
14
+ ESM ⚡️ Build success in 200ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 8653ms
16
+ DTS ⚡️ Build success in 8418ms
17
17
  DTS dist/index.d.ts 9.00 KB
18
18
  DTS dist/plugin.d.ts 128.00 B
@@ -3,32 +3,32 @@ $ vitest run --coverage
3
3
   RUN  v4.1.5 /home/runner/work/ContractKit/ContractKit/packages/openapi-to-ck
4
4
  Coverage enabled with v8
5
5
 
6
- ✓ tests/schema-to-ast.test.ts (36 tests) 73ms
6
+ ✓ tests/schema-to-ast.test.ts (36 tests) 104ms
7
7
  ✓ tests/normalize.test.ts (6 tests) 64ms
8
- ✓ tests/tag-splitter.test.ts (5 tests) 85ms
9
- ✓ tests/ast-to-ck.test.ts (45 tests) 200ms
10
- ✓ tests/convert.test.ts (16 tests) 170ms
11
- ✓ tests/circular-refs.test.ts (8 tests) 30ms
8
+ ✓ tests/ast-to-ck.test.ts (45 tests) 180ms
9
+ ✓ tests/tag-splitter.test.ts (5 tests) 60ms
10
+ ✓ tests/convert.test.ts (17 tests) 155ms
11
+ ✓ tests/circular-refs.test.ts (8 tests) 12ms
12
12
 
13
13
   Test Files  6 passed (6)
14
-  Tests  116 passed (116)
15
-  Start at  15:07:02
16
-  Duration  6.83s (transform 3.49s, setup 0ms, import 10.45s, tests 621ms, environment 25ms)
14
+  Tests  117 passed (117)
15
+  Start at  16:09:44
16
+  Duration  6.07s (transform 3.31s, setup 0ms, import 9.03s, tests 574ms, environment 4ms)
17
17
 
18
18
   % Coverage report from v8
19
19
  -------------------|---------|----------|---------|---------|-------------------------------------------------------------
20
20
  File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
21
21
  -------------------|---------|----------|---------|---------|-------------------------------------------------------------
22
- All files | 81.44 | 71.01 | 94.78 | 83.92 |
23
- src | 81.24 | 71.31 | 93.61 | 83.57 |
24
- ast-to-ck.ts | 91.73 | 84.26 | 100 | 92.89 | 117-127,204,305,360,393-394,404,465
22
+ All files | 81.5 | 71.07 | 94.82 | 84.21 |
23
+ src | 81.27 | 71.27 | 93.68 | 83.86 |
24
+ ast-to-ck.ts | 91.73 | 83.93 | 100 | 92.89 | 117-127,204,305,360,393-394,404,465
25
25
  circular-refs.ts | 100 | 90 | 100 | 100 | 20-23
26
26
  convert.ts | 77.19 | 87.5 | 80 | 77.77 | 83-98,112-117
27
27
  normalize.ts | 62.96 | 56.6 | 80 | 63.33 | 79,121-163,237-255,270-271,280-309,346,350,358
28
- paths-to-ast.ts | 85.03 | 65.71 | 100 | 89.56 | 100,125,130,140-141,149,192,206,247,277,283,320
28
+ paths-to-ast.ts | 85.07 | 66.99 | 100 | 91.45 | 101,126,131,141-142,150,193,207,248,323
29
29
  schema-to-ast.ts | 84.69 | 75 | 95.65 | 87.65 | 128-129,151,159,173,196-197,205-206,311-314,353-360,396-404
30
- tag-splitter.ts | 70 | 57.14 | 81.81 | 76.47 | 63-71,137-138,141-146,162-163,171-178
30
+ tag-splitter.ts | 70 | 55.88 | 81.81 | 76.47 | 63-71,137-138,141-146,162-163,171-178
31
31
  warnings.ts | 100 | 100 | 100 | 100 |
32
- tests | 86.48 | 60 | 100 | 93.33 |
33
- helpers.ts | 86.48 | 60 | 100 | 93.33 | 138-139
32
+ tests | 86.84 | 65.38 | 100 | 93.54 |
33
+ helpers.ts | 86.84 | 65.38 | 100 | 93.54 | 139-140
34
34
  -------------------|---------|----------|---------|---------|-------------------------------------------------------------
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @contractkit/openapi-to-ck
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 85d7566: Let an operation emit more than one status, and a status serve more than one content type.
8
+
9
+ A status code could previously declare only one mime — the parser warned `Duplicate response body` and dropped the rest — and the generated router pinned both `ctx.status` and `ctx.type` to whichever response happened to be listed first with a body. An endpoint serving several formats had to declare one lying mime and let browsers sniff, and a service had no way to say which status it produced.
10
+
11
+ A status now holds every declared `mime: Type` line (`OpResponseNode.bodies`). When there is more than one, the service picks at runtime and the router sets `ctx.type` from the returned `contentType`. When an operation produces more than one status, the service returns a union discriminated on `status` and the handler switches on it, so each status writes only its own headers, mime and body. Both SDKs mirror the router: the TypeScript and Python clients return a matching union, report which mime came back, and pass the non-2xx statuses they expect to the shared fetch so a declared `304` no longer surfaces as an error. `SdkError` now takes a body type parameter, and each operation exports a `…ErrorBody` alias for the statuses that stay on the throw path.
12
+
13
+ Which statuses the service produces is derived from the declaration: **a status is emitted if it has a block, or is 2xx.** An empty block (`304: {}`) says the service returns that status carrying nothing; a bare `304:` says it is documented and something else produces it. `404(documented): { … }` is the one modifier, forcing a block-carrying status back out.
14
+
15
+ Two long-standing bugs in the same area go with it. The formatter deleted any comment written inside a `response` block — above a status code, above a mime line, above a `headers:` block, or before a closing brace — so `pnpm format` silently threw away the notes explaining why a contract looks the way it does; all four positions now round-trip. And the generated router declared a `_ZodBinary` helper for a binary _response_ body, which is a plain `Buffer` annotation with no schema behind it, leaving an unused const that tripped `noUnusedLocals` downstream; helpers are now chosen from the code that was actually generated, the same way imports already were.
16
+
17
+ **If you are already on a pre-release version, two things change under you.** A contract that declares a body on an error status — `404: { application/json: Problem }` alongside a `200` — now returns it from the service instead of throwing, and the SDK return type becomes a union; add `(documented)` to that status to keep the previous behaviour. Contracts whose error statuses are bodyless (`400:`, `404:`) are unaffected. Anything reading the AST directly should move from `OpResponseNode.contentType`/`bodyType` to `bodies`, which replaces them.
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [85d7566]
22
+ - Updated dependencies [90d19ee]
23
+ - @contractkit/core@0.25.0
24
+
3
25
  ## 0.9.3
4
26
 
5
27
  ### Patch Changes
@@ -1036,31 +1036,31 @@ function requestBodyToNode(reqBody, operationName, schemaCtx, ctx) {
1036
1036
  __name(requestBodyToNode, "requestBodyToNode");
1037
1037
  function responseToNode(statusCode, resp, operationName, schemaCtx, ctx) {
1038
1038
  const headers = convertResponseHeaders(resp.headers, schemaCtx);
1039
- if (!resp.content) {
1040
- return headers ? {
1041
- statusCode,
1042
- headers
1043
- } : {
1044
- statusCode
1045
- };
1046
- }
1047
- const [contentType, mediaType] = Object.entries(resp.content)[0] ?? [];
1048
- if (!contentType || !mediaType?.schema) {
1049
- return headers ? {
1050
- statusCode,
1051
- headers
1052
- } : {
1053
- statusCode
1054
- };
1055
- }
1056
- const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Response${statusCode}`, schemaCtx);
1057
- if (model) {
1058
- ctx.extractedModels.push(model);
1039
+ const empty = /* @__PURE__ */ __name(() => ({
1040
+ statusCode,
1041
+ bodies: [],
1042
+ ...headers ? {
1043
+ headers,
1044
+ hasBlock: true
1045
+ } : {}
1046
+ }), "empty");
1047
+ if (!resp.content) return empty();
1048
+ const bodies = [];
1049
+ for (const [contentType, mediaType] of Object.entries(resp.content)) {
1050
+ if (!mediaType?.schema) continue;
1051
+ const suffix = bodies.length === 0 ? "" : toPascalCase(contentType.replace(/[^a-z0-9]+/gi, " "));
1052
+ const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Response${statusCode}${suffix}`, schemaCtx);
1053
+ if (model) ctx.extractedModels.push(model);
1054
+ bodies.push({
1055
+ contentType,
1056
+ bodyType: typeNode
1057
+ });
1059
1058
  }
1059
+ if (bodies.length === 0) return empty();
1060
1060
  return {
1061
1061
  statusCode,
1062
- contentType,
1063
- bodyType: typeNode,
1062
+ bodies,
1063
+ hasBlock: true,
1064
1064
  ...headers ? {
1065
1065
  headers
1066
1066
  } : {}
@@ -1218,7 +1218,7 @@ function collectRouteRefs(route, refs) {
1218
1218
  for (const body of op.request.bodies) collectTypeRefs(body.bodyType, refs);
1219
1219
  }
1220
1220
  for (const resp of op.responses) {
1221
- if (resp.bodyType) collectTypeRefs(resp.bodyType, refs);
1221
+ for (const body of resp.bodies) collectTypeRefs(body.bodyType, refs);
1222
1222
  }
1223
1223
  }
1224
1224
  }
@@ -1583,12 +1583,12 @@ function serializeResponses(lines, responses, depth) {
1583
1583
  const indent = INDENT.repeat(depth);
1584
1584
  lines.push(`${indent}response: {`);
1585
1585
  for (const resp of responses) {
1586
- const hasBody = resp.bodyType && resp.contentType;
1586
+ const bodies = resp.bodies;
1587
1587
  const hasHeaders = resp.headers && resp.headers.length > 0;
1588
- if (hasBody || hasHeaders) {
1588
+ if (bodies.length > 0 || hasHeaders) {
1589
1589
  lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}: {`);
1590
- if (hasBody) {
1591
- lines.push(`${INDENT.repeat(depth + 2)}${resp.contentType}: ${serializeType(resp.bodyType)}`);
1590
+ for (const body of bodies) {
1591
+ lines.push(`${INDENT.repeat(depth + 2)}${body.contentType}: ${serializeType(body.bodyType)}`);
1592
1592
  }
1593
1593
  if (hasHeaders) {
1594
1594
  lines.push(`${INDENT.repeat(depth + 2)}headers: {`);
@@ -1784,4 +1784,4 @@ export {
1784
1784
  serializeType,
1785
1785
  convertOpenApiToCk
1786
1786
  };
1787
- //# sourceMappingURL=chunk-76CPOLZK.js.map
1787
+ //# sourceMappingURL=chunk-JPI3AQ7V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/normalize.ts","../src/circular-refs.ts","../src/schema-to-ast.ts","../src/paths-to-ast.ts","../src/tag-splitter.ts","../src/ast-to-ck.ts","../src/convert.ts","../src/warnings.ts"],"sourcesContent":["import type { NormalizedDocument } from './types.js';\nimport type { WarningCollector } from './warnings.js';\n\n/**\n * Detects the OpenAPI version from a parsed document and normalizes it to a\n * 3.1-like shape. Swagger 2.0 and OpenAPI 3.0 documents are transformed\n * so that downstream code only needs to handle one schema dialect.\n *\n * Uses @scalar/openapi-parser's `upgrade()` for the heavy lifting when\n * available, with manual fallbacks for edge cases.\n */\nexport function normalize(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const version = detectVersion(doc);\n\n if (version === '2.0') {\n return normalizeSwagger2(doc, warnings);\n }\n if (version === '3.0') {\n return normalizeOas30(doc as unknown as NormalizedDocument, warnings);\n }\n // 3.1+ — already in target shape\n return doc as unknown as NormalizedDocument;\n}\n\nfunction detectVersion(doc: Record<string, unknown>): '2.0' | '3.0' | '3.1' {\n if (typeof doc.swagger === 'string' && doc.swagger.startsWith('2')) return '2.0';\n if (typeof doc.openapi === 'string') {\n if (doc.openapi.startsWith('3.0')) return '3.0';\n }\n return '3.1';\n}\n\n// ─── Swagger 2.0 → 3.1 ───────────────────────────────────────────────────\n\nfunction normalizeSwagger2(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const info = (doc.info as Record<string, unknown>) ?? { title: 'Untitled', version: '0.0.0' };\n const basePath = (doc.basePath as string) ?? '';\n const schemes = (doc.schemes as string[]) ?? ['https'];\n const host = (doc.host as string) ?? 'localhost';\n const globalConsumes = (doc.consumes as string[]) ?? ['application/json'];\n const globalProduces = (doc.produces as string[]) ?? ['application/json'];\n\n const result: NormalizedDocument = {\n openapi: '3.1.0',\n info: {\n title: (info.title as string) ?? 'Untitled',\n version: (info.version as string) ?? '0.0.0',\n description: info.description as string | undefined,\n },\n servers: [{ url: `${schemes[0]}://${host}${basePath}` }],\n paths: {},\n components: {\n schemas: {},\n securitySchemes: {},\n },\n tags: (doc.tags as NormalizedDocument['tags']) ?? [],\n };\n\n // Convert definitions → components/schemas\n const definitions = (doc.definitions as Record<string, unknown>) ?? {};\n for (const [name, schema] of Object.entries(definitions)) {\n result.components!.schemas![name] = normalizeNullable30(schema as Record<string, unknown>);\n }\n\n // Convert securityDefinitions → components/securitySchemes\n const secDefs = (doc.securityDefinitions as Record<string, unknown>) ?? {};\n for (const [name, scheme] of Object.entries(secDefs)) {\n result.components!.securitySchemes![name] = convertSecurityScheme2(scheme as Record<string, unknown>);\n }\n\n // Convert paths\n const paths = (doc.paths as Record<string, Record<string, unknown>>) ?? {};\n for (const [path, pathItem] of Object.entries(paths)) {\n result.paths![path] = normalizePathItem2(pathItem, globalConsumes, globalProduces, warnings);\n }\n\n // Global security\n if (doc.security) {\n result.security = doc.security as Record<string, string[]>[];\n }\n\n return result;\n}\n\nfunction normalizePathItem2(\n pathItem: Record<string, unknown>,\n globalConsumes: string[],\n globalProduces: string[],\n warnings: WarningCollector,\n): Record<string, unknown> {\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];\n const normalized: Record<string, unknown> = {};\n\n // Path-level parameters\n const pathParams = (pathItem.parameters as unknown[]) ?? [];\n\n for (const method of methods) {\n const op = pathItem[method] as Record<string, unknown> | undefined;\n if (!op) continue;\n\n const opConsumes = (op.consumes as string[]) ?? globalConsumes;\n const opProduces = (op.produces as string[]) ?? globalProduces;\n const params = [...pathParams, ...((op.parameters as unknown[]) ?? [])];\n\n // Separate body params from others\n const nonBodyParams: unknown[] = [];\n let requestBody: Record<string, unknown> | undefined;\n\n for (const param of params as Record<string, unknown>[]) {\n if (param.in === 'body') {\n const contentType = opConsumes[0] ?? 'application/json';\n requestBody = {\n description: param.description,\n required: param.required ?? true,\n content: {\n [contentType]: {\n schema: normalizeNullable30((param.schema as Record<string, unknown>) ?? {}),\n },\n },\n };\n } else if (param.in === 'formData') {\n warnings.info(`#/paths/${encodePathSegment(method)}`, 'formData parameters converted to multipart/form-data requestBody');\n // Collect formData params into a schema\n if (!requestBody) {\n requestBody = {\n content: {\n 'multipart/form-data': {\n schema: { type: 'object', properties: {}, required: [] as string[] },\n },\n },\n };\n }\n const formSchema = (requestBody.content as Record<string, Record<string, unknown>>)['multipart/form-data']!.schema as Record<\n string,\n unknown\n >;\n const props = formSchema.properties as Record<string, unknown>;\n props[param.name as string] = normalizeNullable30(param as Record<string, unknown>);\n if (param.required) {\n (formSchema.required as string[]).push(param.name as string);\n }\n } else {\n // Convert param schema\n const normalizedParam = { ...param };\n if (param.type) {\n normalizedParam.schema = normalizeNullable30({\n type: param.type,\n format: param.format,\n enum: param.enum,\n items: param.items,\n default: param.default,\n minimum: param.minimum,\n maximum: param.maximum,\n minLength: param.minLength,\n maxLength: param.maxLength,\n pattern: param.pattern,\n } as Record<string, unknown>);\n delete normalizedParam.type;\n delete normalizedParam.format;\n delete normalizedParam.enum;\n delete normalizedParam.items;\n }\n nonBodyParams.push(normalizedParam);\n }\n }\n\n // Convert responses\n const responses: Record<string, unknown> = {};\n const opResponses = (op.responses as Record<string, Record<string, unknown>>) ?? {};\n for (const [code, resp] of Object.entries(opResponses)) {\n const contentType = opProduces[0] ?? 'application/json';\n const headers = convertResponseHeaders2(resp.headers as Record<string, Record<string, unknown>> | undefined);\n const responseEntry: Record<string, unknown> = {\n description: resp.description ?? '',\n };\n if (resp.schema) {\n responseEntry.content = {\n [contentType]: {\n schema: normalizeNullable30(resp.schema as Record<string, unknown>),\n },\n };\n }\n if (headers) {\n responseEntry.headers = headers;\n }\n responses[code] = responseEntry;\n }\n\n normalized[method] = {\n operationId: op.operationId,\n summary: op.summary,\n description: op.description,\n tags: op.tags,\n parameters: nonBodyParams.length > 0 ? nonBodyParams : undefined,\n requestBody,\n responses,\n security: op.security,\n deprecated: op.deprecated,\n };\n }\n\n return normalized;\n}\n\n/**\n * Convert Swagger 2.0 response headers to a 3.x-shaped Header Object map.\n * 2.0 stores `type`/`format`/`items` inline on the header; 3.x wraps the same fields under `schema`.\n */\nfunction convertResponseHeaders2(\n headers: Record<string, Record<string, unknown>> | undefined,\n): Record<string, Record<string, unknown>> | undefined {\n if (!headers) return undefined;\n const out: Record<string, Record<string, unknown>> = {};\n for (const [name, header] of Object.entries(headers)) {\n if (!header || typeof header !== 'object') continue;\n const { description, type, format, items, ...rest } = header;\n const schema: Record<string, unknown> = { ...rest };\n if (type !== undefined) schema.type = type;\n if (format !== undefined) schema.format = format;\n if (items !== undefined) schema.items = items;\n const normalized: Record<string, unknown> = {};\n if (description !== undefined) normalized.description = description;\n if (Object.keys(schema).length > 0) normalized.schema = normalizeNullable30(schema);\n out[name] = normalized;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction convertSecurityScheme2(scheme: Record<string, unknown>): unknown {\n const type = scheme.type as string;\n if (type === 'basic') {\n return { type: 'http', scheme: 'basic' };\n }\n if (type === 'apiKey') {\n return { type: 'apiKey', name: scheme.name, in: scheme.in };\n }\n if (type === 'oauth2') {\n const flow = scheme.flow as string;\n const flows: Record<string, unknown> = {};\n if (flow === 'implicit') {\n flows.implicit = { authorizationUrl: scheme.authorizationUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'password') {\n flows.password = { tokenUrl: scheme.tokenUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'application') {\n flows.clientCredentials = { tokenUrl: scheme.tokenUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'accessCode') {\n flows.authorizationCode = {\n authorizationUrl: scheme.authorizationUrl,\n tokenUrl: scheme.tokenUrl,\n scopes: scheme.scopes ?? {},\n };\n }\n return { type: 'oauth2', flows };\n }\n return scheme;\n}\n\n// ─── OpenAPI 3.0 → 3.1 ───────────────────────────────────────────────────\n\nfunction normalizeOas30(doc: NormalizedDocument, _warnings: WarningCollector): NormalizedDocument {\n // Walk all schemas and convert `nullable: true` to type arrays\n if (doc.components?.schemas) {\n for (const [name, schema] of Object.entries(doc.components.schemas)) {\n doc.components.schemas[name] = normalizeNullable30(schema as Record<string, unknown>);\n }\n }\n\n // Walk paths and normalize inline schemas\n if (doc.paths) {\n for (const pathItem of Object.values(doc.paths)) {\n normalizePathItemSchemas(pathItem as Record<string, unknown>);\n }\n }\n\n doc.openapi = '3.1.0';\n return doc;\n}\n\nfunction normalizePathItemSchemas(pathItem: Record<string, unknown>): void {\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];\n for (const method of methods) {\n const op = pathItem[method] as Record<string, unknown> | undefined;\n if (!op) continue;\n\n // Normalize parameter schemas\n const params = (op.parameters as Record<string, unknown>[]) ?? [];\n for (const param of params) {\n if (param.schema) {\n param.schema = normalizeNullable30(param.schema as Record<string, unknown>);\n }\n }\n\n // Normalize requestBody schemas\n const reqBody = op.requestBody as Record<string, unknown> | undefined;\n if (reqBody?.content) {\n for (const mediaType of Object.values(reqBody.content as Record<string, Record<string, unknown>>)) {\n if (mediaType.schema) {\n mediaType.schema = normalizeNullable30(mediaType.schema as Record<string, unknown>);\n }\n }\n }\n\n // Normalize response schemas\n const responses = (op.responses as Record<string, Record<string, unknown>>) ?? {};\n for (const resp of Object.values(responses)) {\n if (resp.content) {\n for (const mediaType of Object.values(resp.content as Record<string, Record<string, unknown>>)) {\n if (mediaType.schema) {\n mediaType.schema = normalizeNullable30(mediaType.schema as Record<string, unknown>);\n }\n }\n }\n }\n }\n}\n\n/**\n * Recursively converts OAS 3.0 `nullable: true` to OAS 3.1 `type: [T, \"null\"]`.\n * Also normalizes nested schemas (properties, items, allOf, etc.).\n */\nfunction normalizeNullable30(schema: Record<string, unknown>): Record<string, unknown> {\n if (!schema || typeof schema !== 'object') return schema;\n\n const result = { ...schema };\n\n // Convert nullable: true → type array with null\n if (result.nullable === true && typeof result.type === 'string') {\n result.type = [result.type, 'null'];\n delete result.nullable;\n }\n\n // Convert $ref alongside other properties (OAS 3.0 $ref with siblings was invalid,\n // but OAS 3.1 allows it — no conversion needed, just keep walking)\n\n // Recurse into nested schemas\n if (result.properties && typeof result.properties === 'object') {\n const props = result.properties as Record<string, Record<string, unknown>>;\n for (const [key, val] of Object.entries(props)) {\n props[key] = normalizeNullable30(val);\n }\n }\n if (result.items && typeof result.items === 'object' && !Array.isArray(result.items)) {\n result.items = normalizeNullable30(result.items as Record<string, unknown>);\n }\n if (result.additionalProperties && typeof result.additionalProperties === 'object') {\n result.additionalProperties = normalizeNullable30(result.additionalProperties as Record<string, unknown>);\n }\n for (const combiner of ['allOf', 'oneOf', 'anyOf'] as const) {\n if (Array.isArray(result[combiner])) {\n result[combiner] = (result[combiner] as Record<string, unknown>[]).map(normalizeNullable30);\n }\n }\n\n return result;\n}\n\nfunction encodePathSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n","/**\n * Detects circular $ref chains in OpenAPI schema definitions.\n * Returns the set of schema names that participate in cycles.\n * These should be wrapped in `lazy()` in the output .ck.\n */\nexport function detectCircularRefs(schemas: Record<string, unknown>): Set<string> {\n const circular = new Set<string>();\n const visiting = new Set<string>(); // current DFS path\n const visited = new Set<string>(); // fully explored\n\n function visit(name: string): void {\n if (visited.has(name)) return;\n if (visiting.has(name)) {\n circular.add(name);\n return;\n }\n\n visiting.add(name);\n const schema = schemas[name];\n if (schema && typeof schema === 'object') {\n for (const ref of collectRefs(schema as Record<string, unknown>)) {\n const refName = extractRefName(ref);\n if (refName && schemas[refName]) {\n visit(refName);\n }\n }\n }\n visiting.delete(name);\n visited.add(name);\n }\n\n for (const name of Object.keys(schemas)) {\n visit(name);\n }\n\n return circular;\n}\n\n/**\n * Recursively collects all $ref strings from a schema object.\n */\nfunction collectRefs(obj: Record<string, unknown>): string[] {\n const refs: string[] = [];\n\n function walk(val: unknown): void {\n if (!val || typeof val !== 'object') return;\n if (Array.isArray(val)) {\n for (const item of val) walk(item);\n return;\n }\n const record = val as Record<string, unknown>;\n if (typeof record.$ref === 'string') {\n refs.push(record.$ref);\n }\n for (const v of Object.values(record)) {\n walk(v);\n }\n }\n\n walk(obj);\n return refs;\n}\n\n/**\n * Extracts the schema name from a $ref like \"#/components/schemas/Foo\"\n * or \"#/definitions/Foo\" (Swagger 2.0 after normalization still uses components).\n */\nexport function extractRefName(ref: string): string | undefined {\n const match = ref.match(/^#\\/(?:components\\/schemas|definitions)\\/(.+)$/);\n return match?.[1];\n}\n","import type { ContractTypeNode, ScalarTypeNode, ModelNode, FieldNode, SourceLocation } from '@contractkit/core';\nimport type { NormalizedSchema } from './types.js';\nimport { extractRefName } from './circular-refs.js';\nimport type { WarningCollector } from './warnings.js';\n\n// ─── Conversion Context ───────────────────────────────────────────────────\n\nexport interface SchemaContext {\n /** Schema names involved in circular references — use lazy() for these. */\n circularRefs: Set<string>;\n /** Warning collector for unsupported features. */\n warnings: WarningCollector;\n /** Current JSON pointer path (for warnings). */\n path: string;\n /** Whether to include descriptions. */\n includeComments: boolean;\n /** All named schemas (for inline extraction). */\n namedSchemas: Record<string, NormalizedSchema>;\n /** Extracted inline models (accumulated during conversion). */\n extractedModels: ModelNode[];\n /** Counter for generating unique names for inline models. */\n inlineCounter: number;\n}\n\nconst LOC: SourceLocation = { file: '', line: 0 };\n\n// ─── Format → Scalar Name Mapping ────────────────────────────────────────\n\nconst FORMAT_TO_SCALAR: Record<string, ScalarTypeNode['name']> = {\n email: 'email',\n uri: 'url',\n url: 'url',\n uuid: 'uuid',\n date: 'date',\n 'date-time': 'datetime',\n time: 'time',\n binary: 'binary',\n int64: 'bigint',\n};\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\n/**\n * Convert all named schemas in components/schemas to ModelNodes.\n */\nexport function schemasToModels(schemas: Record<string, NormalizedSchema>, ctx: SchemaContext): ModelNode[] {\n const models: ModelNode[] = [];\n\n for (const [name, schema] of Object.entries(schemas)) {\n const modelCtx = { ...ctx, path: `#/components/schemas/${name}` };\n const model = schemaToModel(name, schema, modelCtx);\n if (model) models.push(model);\n }\n\n // Append any inline models extracted during conversion\n models.push(...ctx.extractedModels);\n\n return models;\n}\n\n/**\n * Convert a named schema to a ModelNode.\n */\nfunction schemaToModel(name: string, schema: NormalizedSchema, ctx: SchemaContext): ModelNode | null {\n warnUnsupported(schema, ctx);\n\n const description = ctx.includeComments ? schema.description : undefined;\n\n // allOf with exactly 2 members, one being a $ref → inheritance\n if (schema.allOf && schema.allOf.length === 2) {\n const [first, second] = schema.allOf;\n const refMember = first?.$ref ? first : second?.$ref ? second : null;\n const objectMember = first?.$ref ? second : first;\n\n if (refMember?.$ref && objectMember?.properties) {\n const baseName = extractRefName(refMember.$ref);\n if (baseName) {\n const fields = schemaPropertiesToFields(objectMember, ctx);\n return {\n kind: 'model',\n name,\n bases: [baseName],\n fields,\n description,\n loc: LOC,\n };\n }\n }\n }\n\n // Object with properties → struct\n if (schema.properties || (schema.type === 'object' && !schema.additionalProperties)) {\n const fields = schemaPropertiesToFields(schema, ctx);\n return {\n kind: 'model',\n name,\n fields,\n description,\n loc: LOC,\n };\n }\n\n // Otherwise → type alias\n const typeNode = schemaToTypeNode(schema, ctx);\n return {\n kind: 'model',\n name,\n fields: [],\n type: typeNode,\n description,\n loc: LOC,\n };\n}\n\n/**\n * Convert an OpenAPI schema to a ContractTypeNode.\n */\nexport function schemaToTypeNode(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // $ref\n if (schema.$ref) {\n const refName = extractRefName(schema.$ref);\n if (refName) {\n if (ctx.circularRefs.has(refName)) {\n return { kind: 'lazy', inner: { kind: 'ref', name: refName } };\n }\n return { kind: 'ref', name: refName };\n }\n ctx.warnings.warn(ctx.path, `Unresolvable $ref: ${schema.$ref}`);\n return { kind: 'scalar', name: 'unknown' };\n }\n\n // const\n if (schema.const !== undefined) {\n return { kind: 'literal', value: schema.const as string | number | boolean };\n }\n\n // enum\n if (schema.enum) {\n return { kind: 'enum', values: schema.enum.map(String) };\n }\n\n // oneOf / anyOf → union (or discriminatedUnion when discriminator.propertyName is set)\n if (schema.oneOf && schema.oneOf.length > 0) {\n if (schema.discriminator?.propertyName) {\n return toDiscriminatedUnion(schema.oneOf, schema.discriminator.propertyName, ctx);\n }\n return toUnion(schema.oneOf, ctx);\n }\n if (schema.anyOf && schema.anyOf.length > 0) {\n if (schema.discriminator?.propertyName) {\n return toDiscriminatedUnion(schema.anyOf, schema.discriminator.propertyName, ctx);\n }\n return toUnion(schema.anyOf, ctx);\n }\n\n // allOf → intersection\n if (schema.allOf && schema.allOf.length > 0) {\n if (schema.allOf.length === 1) {\n return schemaToTypeNode(schema.allOf[0]!, ctx);\n }\n return {\n kind: 'intersection',\n members: schema.allOf.map(s => schemaToTypeNode(s, ctx)),\n };\n }\n\n // Handle nullable type arrays: [string, null] → nullable\n const types = normalizeTypeField(schema);\n\n if (types === null) {\n // No type information at all\n if (schema.properties) {\n return schemaToInlineObject(schema, ctx);\n }\n return { kind: 'scalar', name: 'unknown' };\n }\n\n const { baseType, nullable } = types;\n\n let typeNode: ContractTypeNode;\n\n switch (baseType) {\n case 'string':\n typeNode = stringSchemaToType(schema);\n break;\n case 'integer':\n typeNode = integerSchemaToType(schema);\n break;\n case 'number':\n typeNode = numberSchemaToType(schema);\n break;\n case 'boolean':\n typeNode = { kind: 'scalar', name: 'boolean' };\n break;\n case 'null':\n typeNode = { kind: 'scalar', name: 'null' };\n break;\n case 'array':\n typeNode = arraySchemaToType(schema, ctx);\n break;\n case 'object':\n typeNode = objectSchemaToType(schema, ctx);\n break;\n default:\n ctx.warnings.warn(ctx.path, `Unknown type: ${baseType}`);\n typeNode = { kind: 'scalar', name: 'unknown' };\n }\n\n if (nullable) {\n return { kind: 'union', members: [typeNode, { kind: 'scalar', name: 'null' }] };\n }\n\n return typeNode;\n}\n\n// ─── Type-Specific Converters ─────────────────────────────────────────────\n\nfunction stringSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n // Check format first\n if (schema.format) {\n const scalarName = FORMAT_TO_SCALAR[schema.format];\n if (scalarName) {\n return { kind: 'scalar', name: scalarName };\n }\n }\n\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minLength !== undefined && schema.maxLength !== undefined && schema.minLength === schema.maxLength) {\n mods.len = schema.minLength;\n } else {\n if (schema.minLength !== undefined) mods.min = schema.minLength;\n if (schema.maxLength !== undefined) mods.max = schema.maxLength;\n }\n if (schema.pattern) mods.regex = `/${schema.pattern}/`;\n if (schema.format && !FORMAT_TO_SCALAR[schema.format]) mods.format = schema.format;\n\n return { kind: 'scalar', name: 'string', ...mods };\n}\n\nfunction integerSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n const name: ScalarTypeNode['name'] = schema.format === 'int64' ? 'bigint' : 'int';\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minimum !== undefined) mods.min = schema.minimum;\n if (schema.maximum !== undefined) mods.max = schema.maximum;\n return { kind: 'scalar', name, ...mods };\n}\n\nfunction numberSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minimum !== undefined) mods.min = schema.minimum;\n if (schema.maximum !== undefined) mods.max = schema.maximum;\n return { kind: 'scalar', name: 'number', ...mods };\n}\n\nfunction arraySchemaToType(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // Tuple: prefixItems (OAS 3.1)\n if (schema.prefixItems && schema.prefixItems.length > 0) {\n return {\n kind: 'tuple',\n items: schema.prefixItems.map(s => schemaToTypeNode(s, ctx)),\n };\n }\n\n const item = schema.items ? schemaToTypeNode(schema.items, ctx) : { kind: 'scalar' as const, name: 'unknown' as const };\n const mods: { min?: number; max?: number } = {};\n if (schema.minItems !== undefined) mods.min = schema.minItems;\n if (schema.maxItems !== undefined) mods.max = schema.maxItems;\n\n return { kind: 'array', item, ...mods };\n}\n\nfunction objectSchemaToType(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // Record type: additionalProperties with no named properties\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && !schema.properties) {\n return {\n kind: 'record',\n key: { kind: 'scalar', name: 'string' },\n value: schemaToTypeNode(schema.additionalProperties, ctx),\n };\n }\n\n // Object with properties → inline object or extracted model\n if (schema.properties) {\n return schemaToInlineObject(schema, ctx);\n }\n\n // Empty object\n return { kind: 'scalar', name: 'object' };\n}\n\nfunction schemaToInlineObject(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n const fields = schemaPropertiesToFields(schema, ctx);\n return { kind: 'inlineObject', fields };\n}\n\n// ─── Field Conversion ─────────────────────────────────────────────────────\n\nfunction schemaPropertiesToFields(schema: NormalizedSchema, ctx: SchemaContext): FieldNode[] {\n const properties = schema.properties ?? {};\n const required = new Set(schema.required ?? []);\n const fields: FieldNode[] = [];\n\n for (const [name, propSchema] of Object.entries(properties)) {\n const propCtx = { ...ctx, path: `${ctx.path}/properties/${name}` };\n const fieldType = schemaToTypeNode(propSchema, propCtx);\n\n // Determine nullable from the type (if it's a union with null)\n let nullable = false;\n let effectiveType = fieldType;\n if (fieldType.kind === 'union') {\n const nonNull = fieldType.members.filter(m => !(m.kind === 'scalar' && m.name === 'null'));\n if (nonNull.length < fieldType.members.length) {\n nullable = true;\n effectiveType = nonNull.length === 1 ? nonNull[0]! : { kind: 'union', members: nonNull };\n }\n }\n\n const visibility = propSchema.readOnly ? ('readonly' as const) : propSchema.writeOnly ? ('writeonly' as const) : ('normal' as const);\n\n fields.push({\n name,\n optional: !required.has(name),\n nullable,\n visibility,\n type: effectiveType,\n default: propSchema.default as string | number | boolean | undefined,\n deprecated: propSchema.deprecated,\n description: ctx.includeComments ? propSchema.description : undefined,\n loc: LOC,\n });\n }\n\n return fields;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction normalizeTypeField(schema: NormalizedSchema): { baseType: string; nullable: boolean } | null {\n if (!schema.type) return null;\n\n if (typeof schema.type === 'string') {\n return { baseType: schema.type, nullable: false };\n }\n\n if (Array.isArray(schema.type)) {\n const types = schema.type as string[];\n const nonNull = types.filter(t => t !== 'null');\n const nullable = types.includes('null');\n if (nonNull.length === 1) {\n return { baseType: nonNull[0]!, nullable };\n }\n // Multiple non-null types — unusual but handle gracefully\n if (nonNull.length === 0) {\n return { baseType: 'null', nullable: false };\n }\n // Multiple types → treat as unknown\n return { baseType: nonNull[0]!, nullable };\n }\n\n return null;\n}\n\nfunction toUnion(schemas: NormalizedSchema[], ctx: SchemaContext): ContractTypeNode {\n const members = schemas.map(s => schemaToTypeNode(s, ctx));\n if (members.length === 1) return members[0]!;\n return { kind: 'union', members };\n}\n\nfunction toDiscriminatedUnion(schemas: NormalizedSchema[], discriminator: string, ctx: SchemaContext): ContractTypeNode {\n const members = schemas.map(s => schemaToTypeNode(s, ctx));\n if (members.length === 1) return members[0]!;\n return { kind: 'discriminatedUnion', discriminator, members };\n}\n\nfunction warnUnsupported(schema: NormalizedSchema, ctx: SchemaContext): void {\n if (schema.xml) ctx.warnings.warn(ctx.path, 'xml metadata is not supported, skipping');\n if (schema.externalDocs) ctx.warnings.info(ctx.path, 'externalDocs is not supported, skipping');\n if (schema.not) ctx.warnings.warn(ctx.path, 'not keyword is not supported, skipping');\n}\n\n/**\n * Extract a named model from an inline object schema (used for request/response bodies).\n */\nexport function extractInlineModel(\n schema: NormalizedSchema,\n suggestedName: string,\n ctx: SchemaContext,\n): { typeNode: ContractTypeNode; model?: ModelNode } {\n // If it's a $ref, just use the ref\n if (schema.$ref) {\n return { typeNode: schemaToTypeNode(schema, ctx) };\n }\n\n // If it's an object with properties, extract as a named model\n if (schema.properties || (schema.type === 'object' && schema.additionalProperties === undefined)) {\n const fields = schemaPropertiesToFields(schema, ctx);\n const model: ModelNode = {\n kind: 'model',\n name: suggestedName,\n fields,\n description: ctx.includeComments ? schema.description : undefined,\n loc: LOC,\n };\n return {\n typeNode: { kind: 'ref', name: suggestedName },\n model,\n };\n }\n\n // Otherwise return the type node directly\n return { typeNode: schemaToTypeNode(schema, ctx) };\n}\n\n/**\n * Sanitize an OpenAPI schema name to a valid .ck identifier (PascalCase).\n */\nexport function sanitizeName(name: string, warnings: WarningCollector): string {\n // Replace dots, hyphens, spaces, and other invalid chars with word boundaries\n const cleaned = name\n .replace(/[^a-zA-Z0-9_$]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n\n if (cleaned !== name) {\n warnings.info(`#/components/schemas/${name}`, `Schema name sanitized: \"${name}\" → \"${cleaned}\"`);\n }\n\n return cleaned || 'UnnamedSchema';\n}\n","import type {\n OpRouteNode,\n OpOperationNode,\n OpParamNode,\n OpRequestNode,\n OpResponseNode,\n OpResponseBodyNode,\n OpResponseHeaderNode,\n HttpMethod,\n ModelNode,\n SourceLocation,\n SecurityNode,\n} from '@contractkit/core';\nimport type {\n NormalizedDocument,\n NormalizedPathItem,\n NormalizedOperation,\n NormalizedParameter,\n NormalizedRequestBody,\n NormalizedResponse,\n} from './types.js';\nimport { schemaToTypeNode, extractInlineModel } from './schema-to-ast.js';\nimport type { SchemaContext } from './schema-to-ast.js';\nimport type { WarningCollector } from './warnings.js';\n\nconst LOC: SourceLocation = { file: '', line: 0 };\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete'];\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\nexport interface PathsContext {\n circularRefs: Set<string>;\n warnings: WarningCollector;\n includeComments: boolean;\n namedSchemas: Record<string, unknown>;\n /** Accumulates inline models extracted from request/response bodies. */\n extractedModels: ModelNode[];\n /** Global security from the spec (for detecting explicit overrides). */\n globalSecurity?: Record<string, string[]>[];\n}\n\n/**\n * Convert OpenAPI paths to OpRouteNode[].\n * Returns routes along with a tag mapping for each route.\n */\nexport function pathsToRoutes(doc: NormalizedDocument, ctx: PathsContext): { routes: OpRouteNode[]; routeTags: Map<OpRouteNode, string> } {\n const routes: OpRouteNode[] = [];\n const routeTags = new Map<OpRouteNode, string>();\n const paths = doc.paths ?? {};\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem) continue;\n const result = pathItemToRoute(path, pathItem, ctx);\n if (result) {\n routes.push(result.route);\n routeTags.set(result.route, result.tag);\n }\n }\n\n return { routes, routeTags };\n}\n\n// ─── Path Item → Route ───────────────────────────────────────────────────\n\nfunction pathItemToRoute(path: string, pathItem: NormalizedPathItem, ctx: PathsContext): { route: OpRouteNode; tag: string } | null {\n const operations: OpOperationNode[] = [];\n let primaryTag = 'default';\n\n // Collect path-level parameters\n const pathParams = (pathItem.parameters ?? []).filter(p => p.in === 'path');\n\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n\n const opNode = operationToNode(method, op, path, ctx);\n operations.push(opNode);\n\n // Use first tag of first operation as the route's tag\n if (op.tags && op.tags.length > 0 && primaryTag === 'default') {\n primaryTag = op.tags[0]!;\n }\n }\n\n if (operations.length === 0) return null;\n\n // Build params from path-level + inferred from path template\n const params = buildPathParams(path, pathParams, pathItem, ctx);\n\n const route: OpRouteNode = {\n path,\n operations,\n loc: LOC,\n };\n\n if (params.length > 0) {\n route.params = { kind: 'params', nodes: params };\n }\n\n if (pathItem.description && ctx.includeComments) {\n route.description = pathItem.description;\n }\n\n return { route, tag: primaryTag };\n}\n\n// ─── Operation → Node ─────────────────────────────────────────────────────\n\nfunction operationToNode(method: HttpMethod, op: NormalizedOperation, path: string, ctx: PathsContext): OpOperationNode {\n const pathPrefix = `#/paths/${encodePathSegment(path)}/${method}`;\n const schemaCtx = makeSchemaCtx(ctx, pathPrefix);\n\n const node: OpOperationNode = {\n method,\n responses: [],\n loc: LOC,\n };\n\n // operationId → sdk\n if (op.operationId) {\n node.sdk = op.operationId;\n }\n\n // Description\n if (op.description && ctx.includeComments) {\n node.description = op.description;\n }\n\n // Deprecated\n if (op.deprecated) {\n node.modifiers = ['deprecated'];\n }\n\n // Query and header parameters\n const queryParams: OpParamNode[] = [];\n const headerParams: OpParamNode[] = [];\n\n for (const param of op.parameters ?? []) {\n if (param.in === 'query') {\n queryParams.push(parameterToNode(param, schemaCtx));\n } else if (param.in === 'header') {\n headerParams.push(parameterToNode(param, schemaCtx));\n }\n }\n\n if (queryParams.length > 0) {\n node.query = { kind: 'params', nodes: queryParams };\n }\n if (headerParams.length > 0) {\n node.headers = { kind: 'params', nodes: headerParams };\n }\n\n // Request body\n if (op.requestBody) {\n node.request = requestBodyToNode(op.requestBody, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n }\n\n // Responses\n const responses = op.responses ?? {};\n for (const [code, resp] of Object.entries(responses)) {\n const statusCode = parseInt(code, 10);\n if (isNaN(statusCode)) continue;\n const respNode = responseToNode(statusCode, resp, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n node.responses.push(respNode);\n }\n\n // Security\n if (op.security !== undefined) {\n node.security = convertSecurity(op.security);\n }\n\n return node;\n}\n\n// ─── Parameters ───────────────────────────────────────────────────────────\n\nfunction buildPathParams(path: string, pathLevelParams: NormalizedParameter[], pathItem: NormalizedPathItem, ctx: PathsContext): OpParamNode[] {\n const schemaCtx = makeSchemaCtx(ctx, `#/paths/${encodePathSegment(path)}`);\n\n // Collect all path params from path-level and operation-level\n const paramMap = new Map<string, NormalizedParameter>();\n\n for (const p of pathLevelParams) {\n paramMap.set(p.name, p);\n }\n\n // Also check operation-level path params\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op?.parameters) continue;\n for (const p of op.parameters) {\n if (p.in === 'path' && !paramMap.has(p.name)) {\n paramMap.set(p.name, p);\n }\n }\n }\n\n // Extract param names from path template\n const templateNames = [...path.matchAll(/\\{([^}]+)\\}/g)].map(m => m[1]!);\n\n return templateNames.map(name => {\n const param = paramMap.get(name);\n if (param) {\n return parameterToNode(param, schemaCtx);\n }\n // Infer as uuid if no schema is given\n return {\n name,\n optional: false,\n nullable: false,\n type: { kind: 'scalar' as const, name: 'string' as const },\n loc: LOC,\n };\n });\n}\n\nfunction parameterToNode(param: NormalizedParameter, ctx: SchemaContext): OpParamNode {\n const type = param.schema ? schemaToTypeNode(param.schema, ctx) : { kind: 'scalar' as const, name: 'string' as const };\n\n return {\n name: param.name,\n optional: param.in !== 'path' && !param.required,\n nullable: false,\n type,\n description: ctx.includeComments ? param.description : undefined,\n loc: LOC,\n };\n}\n\n// ─── Request Body ─────────────────────────────────────────────────────────\n\nfunction requestBodyToNode(\n reqBody: NormalizedRequestBody,\n operationName: string,\n schemaCtx: SchemaContext,\n ctx: PathsContext,\n): OpRequestNode | undefined {\n const content = reqBody.content;\n if (!content) return undefined;\n\n const supported = new Set<string>(['application/json', 'application/x-www-form-urlencoded', 'multipart/form-data']);\n const bodies: OpRequestNode['bodies'] = [];\n\n for (const [contentType, mediaType] of Object.entries(content)) {\n if (!supported.has(contentType) || !mediaType?.schema) continue;\n const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Request`, schemaCtx);\n if (model) {\n ctx.extractedModels.push(model);\n }\n bodies.push({\n contentType: contentType as OpRequestNode['bodies'][number]['contentType'],\n bodyType: typeNode,\n });\n }\n\n if (bodies.length === 0) return undefined;\n return { bodies };\n}\n\n// ─── Responses ────────────────────────────────────────────────────────────\n\nfunction responseToNode(\n statusCode: number,\n resp: NormalizedResponse,\n operationName: string,\n schemaCtx: SchemaContext,\n ctx: PathsContext,\n): OpResponseNode {\n const headers = convertResponseHeaders(resp.headers, schemaCtx);\n const empty = (): OpResponseNode => ({ statusCode, bodies: [], ...(headers ? { headers, hasBlock: true } : {}) });\n\n if (!resp.content) return empty();\n\n // Every declared content type is kept — `.ck` can express several mimes for one status, so\n // there is no reason to narrow a spec down to its first one on the way in.\n const bodies: OpResponseBodyNode[] = [];\n for (const [contentType, mediaType] of Object.entries(resp.content)) {\n if (!mediaType?.schema) continue;\n // The extracted model is named for the status; a second mime for the same status reuses\n // that name rather than minting a near-duplicate.\n const suffix = bodies.length === 0 ? '' : toPascalCase(contentType.replace(/[^a-z0-9]+/gi, ' '));\n const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Response${statusCode}${suffix}`, schemaCtx);\n if (model) ctx.extractedModels.push(model);\n bodies.push({ contentType, bodyType: typeNode });\n }\n\n if (bodies.length === 0) return empty();\n\n return {\n statusCode,\n bodies,\n hasBlock: true,\n ...(headers ? { headers } : {}),\n };\n}\n\nfunction convertResponseHeaders(headers: NormalizedResponse['headers'], schemaCtx: SchemaContext): OpResponseHeaderNode[] | undefined {\n if (!headers) return undefined;\n const out: OpResponseHeaderNode[] = [];\n for (const [name, header] of Object.entries(headers)) {\n if (!header) continue;\n const type = header.schema ? schemaToTypeNode(header.schema, schemaCtx) : { kind: 'scalar' as const, name: 'string' as const };\n out.push({\n name,\n optional: !header.required,\n type,\n description: schemaCtx.includeComments ? header.description : undefined,\n });\n }\n return out.length > 0 ? out : undefined;\n}\n\n// ─── Security ─────────────────────────────────────────────────────────────\n\nfunction convertSecurity(security: Record<string, string[]>[]): SecurityNode {\n // Empty array = explicitly no security\n if (security.length === 0) {\n return 'none';\n }\n\n // The DSL's security model is simpler — OpenAPI scopes/roles don't map onto named policies,\n // so any non-empty security requirement is collapsed to \"authenticated, default policy\".\n return { loc: LOC };\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction makeSchemaCtx(ctx: PathsContext, path: string): SchemaContext {\n return {\n circularRefs: ctx.circularRefs,\n warnings: ctx.warnings,\n path,\n includeComments: ctx.includeComments,\n namedSchemas: ctx.namedSchemas as Record<string, never>,\n extractedModels: ctx.extractedModels,\n inlineCounter: 0,\n };\n}\n\nfunction toPascalCase(input: string): string {\n return input\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\nfunction encodePathSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n","import type { CkRootNode, ModelNode, OpRouteNode, ContractTypeNode } from '@contractkit/core';\n\n/**\n * Split models and routes into per-tag CkRootNode instances.\n *\n * Algorithm:\n * 1. Routes are assigned to the file of their first tag (untagged → 'default')\n * 2. Models referenced by exactly one tag go into that tag's file\n * 3. Models referenced by 2+ tags go into 'shared'\n * 4. Orphan models (not referenced by any route) go into 'shared'\n */\nexport function splitByTag(models: ModelNode[], routes: OpRouteNode[], routeTags: Map<OpRouteNode, string>): Map<string, CkRootNode> {\n // Step 1: Group routes by tag\n const routesByTag = new Map<string, OpRouteNode[]>();\n for (const route of routes) {\n const tag = routeTags.get(route) ?? 'default';\n const group = routesByTag.get(tag) ?? [];\n group.push(route);\n routesByTag.set(tag, group);\n }\n\n // Step 2: For each tag, collect which model names are referenced\n const modelsByTag = new Map<string, Set<string>>();\n for (const [tag, tagRoutes] of routesByTag) {\n const refs = new Set<string>();\n for (const route of tagRoutes) {\n collectRouteRefs(route, refs);\n }\n modelsByTag.set(tag, refs);\n }\n\n // Step 3: Determine which tag each model belongs to\n const modelNameToModel = new Map(models.map(m => [m.name, m]));\n const modelAssignment = new Map<string, string>(); // modelName → tag or 'shared'\n\n for (const model of models) {\n const tags: string[] = [];\n for (const [tag, refs] of modelsByTag) {\n if (refs.has(model.name)) {\n tags.push(tag);\n }\n }\n\n if (tags.length === 0) {\n // Orphan model → shared\n modelAssignment.set(model.name, 'shared');\n } else if (tags.length === 1) {\n // Single tag reference → that tag's file\n modelAssignment.set(model.name, tags[0]!);\n } else {\n // Multi-tag reference → shared\n modelAssignment.set(model.name, 'shared');\n }\n }\n\n // Also check transitive: models referenced by shared models should also be shared\n // (simple one-pass — could iterate to fixed point for deep chains)\n for (const model of models) {\n if (modelAssignment.get(model.name) === 'shared') {\n const refs = new Set<string>();\n collectModelRefs(model, refs);\n for (const ref of refs) {\n if (modelNameToModel.has(ref)) {\n const currentTag = modelAssignment.get(ref);\n // Only promote to shared if it was assigned to a specific tag\n // (don't override if already shared)\n if (currentTag && currentTag !== 'shared') {\n // Check if another tag also references this model\n const otherTags = [...modelsByTag.entries()].filter(([t, r]) => t !== currentTag && r.has(ref)).map(([t]) => t);\n if (otherTags.length > 0) {\n modelAssignment.set(ref, 'shared');\n }\n }\n }\n }\n }\n }\n\n // Step 4: Build CkRootNode per tag\n const result = new Map<string, CkRootNode>();\n const allTags = new Set([...routesByTag.keys(), ...new Set(modelAssignment.values())]);\n\n for (const tag of allTags) {\n const tagModels = models.filter(m => modelAssignment.get(m.name) === tag);\n const tagRoutes = routesByTag.get(tag) ?? [];\n\n if (tagModels.length === 0 && tagRoutes.length === 0) continue;\n\n const filename = sanitizeFilename(tag);\n result.set(`${filename}.ck`, {\n kind: 'ckRoot',\n meta: tag !== 'shared' ? { area: tag } : {},\n services: {},\n models: tagModels,\n routes: tagRoutes,\n file: `${filename}.ck`,\n });\n }\n\n return result;\n}\n\n/**\n * Create a single CkRootNode with all models and routes.\n */\nexport function mergeIntoSingle(models: ModelNode[], routes: OpRouteNode[], filename: string = 'api'): CkRootNode {\n return {\n kind: 'ckRoot',\n meta: {},\n services: {},\n models,\n routes,\n file: `${filename}.ck`,\n };\n}\n\n// ─── Reference Collection ─────────────────────────────────────────────────\n\nfunction collectRouteRefs(route: OpRouteNode, refs: Set<string>): void {\n if (route.params) {\n collectParamSourceRefs(route.params, refs);\n }\n for (const op of route.operations) {\n if (op.query) collectParamSourceRefs(op.query, refs);\n if (op.headers) collectParamSourceRefs(op.headers, refs);\n if (op.request) {\n for (const body of op.request.bodies) collectTypeRefs(body.bodyType, refs);\n }\n for (const resp of op.responses) {\n for (const body of resp.bodies) collectTypeRefs(body.bodyType, refs);\n }\n }\n}\n\nfunction collectParamSourceRefs(source: unknown, refs: Set<string>): void {\n if (typeof source === 'string') {\n refs.add(source);\n return;\n }\n if (Array.isArray(source)) {\n for (const param of source) {\n if (param && typeof param === 'object' && 'type' in param) {\n collectTypeRefs(param.type as ContractTypeNode, refs);\n }\n }\n return;\n }\n if (source && typeof source === 'object' && 'kind' in source) {\n collectTypeRefs(source as ContractTypeNode, refs);\n }\n}\n\nfunction collectTypeRefs(type: ContractTypeNode, refs: Set<string>): void {\n switch (type.kind) {\n case 'ref':\n refs.add(type.name);\n break;\n case 'array':\n collectTypeRefs(type.item, refs);\n break;\n case 'tuple':\n for (const item of type.items) collectTypeRefs(item, refs);\n break;\n case 'record':\n collectTypeRefs(type.key, refs);\n collectTypeRefs(type.value, refs);\n break;\n case 'union':\n case 'discriminatedUnion':\n case 'intersection':\n for (const member of type.members) collectTypeRefs(member, refs);\n break;\n case 'inlineObject':\n for (const field of type.fields) collectTypeRefs(field.type, refs);\n break;\n case 'lazy':\n collectTypeRefs(type.inner, refs);\n break;\n }\n}\n\nfunction collectModelRefs(model: ModelNode, refs: Set<string>): void {\n if (model.bases) for (const b of model.bases) refs.add(b);\n if (model.type) collectTypeRefs(model.type, refs);\n for (const field of model.fields) {\n collectTypeRefs(field.type, refs);\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction sanitizeFilename(tag: string): string {\n return (\n tag\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '') || 'default'\n );\n}\n","import type {\n CkRootNode,\n ModelNode,\n FieldNode,\n ContractTypeNode,\n OpRouteNode,\n OpOperationNode,\n OpRequestNode,\n OpResponseNode,\n ParamSource,\n SecurityNode,\n SecurityFields,\n ObjectMode,\n RouteModifier,\n} from '@contractkit/core';\n\nconst INDENT = ' '; // 4 spaces\n\n/** Matches a bare identifier that needs no quoting (mirrors serializeDefault). */\nconst IDENT_RE = /^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/;\n\n/**\n * Flatten a description to a single line so it is safe to embed in a trailing\n * `# ...` comment. OpenAPI descriptions routinely contain newlines; an embedded\n * newline would terminate the comment and dump the rest as raw `.ck` source.\n */\nfunction singleLineComment(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Serialize an enum value as a `.ck` enum argument. Bare identifiers are emitted\n * as-is; anything else (spaces, punctuation) is wrapped in a string literal.\n * `.ck` string literals have no escape sequences, so when the value contains a\n * double quote we fall back to single quotes (and vice versa).\n */\nfunction quoteEnumValue(value: string): string {\n if (IDENT_RE.test(value)) return value;\n if (!value.includes('\"')) return `\"${value}\"`;\n if (!value.includes(\"'\")) return `'${value}'`;\n // Value contains both quote styles; `.ck` cannot escape, so keep double\n // quotes and preserve the inner ones as best we can.\n return `\"${value}\"`;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\n/** Options controlling how a {@link CkRootNode} is rendered to `.ck` source. */\nexport interface SerializeOptions {\n /** Emit descriptions as inline # comments. Default: true. */\n includeComments?: boolean;\n}\n\n/**\n * Serialize a `.ck` AST back to formatted `.ck` source text. Emits the options\n * block first, then every model, then every route, separated by blank lines and\n * terminated with a trailing newline. Descriptions become trailing `# ...`\n * comments unless `options.includeComments` is `false`. The output is designed\n * to re-parse cleanly via `parseCk` (see round-trip tests).\n */\nexport function astToCk(root: CkRootNode, options: SerializeOptions = {}): string {\n const { includeComments = true } = options;\n const ctx: Ctx = { includeComments };\n const parts: string[] = [];\n\n // Options block\n const optionsBlock = serializeOptions(root);\n if (optionsBlock) parts.push(optionsBlock);\n\n // Models\n for (const model of root.models) {\n parts.push(serializeModel(model, ctx));\n }\n\n // Routes\n for (const route of root.routes) {\n parts.push(serializeRoute(route, ctx));\n }\n\n return parts.join('\\n\\n') + '\\n';\n}\n\n// ─── Context ──────────────────────────────────────────────────────────────\n\ninterface Ctx {\n includeComments: boolean;\n}\n\n// ─── Options block ────────────────────────────────────────────────────────\n\nfunction serializeOptions(root: CkRootNode): string | null {\n const hasKeys = Object.keys(root.meta).length > 0;\n const hasServices = root.services && Object.keys(root.services).length > 0;\n const hasSecurity = root.security !== undefined;\n\n if (!hasKeys && !hasServices && !hasSecurity) return null;\n\n const lines: string[] = ['options {'];\n\n if (hasKeys) {\n lines.push(`${INDENT}keys: {`);\n for (const [key, value] of Object.entries(root.meta)) {\n lines.push(`${INDENT}${INDENT}${key}: ${value}`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasServices) {\n lines.push(`${INDENT}services: {`);\n for (const [name, path] of Object.entries(root.services)) {\n lines.push(`${INDENT}${INDENT}${name}: \"${path}\"`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasSecurity) {\n lines.push(`${INDENT}security: {`);\n if (root.security === 'none') {\n lines.push(`${INDENT}${INDENT}none`);\n } else {\n const sec = root.security as SecurityFields;\n if (sec.policy !== undefined) {\n const value = sec.policy === false ? 'none' : sec.policy;\n lines.push(`${INDENT}${INDENT}policy: ${value}`);\n }\n }\n lines.push(`${INDENT}}`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n// ─── Models ───────────────────────────────────────────────────────────────\n\nfunction serializeModel(model: ModelNode, ctx: Ctx): string {\n const parts: string[] = [];\n\n // Modifiers: format(input=snake) mode(loose) deprecated\n const prefixes: string[] = [];\n if (model.inputCase && model.inputCase !== 'camel') {\n prefixes.push(`format(input=${model.inputCase})`);\n }\n if (model.mode && model.mode !== 'strict') {\n prefixes.push(`mode(${model.mode})`);\n }\n if (model.deprecated) {\n prefixes.push('deprecated');\n }\n\n const prefix = prefixes.length > 0 ? prefixes.join(' ') + ' ' : '';\n const comment = ctx.includeComments && model.description ? ` # ${singleLineComment(model.description)}` : '';\n\n // Type alias: contract Name: typeExpression\n if (model.type) {\n parts.push(`contract ${prefix}${model.name}: ${serializeType(model.type)}${comment}`);\n return parts.join('');\n }\n\n // Inheritance: contract Name: Base1 & Base2 & { ... }\n if (model.bases && model.bases.length > 0) {\n parts.push(`contract ${prefix}${model.name}: ${model.bases.join(' & ')} & {${comment}`);\n } else {\n parts.push(`contract ${prefix}${model.name}: {${comment}`);\n }\n\n for (const field of model.fields) {\n parts.push(serializeField(field, 1, ctx));\n }\n\n parts.push('}');\n return parts.join('\\n');\n}\n\nfunction serializeField(field: FieldNode, depth: number, ctx: Ctx): string {\n const indent = INDENT.repeat(depth);\n const optional = field.optional ? '?' : '';\n const visibility = field.visibility !== 'normal' ? `${field.visibility} ` : '';\n const deprecated = field.deprecated ? 'deprecated ' : '';\n\n let typeStr = serializeType(field.type);\n\n // Nullable fields: if the type doesn't already contain null, append `| null`\n if (field.nullable && !typeContainsNull(field.type)) {\n typeStr = `${typeStr} | null`;\n }\n\n const defaultVal = field.default !== undefined ? ` = ${serializeDefault(field.default)}` : '';\n const comment = ctx.includeComments && field.description ? ` # ${singleLineComment(field.description)}` : '';\n\n return `${indent}${field.name}${optional}: ${deprecated}${visibility}${typeStr}${defaultVal}${comment}`;\n}\n\nfunction typeContainsNull(type: ContractTypeNode): boolean {\n if (type.kind === 'scalar' && type.name === 'null') return true;\n if (type.kind === 'union') return type.members.some(typeContainsNull);\n return false;\n}\n\nfunction serializeDefault(value: string | number | boolean): string {\n if (typeof value === 'string') {\n // If it looks like an identifier (e.g. enum value), don't quote it\n if (/^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/.test(value)) return value;\n return `\"${value}\"`;\n }\n return String(value);\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────\n\n/**\n * Serialize a single {@link ContractTypeNode} to its inline `.ck` type\n * expression (e.g. `array(User, min=1)`, `string | int`, `enum(asc, desc)`).\n * Recurses through composite types; enum values are quoted as needed via\n * {@link quoteEnumValue}.\n */\nexport function serializeType(type: ContractTypeNode): string {\n switch (type.kind) {\n case 'scalar':\n return serializeScalar(type);\n case 'array':\n return serializeArray(type);\n case 'tuple':\n return `tuple(${type.items.map(serializeType).join(', ')})`;\n case 'record':\n return `record(${serializeType(type.key)}, ${serializeType(type.value)})`;\n case 'enum':\n return `enum(${type.values.map(quoteEnumValue).join(', ')})`;\n case 'literal':\n return serializeLiteral(type);\n case 'union':\n return type.members.map(serializeType).join(' | ');\n case 'discriminatedUnion':\n return `discriminated(by=${type.discriminator}, ${type.members.map(serializeType).join(' | ')})`;\n case 'intersection':\n return type.members.map(serializeType).join(' & ');\n case 'ref':\n return type.name;\n case 'inlineObject':\n return serializeInlineObject(type);\n case 'lazy':\n return `lazy(${serializeType(type.inner)})`;\n }\n}\n\nfunction serializeScalar(type: {\n name: string;\n min?: number | bigint | string;\n max?: number | bigint | string;\n len?: number;\n regex?: string;\n format?: string;\n}): string {\n const args: string[] = [];\n if (type.len !== undefined) args.push(`length=${type.len}`);\n if (type.min !== undefined) args.push(typeof type.min === 'string' ? `min=\"${type.min}\"` : `min=${type.min}`);\n if (type.max !== undefined) args.push(typeof type.max === 'string' ? `max=\"${type.max}\"` : `max=${type.max}`);\n if (type.regex !== undefined) args.push(`regex=${type.regex}`);\n if (type.format !== undefined) args.push(`format=${type.format}`);\n\n if (args.length === 0) return type.name;\n return `${type.name}(${args.join(', ')})`;\n}\n\nfunction serializeArray(type: { item: ContractTypeNode; min?: number; max?: number }): string {\n const args: string[] = [serializeType(type.item)];\n if (type.min !== undefined) args.push(`min=${type.min}`);\n if (type.max !== undefined) args.push(`max=${type.max}`);\n return `array(${args.join(', ')})`;\n}\n\nfunction serializeLiteral(type: { value: string | number | boolean }): string {\n if (typeof type.value === 'string') return `literal(\"${type.value}\")`;\n return `literal(${type.value})`;\n}\n\nfunction serializeInlineObject(type: { fields: FieldNode[]; mode?: ObjectMode }): string {\n const modePrefix = type.mode ? `mode(${type.mode}) ` : '';\n if (type.fields.length === 0) return `${modePrefix}{}`;\n\n const lines: string[] = [`${modePrefix}{`];\n for (const field of type.fields) {\n lines.push(serializeField(field, 2, { includeComments: true }));\n }\n lines.push(`${INDENT}}`);\n return lines.join('\\n');\n}\n\n// ─── Routes ───────────────────────────────────────────────────────────────\n\nfunction serializeRoute(route: OpRouteNode, ctx: Ctx): string {\n const lines: string[] = [];\n\n const modStr = serializeModifiers(route.modifiers);\n const comment = ctx.includeComments && route.description ? ` # ${singleLineComment(route.description)}` : '';\n lines.push(`operation${modStr} ${route.path}: {${comment}`);\n\n // Route-level params\n if (route.params) {\n serializeParamSource(lines, 'params', route.params, route.paramsMode, 1, ctx);\n }\n\n // Route-level security\n if (route.security !== undefined) {\n serializeSecurityBlock(lines, route.security, 1, ctx);\n }\n\n // Operations\n for (const op of route.operations) {\n serializeOperation(lines, op, 1, ctx);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\nfunction serializeOperation(lines: string[], op: OpOperationNode, depth: number, ctx: Ctx): string[] {\n const indent = INDENT.repeat(depth);\n const modStr = serializeModifiers(op.modifiers);\n const comment = ctx.includeComments && op.description ? ` # ${singleLineComment(op.description)}` : '';\n lines.push(`${indent}${op.method}${modStr}: {${comment}`);\n\n const inner = INDENT.repeat(depth + 1);\n\n // Service\n if (op.service) {\n lines.push(`${inner}service: ${op.service}`);\n }\n\n // SDK\n if (op.sdk) {\n lines.push(`${inner}sdk: ${op.sdk}`);\n }\n\n // Signature\n if (op.signature) {\n const sigComment = ctx.includeComments && op.signatureDescription ? ` # ${singleLineComment(op.signatureDescription)}` : '';\n if (op.signaturePolicy) {\n lines.push(`${inner}signature: {`);\n lines.push(`${inner} options: ${op.signature}${sigComment}`);\n lines.push(`${inner} policy: ${op.signaturePolicy}`);\n lines.push(`${inner}}`);\n } else {\n lines.push(`${inner}signature: ${op.signature}${sigComment}`);\n }\n }\n\n // Security\n if (op.security !== undefined) {\n serializeSecurityBlock(lines, op.security, depth + 1, ctx);\n }\n\n // Query\n if (op.query) {\n serializeParamSource(lines, 'query', op.query, op.queryMode, depth + 1, ctx);\n }\n\n // Headers\n if (op.headers) {\n serializeParamSource(lines, 'headers', op.headers, op.headersMode, depth + 1, ctx);\n }\n\n // Request\n if (op.request) {\n serializeRequest(lines, op.request, depth + 1);\n }\n\n // Responses\n if (op.responses.length > 0) {\n serializeResponses(lines, op.responses, depth + 1);\n }\n\n lines.push(`${indent}}`);\n return lines;\n}\n\nfunction serializeModifiers(modifiers?: RouteModifier[]): string {\n if (!modifiers || modifiers.length === 0) return '';\n return `(${modifiers.join(', ')})`;\n}\n\nfunction serializeParamSource(lines: string[], keyword: string, source: ParamSource, mode: ObjectMode | undefined, depth: number, ctx: Ctx): void {\n const indent = INDENT.repeat(depth);\n\n // String reference: `query: TypeName`\n if (source.kind === 'ref') {\n lines.push(`${indent}${keyword}: ${source.name}`);\n return;\n }\n\n // ContractTypeNode reference\n if (source.kind === 'type') {\n lines.push(`${indent}${keyword}: ${serializeType(source.node)}`);\n return;\n }\n\n // Inline param declarations: `params: { name: type }`\n const modeStr = mode ? `mode(${mode}) ` : '';\n lines.push(`${indent}${keyword}: ${modeStr}{`);\n for (const param of source.nodes) {\n const optional = param.optional ? '?' : '';\n let typeStr = serializeType(param.type);\n if (param.nullable && !typeContainsNull(param.type)) {\n typeStr = `${typeStr} | null`;\n }\n const defaultVal = param.default !== undefined ? ` = ${serializeDefault(param.default)}` : '';\n const comment = ctx.includeComments && param.description ? ` # ${singleLineComment(param.description)}` : '';\n lines.push(`${INDENT.repeat(depth + 1)}${param.name}${optional}: ${typeStr}${defaultVal}${comment}`);\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeRequest(lines: string[], request: OpRequestNode, depth: number): void {\n const indent = INDENT.repeat(depth);\n lines.push(`${indent}request: {`);\n for (const body of request.bodies) {\n lines.push(`${INDENT.repeat(depth + 1)}${body.contentType}: ${serializeType(body.bodyType)}`);\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeResponses(lines: string[], responses: OpResponseNode[], depth: number): void {\n const indent = INDENT.repeat(depth);\n lines.push(`${indent}response: {`);\n for (const resp of responses) {\n const bodies = resp.bodies;\n const hasHeaders = resp.headers && resp.headers.length > 0;\n if (bodies.length > 0 || hasHeaders) {\n lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}: {`);\n for (const body of bodies) {\n lines.push(`${INDENT.repeat(depth + 2)}${body.contentType}: ${serializeType(body.bodyType)}`);\n }\n if (hasHeaders) {\n lines.push(`${INDENT.repeat(depth + 2)}headers: {`);\n for (const h of resp.headers!) {\n const opt = h.optional ? '?' : '';\n const trail = h.description ? ` # ${singleLineComment(h.description)}` : '';\n lines.push(`${INDENT.repeat(depth + 3)}${h.name}${opt}: ${serializeType(h.type)}${trail}`);\n }\n lines.push(`${INDENT.repeat(depth + 2)}}`);\n }\n lines.push(`${INDENT.repeat(depth + 1)}}`);\n } else {\n lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}:`);\n }\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeSecurityBlock(lines: string[], security: SecurityNode, depth: number, ctx: Ctx): void {\n const indent = INDENT.repeat(depth);\n if (security === 'none') {\n lines.push(`${indent}security: none`);\n return;\n }\n\n const sec = security as SecurityFields;\n if (sec.policy !== undefined) {\n const comment = ctx.includeComments && sec.policyDescription ? ` # ${singleLineComment(sec.policyDescription)}` : '';\n const value = sec.policy === false ? 'none' : sec.policy;\n lines.push(`${indent}security: {`);\n lines.push(`${INDENT.repeat(depth + 1)}policy: ${value}${comment}`);\n lines.push(`${indent}}`);\n } else {\n lines.push(`${indent}security: {}`);\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { parse as parseYaml } from 'yaml';\nimport type { ConvertOptions, ConvertResult, NormalizedDocument } from './types.js';\nimport { WarningCollector } from './warnings.js';\nimport { normalize } from './normalize.js';\nimport { detectCircularRefs } from './circular-refs.js';\nimport { schemasToModels, sanitizeName } from './schema-to-ast.js';\nimport type { SchemaContext } from './schema-to-ast.js';\nimport { pathsToRoutes } from './paths-to-ast.js';\nimport { splitByTag, mergeIntoSingle } from './tag-splitter.js';\nimport { astToCk } from './ast-to-ck.js';\nimport type { NormalizedSchema } from './types.js';\nimport type { ModelNode } from '@contractkit/core';\n\n/**\n * Convert an OpenAPI spec (2.0, 3.0, or 3.1) to Contract Kit .ck source files.\n */\nexport async function convertOpenApiToCk(options: ConvertOptions): Promise<ConvertResult> {\n const { split = 'by-tag', includeComments = true } = options;\n const warnings = new WarningCollector(options.onWarning);\n\n // Step 1: Parse the input into a document object\n const rawDoc = await parseInput(options.input);\n\n // Step 2: Normalize to 3.1 shape\n const doc = normalize(rawDoc, warnings);\n\n // Step 3: Sanitize schema names\n const schemas = sanitizeSchemaNames(doc, warnings);\n\n // Step 4: Detect circular references\n const circularRefs = detectCircularRefs(schemas);\n\n // Step 5: Convert schemas to model AST nodes\n const extractedModels: ModelNode[] = [];\n const schemaCtx: SchemaContext = {\n circularRefs,\n warnings,\n path: '#/components/schemas',\n includeComments,\n namedSchemas: schemas,\n extractedModels,\n inlineCounter: 0,\n };\n\n const models = schemasToModels(schemas, schemaCtx);\n\n // Step 6: Convert paths to route AST nodes\n const { routes, routeTags } = pathsToRoutes(doc, {\n circularRefs,\n warnings,\n includeComments,\n namedSchemas: schemas,\n extractedModels,\n globalSecurity: doc.security,\n });\n\n // Step 7: Split or merge\n const files = new Map<string, string>();\n\n if (split === 'by-tag') {\n const ckRoots = splitByTag(models, routes, routeTags);\n for (const [filename, root] of ckRoots) {\n files.set(filename, astToCk(root, { includeComments }));\n }\n } else {\n const root = mergeIntoSingle(models, routes);\n files.set('api.ck', astToCk(root, { includeComments }));\n }\n\n return { files, warnings: warnings.warnings };\n}\n\n// ─── Input Parsing ────────────────────────────────────────────────────────\n\nasync function parseInput(input: string | Record<string, unknown>): Promise<Record<string, unknown>> {\n // Already a parsed object\n if (typeof input === 'object') {\n return input;\n }\n\n // Try as a file path first\n try {\n const content = readFileSync(input, 'utf-8');\n return parseJsonOrYaml(content);\n } catch {\n // Not a file path — try parsing as JSON/YAML string\n return parseJsonOrYaml(input);\n }\n}\n\nfunction parseJsonOrYaml(content: string): Record<string, unknown> {\n // Try JSON first (faster)\n try {\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n // Fall back to YAML\n return parseYaml(content) as Record<string, unknown>;\n }\n}\n\n// ─── Schema Name Sanitization ─────────────────────────────────────────────\n\nfunction sanitizeSchemaNames(doc: NormalizedDocument, warnings: WarningCollector): Record<string, NormalizedSchema> {\n const original = doc.components?.schemas ?? {};\n const sanitized: Record<string, NormalizedSchema> = {};\n const nameMap = new Map<string, string>(); // original → sanitized\n\n for (const name of Object.keys(original)) {\n const clean = sanitizeName(name, warnings);\n if (sanitized[clean]) {\n warnings.warn(`#/components/schemas/${name}`, `Name collision after sanitization: \"${name}\" and another schema both map to \"${clean}\"`);\n // Disambiguate with a suffix\n let i = 2;\n while (sanitized[`${clean}${i}`]) i++;\n nameMap.set(name, `${clean}${i}`);\n sanitized[`${clean}${i}`] = original[name] as NormalizedSchema;\n } else {\n nameMap.set(name, clean);\n sanitized[clean] = original[name] as NormalizedSchema;\n }\n }\n\n // Update $refs in the document to use sanitized names\n if (nameMap.size > 0) {\n updateRefs(doc, nameMap);\n }\n\n return sanitized;\n}\n\nfunction updateRefs(obj: unknown, nameMap: Map<string, string>): void {\n if (!obj || typeof obj !== 'object') return;\n if (Array.isArray(obj)) {\n for (const item of obj) updateRefs(item, nameMap);\n return;\n }\n\n const record = obj as Record<string, unknown>;\n if (typeof record.$ref === 'string') {\n const match = record.$ref.match(/^#\\/components\\/schemas\\/(.+)$/);\n if (match?.[1] && nameMap.has(match[1])) {\n record.$ref = `#/components/schemas/${nameMap.get(match[1])}`;\n }\n }\n\n for (const value of Object.values(record)) {\n updateRefs(value, nameMap);\n }\n}\n","import type { Warning } from './types.js';\n\nexport class WarningCollector {\n readonly warnings: Warning[] = [];\n private onWarning?: (w: Warning) => void;\n\n constructor(onWarning?: (w: Warning) => void) {\n this.onWarning = onWarning;\n }\n\n warn(path: string, message: string): void {\n this.add({ path, message, severity: 'warn' });\n }\n\n info(path: string, message: string): void {\n this.add({ path, message, severity: 'info' });\n }\n\n private add(warning: Warning): void {\n this.warnings.push(warning);\n this.onWarning?.(warning);\n }\n}\n"],"mappings":"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","names":["normalize","doc","warnings","version","detectVersion","normalizeSwagger2","normalizeOas30","swagger","startsWith","openapi","info","title","basePath","schemes","host","globalConsumes","consumes","globalProduces","produces","result","description","servers","url","paths","components","schemas","securitySchemes","tags","definitions","name","schema","Object","entries","normalizeNullable30","secDefs","securityDefinitions","scheme","convertSecurityScheme2","path","pathItem","normalizePathItem2","security","methods","normalized","pathParams","parameters","method","op","opConsumes","opProduces","params","nonBodyParams","requestBody","param","in","contentType","required","content","encodePathSegment","type","properties","formSchema","props","push","normalizedParam","format","enum","items","default","minimum","maximum","minLength","maxLength","pattern","responses","opResponses","code","resp","headers","convertResponseHeaders2","responseEntry","operationId","summary","length","undefined","deprecated","out","header","rest","keys","flow","flows","implicit","authorizationUrl","scopes","password","tokenUrl","clientCredentials","authorizationCode","_warnings","values","normalizePathItemSchemas","reqBody","mediaType","nullable","key","val","Array","isArray","additionalProperties","combiner","map","s","replace","detectCircularRefs","schemas","circular","Set","visiting","visited","visit","name","has","add","schema","ref","collectRefs","refName","extractRefName","delete","Object","keys","obj","refs","walk","val","Array","isArray","item","record","$ref","push","v","values","match","LOC","file","line","FORMAT_TO_SCALAR","email","uri","url","uuid","date","time","binary","int64","schemasToModels","schemas","ctx","models","name","schema","Object","entries","modelCtx","path","model","schemaToModel","push","extractedModels","warnUnsupported","description","includeComments","undefined","allOf","length","first","second","refMember","$ref","objectMember","properties","baseName","extractRefName","fields","schemaPropertiesToFields","kind","bases","loc","type","additionalProperties","typeNode","schemaToTypeNode","refName","circularRefs","has","inner","warnings","warn","const","value","enum","values","map","String","oneOf","discriminator","propertyName","toDiscriminatedUnion","toUnion","anyOf","members","s","types","normalizeTypeField","schemaToInlineObject","baseType","nullable","stringSchemaToType","integerSchemaToType","numberSchemaToType","arraySchemaToType","objectSchemaToType","format","scalarName","mods","minLength","maxLength","len","min","max","pattern","regex","minimum","maximum","prefixItems","items","item","minItems","maxItems","key","required","Set","propSchema","propCtx","fieldType","effectiveType","nonNull","filter","m","visibility","readOnly","writeOnly","optional","default","deprecated","Array","isArray","t","includes","xml","externalDocs","info","not","extractInlineModel","suggestedName","sanitizeName","cleaned","replace","split","Boolean","part","charAt","toUpperCase","slice","join","LOC","file","line","HTTP_METHODS","pathsToRoutes","doc","ctx","routes","routeTags","Map","paths","path","pathItem","Object","entries","result","pathItemToRoute","push","route","set","tag","operations","primaryTag","pathParams","parameters","filter","p","in","method","op","opNode","operationToNode","tags","length","params","buildPathParams","loc","kind","nodes","description","includeComments","pathPrefix","encodePathSegment","schemaCtx","makeSchemaCtx","node","responses","operationId","sdk","deprecated","modifiers","queryParams","headerParams","param","parameterToNode","query","headers","requestBody","request","requestBodyToNode","toPascalCase","code","resp","statusCode","parseInt","isNaN","respNode","responseToNode","security","undefined","convertSecurity","pathLevelParams","paramMap","name","has","templateNames","matchAll","map","m","get","optional","nullable","type","schema","schemaToTypeNode","required","reqBody","operationName","content","supported","Set","bodies","contentType","mediaType","typeNode","model","extractInlineModel","extractedModels","bodyType","convertResponseHeaders","empty","hasBlock","suffix","replace","out","header","circularRefs","warnings","namedSchemas","inlineCounter","input","split","Boolean","part","charAt","toUpperCase","slice","join","s","splitByTag","models","routes","routeTags","routesByTag","Map","route","tag","get","group","push","set","modelsByTag","tagRoutes","refs","Set","collectRouteRefs","modelNameToModel","map","m","name","modelAssignment","model","tags","has","length","collectModelRefs","ref","currentTag","otherTags","entries","filter","t","r","result","allTags","keys","values","tagModels","filename","sanitizeFilename","kind","meta","area","services","file","mergeIntoSingle","params","collectParamSourceRefs","op","operations","query","headers","request","body","bodies","collectTypeRefs","bodyType","resp","responses","source","add","Array","isArray","param","type","item","items","key","value","member","members","field","fields","inner","bases","b","toLowerCase","replace","INDENT","IDENT_RE","singleLineComment","text","replace","trim","quoteEnumValue","value","test","includes","astToCk","root","options","includeComments","ctx","parts","optionsBlock","serializeOptions","push","model","models","serializeModel","route","routes","serializeRoute","join","hasKeys","Object","keys","meta","length","hasServices","services","hasSecurity","security","undefined","lines","key","entries","name","path","sec","policy","prefixes","inputCase","mode","deprecated","prefix","comment","description","type","serializeType","bases","field","fields","serializeField","depth","indent","repeat","optional","visibility","typeStr","nullable","typeContainsNull","defaultVal","default","serializeDefault","kind","members","some","String","serializeScalar","serializeArray","items","map","values","serializeLiteral","discriminator","serializeInlineObject","inner","args","len","min","max","regex","format","item","modePrefix","modStr","serializeModifiers","modifiers","params","serializeParamSource","paramsMode","serializeSecurityBlock","op","operations","serializeOperation","method","service","sdk","signature","sigComment","signatureDescription","signaturePolicy","query","queryMode","headers","headersMode","request","serializeRequest","responses","serializeResponses","keyword","source","node","modeStr","param","nodes","body","bodies","contentType","bodyType","resp","hasHeaders","statusCode","h","opt","trail","policyDescription","readFileSync","parse","parseYaml","WarningCollector","warnings","onWarning","warn","path","message","add","severity","info","warning","push","convertOpenApiToCk","options","split","includeComments","warnings","WarningCollector","onWarning","rawDoc","parseInput","input","doc","normalize","schemas","sanitizeSchemaNames","circularRefs","detectCircularRefs","extractedModels","schemaCtx","path","namedSchemas","inlineCounter","models","schemasToModels","routes","routeTags","pathsToRoutes","globalSecurity","security","files","Map","ckRoots","splitByTag","filename","root","set","astToCk","mergeIntoSingle","content","readFileSync","parseJsonOrYaml","JSON","parse","parseYaml","original","components","sanitized","nameMap","name","Object","keys","clean","sanitizeName","warn","i","size","updateRefs","obj","Array","isArray","item","record","$ref","match","has","get","value","values"]}
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  schemasToModels,
12
12
  serializeType,
13
13
  splitByTag
14
- } from "./chunk-76CPOLZK.js";
14
+ } from "./chunk-JPI3AQ7V.js";
15
15
  export {
16
16
  astToCk,
17
17
  convertOpenApiToCk,
@@ -1 +1 @@
1
- {"version":3,"file":"paths-to-ast.d.ts","sourceRoot":"","sources":["../src/paths-to-ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,WAAW,EAOX,SAAS,EAGZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACR,kBAAkB,EAMrB,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAOtD,MAAM,WAAW,YAAY;IACzB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,wEAAwE;IACxE,eAAe,EAAE,SAAS,EAAE,CAAC;IAC7B,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;CAC/C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY,GAAG;IAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;CAAE,CAexI"}
1
+ {"version":3,"file":"paths-to-ast.d.ts","sourceRoot":"","sources":["../src/paths-to-ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,WAAW,EAQX,SAAS,EAGZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACR,kBAAkB,EAMrB,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAOtD,MAAM,WAAW,YAAY;IACzB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,wEAAwE;IACxE,eAAe,EAAE,SAAS,EAAE,CAAC;IAC7B,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;CAC/C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY,GAAG;IAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;CAAE,CAexI"}
package/dist/plugin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __name,
3
3
  convertOpenApiToCk
4
- } from "./chunk-76CPOLZK.js";
4
+ } from "./chunk-JPI3AQ7V.js";
5
5
 
6
6
  // src/plugin.ts
7
7
  import { writeFileSync, mkdirSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractkit/openapi-to-ck",
3
- "version": "0.9.3",
3
+ "version": "0.10.0",
4
4
  "description": "Convert OpenAPI specs (2.0/3.0/3.1) to Contract Kit .ck files",
5
5
  "author": {
6
6
  "name": "Marooned Software",
@@ -29,11 +29,11 @@
29
29
  "dependencies": {
30
30
  "@scalar/openapi-parser": "^0.26.1",
31
31
  "yaml": "^2.8.3",
32
- "@contractkit/core": "0.24.0"
32
+ "@contractkit/core": "0.25.0"
33
33
  },
34
34
  "devDependencies": {
35
- "@repo/config-typescript": "0.1.0",
36
- "@repo/config-eslint": "0.3.1"
35
+ "@repo/config-eslint": "0.3.1",
36
+ "@repo/config-typescript": "0.1.0"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "tsup src/index.ts src/plugin.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly --declaration",
package/src/ast-to-ck.ts CHANGED
@@ -423,12 +423,12 @@ function serializeResponses(lines: string[], responses: OpResponseNode[], depth:
423
423
  const indent = INDENT.repeat(depth);
424
424
  lines.push(`${indent}response: {`);
425
425
  for (const resp of responses) {
426
- const hasBody = resp.bodyType && resp.contentType;
426
+ const bodies = resp.bodies;
427
427
  const hasHeaders = resp.headers && resp.headers.length > 0;
428
- if (hasBody || hasHeaders) {
428
+ if (bodies.length > 0 || hasHeaders) {
429
429
  lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}: {`);
430
- if (hasBody) {
431
- lines.push(`${INDENT.repeat(depth + 2)}${resp.contentType}: ${serializeType(resp.bodyType!)}`);
430
+ for (const body of bodies) {
431
+ lines.push(`${INDENT.repeat(depth + 2)}${body.contentType}: ${serializeType(body.bodyType)}`);
432
432
  }
433
433
  if (hasHeaders) {
434
434
  lines.push(`${INDENT.repeat(depth + 2)}headers: {`);
@@ -4,6 +4,7 @@ import type {
4
4
  OpParamNode,
5
5
  OpRequestNode,
6
6
  OpResponseNode,
7
+ OpResponseBodyNode,
7
8
  OpResponseHeaderNode,
8
9
  HttpMethod,
9
10
  ModelNode,
@@ -266,27 +267,29 @@ function responseToNode(
266
267
  ctx: PathsContext,
267
268
  ): OpResponseNode {
268
269
  const headers = convertResponseHeaders(resp.headers, schemaCtx);
269
-
270
- if (!resp.content) {
271
- return headers ? { statusCode, headers } : { statusCode };
272
- }
273
-
274
- // Pick the first content type
275
- const [contentType, mediaType] = Object.entries(resp.content)[0] ?? [];
276
- if (!contentType || !mediaType?.schema) {
277
- return headers ? { statusCode, headers } : { statusCode };
270
+ const empty = (): OpResponseNode => ({ statusCode, bodies: [], ...(headers ? { headers, hasBlock: true } : {}) });
271
+
272
+ if (!resp.content) return empty();
273
+
274
+ // Every declared content type is kept — `.ck` can express several mimes for one status, so
275
+ // there is no reason to narrow a spec down to its first one on the way in.
276
+ const bodies: OpResponseBodyNode[] = [];
277
+ for (const [contentType, mediaType] of Object.entries(resp.content)) {
278
+ if (!mediaType?.schema) continue;
279
+ // The extracted model is named for the status; a second mime for the same status reuses
280
+ // that name rather than minting a near-duplicate.
281
+ const suffix = bodies.length === 0 ? '' : toPascalCase(contentType.replace(/[^a-z0-9]+/gi, ' '));
282
+ const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Response${statusCode}${suffix}`, schemaCtx);
283
+ if (model) ctx.extractedModels.push(model);
284
+ bodies.push({ contentType, bodyType: typeNode });
278
285
  }
279
286
 
280
- const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Response${statusCode}`, schemaCtx);
281
-
282
- if (model) {
283
- ctx.extractedModels.push(model);
284
- }
287
+ if (bodies.length === 0) return empty();
285
288
 
286
289
  return {
287
290
  statusCode,
288
- contentType: contentType as 'application/json',
289
- bodyType: typeNode,
291
+ bodies,
292
+ hasBlock: true,
290
293
  ...(headers ? { headers } : {}),
291
294
  };
292
295
  }
@@ -127,7 +127,7 @@ function collectRouteRefs(route: OpRouteNode, refs: Set<string>): void {
127
127
  for (const body of op.request.bodies) collectTypeRefs(body.bodyType, refs);
128
128
  }
129
129
  for (const resp of op.responses) {
130
- if (resp.bodyType) collectTypeRefs(resp.bodyType, refs);
130
+ for (const body of resp.bodies) collectTypeRefs(body.bodyType, refs);
131
131
  }
132
132
  }
133
133
  }
@@ -155,6 +155,38 @@ describe('convertOpenApiToCk', () => {
155
155
  });
156
156
  });
157
157
 
158
+ describe('several mimes for one status', () => {
159
+ it('keeps every content entry rather than narrowing to the first', async () => {
160
+ const result = await convertOpenApiToCk({
161
+ input: {
162
+ openapi: '3.1.0',
163
+ info: { title: 'Art', version: '1.0' },
164
+ paths: {
165
+ '/art': {
166
+ get: {
167
+ operationId: 'getArt',
168
+ responses: {
169
+ '200': {
170
+ description: 'OK',
171
+ content: {
172
+ 'image/png': { schema: { type: 'string', format: 'binary' } },
173
+ 'image/jpeg': { schema: { type: 'string', format: 'binary' } },
174
+ },
175
+ },
176
+ },
177
+ },
178
+ },
179
+ },
180
+ },
181
+ split: 'single',
182
+ });
183
+
184
+ const content = result.files.get('api.ck')!;
185
+ expect(content).toContain('image/png: binary');
186
+ expect(content).toContain('image/jpeg: binary');
187
+ });
188
+ });
189
+
158
190
  describe('response headers', () => {
159
191
  it('lifts OpenAPI 3.x response headers into a typed headers block', async () => {
160
192
  const result = await convertOpenApiToCk({
package/tests/helpers.ts CHANGED
@@ -126,7 +126,8 @@ export function opRequest(bodyType: ContractTypeNode, contentType: string = 'app
126
126
  }
127
127
 
128
128
  export function opResponse(statusCode: number, bodyType?: ContractTypeNode, contentType?: 'application/json'): OpResponseNode {
129
- return { statusCode, contentType, bodyType };
129
+ const bodies = bodyType === undefined ? [] : [{ contentType: contentType ?? 'application/json', bodyType }];
130
+ return { statusCode, bodies, ...(bodyType !== undefined ? { hasBlock: true } : {}) };
130
131
  }
131
132
 
132
133
  /** Normalize a raw param value (old bare format or new discriminated union) to ParamSource. */
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/normalize.ts","../src/circular-refs.ts","../src/schema-to-ast.ts","../src/paths-to-ast.ts","../src/tag-splitter.ts","../src/ast-to-ck.ts","../src/convert.ts","../src/warnings.ts"],"sourcesContent":["import type { NormalizedDocument } from './types.js';\nimport type { WarningCollector } from './warnings.js';\n\n/**\n * Detects the OpenAPI version from a parsed document and normalizes it to a\n * 3.1-like shape. Swagger 2.0 and OpenAPI 3.0 documents are transformed\n * so that downstream code only needs to handle one schema dialect.\n *\n * Uses @scalar/openapi-parser's `upgrade()` for the heavy lifting when\n * available, with manual fallbacks for edge cases.\n */\nexport function normalize(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const version = detectVersion(doc);\n\n if (version === '2.0') {\n return normalizeSwagger2(doc, warnings);\n }\n if (version === '3.0') {\n return normalizeOas30(doc as unknown as NormalizedDocument, warnings);\n }\n // 3.1+ — already in target shape\n return doc as unknown as NormalizedDocument;\n}\n\nfunction detectVersion(doc: Record<string, unknown>): '2.0' | '3.0' | '3.1' {\n if (typeof doc.swagger === 'string' && doc.swagger.startsWith('2')) return '2.0';\n if (typeof doc.openapi === 'string') {\n if (doc.openapi.startsWith('3.0')) return '3.0';\n }\n return '3.1';\n}\n\n// ─── Swagger 2.0 → 3.1 ───────────────────────────────────────────────────\n\nfunction normalizeSwagger2(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const info = (doc.info as Record<string, unknown>) ?? { title: 'Untitled', version: '0.0.0' };\n const basePath = (doc.basePath as string) ?? '';\n const schemes = (doc.schemes as string[]) ?? ['https'];\n const host = (doc.host as string) ?? 'localhost';\n const globalConsumes = (doc.consumes as string[]) ?? ['application/json'];\n const globalProduces = (doc.produces as string[]) ?? ['application/json'];\n\n const result: NormalizedDocument = {\n openapi: '3.1.0',\n info: {\n title: (info.title as string) ?? 'Untitled',\n version: (info.version as string) ?? '0.0.0',\n description: info.description as string | undefined,\n },\n servers: [{ url: `${schemes[0]}://${host}${basePath}` }],\n paths: {},\n components: {\n schemas: {},\n securitySchemes: {},\n },\n tags: (doc.tags as NormalizedDocument['tags']) ?? [],\n };\n\n // Convert definitions → components/schemas\n const definitions = (doc.definitions as Record<string, unknown>) ?? {};\n for (const [name, schema] of Object.entries(definitions)) {\n result.components!.schemas![name] = normalizeNullable30(schema as Record<string, unknown>);\n }\n\n // Convert securityDefinitions → components/securitySchemes\n const secDefs = (doc.securityDefinitions as Record<string, unknown>) ?? {};\n for (const [name, scheme] of Object.entries(secDefs)) {\n result.components!.securitySchemes![name] = convertSecurityScheme2(scheme as Record<string, unknown>);\n }\n\n // Convert paths\n const paths = (doc.paths as Record<string, Record<string, unknown>>) ?? {};\n for (const [path, pathItem] of Object.entries(paths)) {\n result.paths![path] = normalizePathItem2(pathItem, globalConsumes, globalProduces, warnings);\n }\n\n // Global security\n if (doc.security) {\n result.security = doc.security as Record<string, string[]>[];\n }\n\n return result;\n}\n\nfunction normalizePathItem2(\n pathItem: Record<string, unknown>,\n globalConsumes: string[],\n globalProduces: string[],\n warnings: WarningCollector,\n): Record<string, unknown> {\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];\n const normalized: Record<string, unknown> = {};\n\n // Path-level parameters\n const pathParams = (pathItem.parameters as unknown[]) ?? [];\n\n for (const method of methods) {\n const op = pathItem[method] as Record<string, unknown> | undefined;\n if (!op) continue;\n\n const opConsumes = (op.consumes as string[]) ?? globalConsumes;\n const opProduces = (op.produces as string[]) ?? globalProduces;\n const params = [...pathParams, ...((op.parameters as unknown[]) ?? [])];\n\n // Separate body params from others\n const nonBodyParams: unknown[] = [];\n let requestBody: Record<string, unknown> | undefined;\n\n for (const param of params as Record<string, unknown>[]) {\n if (param.in === 'body') {\n const contentType = opConsumes[0] ?? 'application/json';\n requestBody = {\n description: param.description,\n required: param.required ?? true,\n content: {\n [contentType]: {\n schema: normalizeNullable30((param.schema as Record<string, unknown>) ?? {}),\n },\n },\n };\n } else if (param.in === 'formData') {\n warnings.info(`#/paths/${encodePathSegment(method)}`, 'formData parameters converted to multipart/form-data requestBody');\n // Collect formData params into a schema\n if (!requestBody) {\n requestBody = {\n content: {\n 'multipart/form-data': {\n schema: { type: 'object', properties: {}, required: [] as string[] },\n },\n },\n };\n }\n const formSchema = (requestBody.content as Record<string, Record<string, unknown>>)['multipart/form-data']!.schema as Record<\n string,\n unknown\n >;\n const props = formSchema.properties as Record<string, unknown>;\n props[param.name as string] = normalizeNullable30(param as Record<string, unknown>);\n if (param.required) {\n (formSchema.required as string[]).push(param.name as string);\n }\n } else {\n // Convert param schema\n const normalizedParam = { ...param };\n if (param.type) {\n normalizedParam.schema = normalizeNullable30({\n type: param.type,\n format: param.format,\n enum: param.enum,\n items: param.items,\n default: param.default,\n minimum: param.minimum,\n maximum: param.maximum,\n minLength: param.minLength,\n maxLength: param.maxLength,\n pattern: param.pattern,\n } as Record<string, unknown>);\n delete normalizedParam.type;\n delete normalizedParam.format;\n delete normalizedParam.enum;\n delete normalizedParam.items;\n }\n nonBodyParams.push(normalizedParam);\n }\n }\n\n // Convert responses\n const responses: Record<string, unknown> = {};\n const opResponses = (op.responses as Record<string, Record<string, unknown>>) ?? {};\n for (const [code, resp] of Object.entries(opResponses)) {\n const contentType = opProduces[0] ?? 'application/json';\n const headers = convertResponseHeaders2(resp.headers as Record<string, Record<string, unknown>> | undefined);\n const responseEntry: Record<string, unknown> = {\n description: resp.description ?? '',\n };\n if (resp.schema) {\n responseEntry.content = {\n [contentType]: {\n schema: normalizeNullable30(resp.schema as Record<string, unknown>),\n },\n };\n }\n if (headers) {\n responseEntry.headers = headers;\n }\n responses[code] = responseEntry;\n }\n\n normalized[method] = {\n operationId: op.operationId,\n summary: op.summary,\n description: op.description,\n tags: op.tags,\n parameters: nonBodyParams.length > 0 ? nonBodyParams : undefined,\n requestBody,\n responses,\n security: op.security,\n deprecated: op.deprecated,\n };\n }\n\n return normalized;\n}\n\n/**\n * Convert Swagger 2.0 response headers to a 3.x-shaped Header Object map.\n * 2.0 stores `type`/`format`/`items` inline on the header; 3.x wraps the same fields under `schema`.\n */\nfunction convertResponseHeaders2(\n headers: Record<string, Record<string, unknown>> | undefined,\n): Record<string, Record<string, unknown>> | undefined {\n if (!headers) return undefined;\n const out: Record<string, Record<string, unknown>> = {};\n for (const [name, header] of Object.entries(headers)) {\n if (!header || typeof header !== 'object') continue;\n const { description, type, format, items, ...rest } = header;\n const schema: Record<string, unknown> = { ...rest };\n if (type !== undefined) schema.type = type;\n if (format !== undefined) schema.format = format;\n if (items !== undefined) schema.items = items;\n const normalized: Record<string, unknown> = {};\n if (description !== undefined) normalized.description = description;\n if (Object.keys(schema).length > 0) normalized.schema = normalizeNullable30(schema);\n out[name] = normalized;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction convertSecurityScheme2(scheme: Record<string, unknown>): unknown {\n const type = scheme.type as string;\n if (type === 'basic') {\n return { type: 'http', scheme: 'basic' };\n }\n if (type === 'apiKey') {\n return { type: 'apiKey', name: scheme.name, in: scheme.in };\n }\n if (type === 'oauth2') {\n const flow = scheme.flow as string;\n const flows: Record<string, unknown> = {};\n if (flow === 'implicit') {\n flows.implicit = { authorizationUrl: scheme.authorizationUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'password') {\n flows.password = { tokenUrl: scheme.tokenUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'application') {\n flows.clientCredentials = { tokenUrl: scheme.tokenUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'accessCode') {\n flows.authorizationCode = {\n authorizationUrl: scheme.authorizationUrl,\n tokenUrl: scheme.tokenUrl,\n scopes: scheme.scopes ?? {},\n };\n }\n return { type: 'oauth2', flows };\n }\n return scheme;\n}\n\n// ─── OpenAPI 3.0 → 3.1 ───────────────────────────────────────────────────\n\nfunction normalizeOas30(doc: NormalizedDocument, _warnings: WarningCollector): NormalizedDocument {\n // Walk all schemas and convert `nullable: true` to type arrays\n if (doc.components?.schemas) {\n for (const [name, schema] of Object.entries(doc.components.schemas)) {\n doc.components.schemas[name] = normalizeNullable30(schema as Record<string, unknown>);\n }\n }\n\n // Walk paths and normalize inline schemas\n if (doc.paths) {\n for (const pathItem of Object.values(doc.paths)) {\n normalizePathItemSchemas(pathItem as Record<string, unknown>);\n }\n }\n\n doc.openapi = '3.1.0';\n return doc;\n}\n\nfunction normalizePathItemSchemas(pathItem: Record<string, unknown>): void {\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];\n for (const method of methods) {\n const op = pathItem[method] as Record<string, unknown> | undefined;\n if (!op) continue;\n\n // Normalize parameter schemas\n const params = (op.parameters as Record<string, unknown>[]) ?? [];\n for (const param of params) {\n if (param.schema) {\n param.schema = normalizeNullable30(param.schema as Record<string, unknown>);\n }\n }\n\n // Normalize requestBody schemas\n const reqBody = op.requestBody as Record<string, unknown> | undefined;\n if (reqBody?.content) {\n for (const mediaType of Object.values(reqBody.content as Record<string, Record<string, unknown>>)) {\n if (mediaType.schema) {\n mediaType.schema = normalizeNullable30(mediaType.schema as Record<string, unknown>);\n }\n }\n }\n\n // Normalize response schemas\n const responses = (op.responses as Record<string, Record<string, unknown>>) ?? {};\n for (const resp of Object.values(responses)) {\n if (resp.content) {\n for (const mediaType of Object.values(resp.content as Record<string, Record<string, unknown>>)) {\n if (mediaType.schema) {\n mediaType.schema = normalizeNullable30(mediaType.schema as Record<string, unknown>);\n }\n }\n }\n }\n }\n}\n\n/**\n * Recursively converts OAS 3.0 `nullable: true` to OAS 3.1 `type: [T, \"null\"]`.\n * Also normalizes nested schemas (properties, items, allOf, etc.).\n */\nfunction normalizeNullable30(schema: Record<string, unknown>): Record<string, unknown> {\n if (!schema || typeof schema !== 'object') return schema;\n\n const result = { ...schema };\n\n // Convert nullable: true → type array with null\n if (result.nullable === true && typeof result.type === 'string') {\n result.type = [result.type, 'null'];\n delete result.nullable;\n }\n\n // Convert $ref alongside other properties (OAS 3.0 $ref with siblings was invalid,\n // but OAS 3.1 allows it — no conversion needed, just keep walking)\n\n // Recurse into nested schemas\n if (result.properties && typeof result.properties === 'object') {\n const props = result.properties as Record<string, Record<string, unknown>>;\n for (const [key, val] of Object.entries(props)) {\n props[key] = normalizeNullable30(val);\n }\n }\n if (result.items && typeof result.items === 'object' && !Array.isArray(result.items)) {\n result.items = normalizeNullable30(result.items as Record<string, unknown>);\n }\n if (result.additionalProperties && typeof result.additionalProperties === 'object') {\n result.additionalProperties = normalizeNullable30(result.additionalProperties as Record<string, unknown>);\n }\n for (const combiner of ['allOf', 'oneOf', 'anyOf'] as const) {\n if (Array.isArray(result[combiner])) {\n result[combiner] = (result[combiner] as Record<string, unknown>[]).map(normalizeNullable30);\n }\n }\n\n return result;\n}\n\nfunction encodePathSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n","/**\n * Detects circular $ref chains in OpenAPI schema definitions.\n * Returns the set of schema names that participate in cycles.\n * These should be wrapped in `lazy()` in the output .ck.\n */\nexport function detectCircularRefs(schemas: Record<string, unknown>): Set<string> {\n const circular = new Set<string>();\n const visiting = new Set<string>(); // current DFS path\n const visited = new Set<string>(); // fully explored\n\n function visit(name: string): void {\n if (visited.has(name)) return;\n if (visiting.has(name)) {\n circular.add(name);\n return;\n }\n\n visiting.add(name);\n const schema = schemas[name];\n if (schema && typeof schema === 'object') {\n for (const ref of collectRefs(schema as Record<string, unknown>)) {\n const refName = extractRefName(ref);\n if (refName && schemas[refName]) {\n visit(refName);\n }\n }\n }\n visiting.delete(name);\n visited.add(name);\n }\n\n for (const name of Object.keys(schemas)) {\n visit(name);\n }\n\n return circular;\n}\n\n/**\n * Recursively collects all $ref strings from a schema object.\n */\nfunction collectRefs(obj: Record<string, unknown>): string[] {\n const refs: string[] = [];\n\n function walk(val: unknown): void {\n if (!val || typeof val !== 'object') return;\n if (Array.isArray(val)) {\n for (const item of val) walk(item);\n return;\n }\n const record = val as Record<string, unknown>;\n if (typeof record.$ref === 'string') {\n refs.push(record.$ref);\n }\n for (const v of Object.values(record)) {\n walk(v);\n }\n }\n\n walk(obj);\n return refs;\n}\n\n/**\n * Extracts the schema name from a $ref like \"#/components/schemas/Foo\"\n * or \"#/definitions/Foo\" (Swagger 2.0 after normalization still uses components).\n */\nexport function extractRefName(ref: string): string | undefined {\n const match = ref.match(/^#\\/(?:components\\/schemas|definitions)\\/(.+)$/);\n return match?.[1];\n}\n","import type { ContractTypeNode, ScalarTypeNode, ModelNode, FieldNode, SourceLocation } from '@contractkit/core';\nimport type { NormalizedSchema } from './types.js';\nimport { extractRefName } from './circular-refs.js';\nimport type { WarningCollector } from './warnings.js';\n\n// ─── Conversion Context ───────────────────────────────────────────────────\n\nexport interface SchemaContext {\n /** Schema names involved in circular references — use lazy() for these. */\n circularRefs: Set<string>;\n /** Warning collector for unsupported features. */\n warnings: WarningCollector;\n /** Current JSON pointer path (for warnings). */\n path: string;\n /** Whether to include descriptions. */\n includeComments: boolean;\n /** All named schemas (for inline extraction). */\n namedSchemas: Record<string, NormalizedSchema>;\n /** Extracted inline models (accumulated during conversion). */\n extractedModels: ModelNode[];\n /** Counter for generating unique names for inline models. */\n inlineCounter: number;\n}\n\nconst LOC: SourceLocation = { file: '', line: 0 };\n\n// ─── Format → Scalar Name Mapping ────────────────────────────────────────\n\nconst FORMAT_TO_SCALAR: Record<string, ScalarTypeNode['name']> = {\n email: 'email',\n uri: 'url',\n url: 'url',\n uuid: 'uuid',\n date: 'date',\n 'date-time': 'datetime',\n time: 'time',\n binary: 'binary',\n int64: 'bigint',\n};\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\n/**\n * Convert all named schemas in components/schemas to ModelNodes.\n */\nexport function schemasToModels(schemas: Record<string, NormalizedSchema>, ctx: SchemaContext): ModelNode[] {\n const models: ModelNode[] = [];\n\n for (const [name, schema] of Object.entries(schemas)) {\n const modelCtx = { ...ctx, path: `#/components/schemas/${name}` };\n const model = schemaToModel(name, schema, modelCtx);\n if (model) models.push(model);\n }\n\n // Append any inline models extracted during conversion\n models.push(...ctx.extractedModels);\n\n return models;\n}\n\n/**\n * Convert a named schema to a ModelNode.\n */\nfunction schemaToModel(name: string, schema: NormalizedSchema, ctx: SchemaContext): ModelNode | null {\n warnUnsupported(schema, ctx);\n\n const description = ctx.includeComments ? schema.description : undefined;\n\n // allOf with exactly 2 members, one being a $ref → inheritance\n if (schema.allOf && schema.allOf.length === 2) {\n const [first, second] = schema.allOf;\n const refMember = first?.$ref ? first : second?.$ref ? second : null;\n const objectMember = first?.$ref ? second : first;\n\n if (refMember?.$ref && objectMember?.properties) {\n const baseName = extractRefName(refMember.$ref);\n if (baseName) {\n const fields = schemaPropertiesToFields(objectMember, ctx);\n return {\n kind: 'model',\n name,\n bases: [baseName],\n fields,\n description,\n loc: LOC,\n };\n }\n }\n }\n\n // Object with properties → struct\n if (schema.properties || (schema.type === 'object' && !schema.additionalProperties)) {\n const fields = schemaPropertiesToFields(schema, ctx);\n return {\n kind: 'model',\n name,\n fields,\n description,\n loc: LOC,\n };\n }\n\n // Otherwise → type alias\n const typeNode = schemaToTypeNode(schema, ctx);\n return {\n kind: 'model',\n name,\n fields: [],\n type: typeNode,\n description,\n loc: LOC,\n };\n}\n\n/**\n * Convert an OpenAPI schema to a ContractTypeNode.\n */\nexport function schemaToTypeNode(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // $ref\n if (schema.$ref) {\n const refName = extractRefName(schema.$ref);\n if (refName) {\n if (ctx.circularRefs.has(refName)) {\n return { kind: 'lazy', inner: { kind: 'ref', name: refName } };\n }\n return { kind: 'ref', name: refName };\n }\n ctx.warnings.warn(ctx.path, `Unresolvable $ref: ${schema.$ref}`);\n return { kind: 'scalar', name: 'unknown' };\n }\n\n // const\n if (schema.const !== undefined) {\n return { kind: 'literal', value: schema.const as string | number | boolean };\n }\n\n // enum\n if (schema.enum) {\n return { kind: 'enum', values: schema.enum.map(String) };\n }\n\n // oneOf / anyOf → union (or discriminatedUnion when discriminator.propertyName is set)\n if (schema.oneOf && schema.oneOf.length > 0) {\n if (schema.discriminator?.propertyName) {\n return toDiscriminatedUnion(schema.oneOf, schema.discriminator.propertyName, ctx);\n }\n return toUnion(schema.oneOf, ctx);\n }\n if (schema.anyOf && schema.anyOf.length > 0) {\n if (schema.discriminator?.propertyName) {\n return toDiscriminatedUnion(schema.anyOf, schema.discriminator.propertyName, ctx);\n }\n return toUnion(schema.anyOf, ctx);\n }\n\n // allOf → intersection\n if (schema.allOf && schema.allOf.length > 0) {\n if (schema.allOf.length === 1) {\n return schemaToTypeNode(schema.allOf[0]!, ctx);\n }\n return {\n kind: 'intersection',\n members: schema.allOf.map(s => schemaToTypeNode(s, ctx)),\n };\n }\n\n // Handle nullable type arrays: [string, null] → nullable\n const types = normalizeTypeField(schema);\n\n if (types === null) {\n // No type information at all\n if (schema.properties) {\n return schemaToInlineObject(schema, ctx);\n }\n return { kind: 'scalar', name: 'unknown' };\n }\n\n const { baseType, nullable } = types;\n\n let typeNode: ContractTypeNode;\n\n switch (baseType) {\n case 'string':\n typeNode = stringSchemaToType(schema);\n break;\n case 'integer':\n typeNode = integerSchemaToType(schema);\n break;\n case 'number':\n typeNode = numberSchemaToType(schema);\n break;\n case 'boolean':\n typeNode = { kind: 'scalar', name: 'boolean' };\n break;\n case 'null':\n typeNode = { kind: 'scalar', name: 'null' };\n break;\n case 'array':\n typeNode = arraySchemaToType(schema, ctx);\n break;\n case 'object':\n typeNode = objectSchemaToType(schema, ctx);\n break;\n default:\n ctx.warnings.warn(ctx.path, `Unknown type: ${baseType}`);\n typeNode = { kind: 'scalar', name: 'unknown' };\n }\n\n if (nullable) {\n return { kind: 'union', members: [typeNode, { kind: 'scalar', name: 'null' }] };\n }\n\n return typeNode;\n}\n\n// ─── Type-Specific Converters ─────────────────────────────────────────────\n\nfunction stringSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n // Check format first\n if (schema.format) {\n const scalarName = FORMAT_TO_SCALAR[schema.format];\n if (scalarName) {\n return { kind: 'scalar', name: scalarName };\n }\n }\n\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minLength !== undefined && schema.maxLength !== undefined && schema.minLength === schema.maxLength) {\n mods.len = schema.minLength;\n } else {\n if (schema.minLength !== undefined) mods.min = schema.minLength;\n if (schema.maxLength !== undefined) mods.max = schema.maxLength;\n }\n if (schema.pattern) mods.regex = `/${schema.pattern}/`;\n if (schema.format && !FORMAT_TO_SCALAR[schema.format]) mods.format = schema.format;\n\n return { kind: 'scalar', name: 'string', ...mods };\n}\n\nfunction integerSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n const name: ScalarTypeNode['name'] = schema.format === 'int64' ? 'bigint' : 'int';\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minimum !== undefined) mods.min = schema.minimum;\n if (schema.maximum !== undefined) mods.max = schema.maximum;\n return { kind: 'scalar', name, ...mods };\n}\n\nfunction numberSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minimum !== undefined) mods.min = schema.minimum;\n if (schema.maximum !== undefined) mods.max = schema.maximum;\n return { kind: 'scalar', name: 'number', ...mods };\n}\n\nfunction arraySchemaToType(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // Tuple: prefixItems (OAS 3.1)\n if (schema.prefixItems && schema.prefixItems.length > 0) {\n return {\n kind: 'tuple',\n items: schema.prefixItems.map(s => schemaToTypeNode(s, ctx)),\n };\n }\n\n const item = schema.items ? schemaToTypeNode(schema.items, ctx) : { kind: 'scalar' as const, name: 'unknown' as const };\n const mods: { min?: number; max?: number } = {};\n if (schema.minItems !== undefined) mods.min = schema.minItems;\n if (schema.maxItems !== undefined) mods.max = schema.maxItems;\n\n return { kind: 'array', item, ...mods };\n}\n\nfunction objectSchemaToType(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // Record type: additionalProperties with no named properties\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && !schema.properties) {\n return {\n kind: 'record',\n key: { kind: 'scalar', name: 'string' },\n value: schemaToTypeNode(schema.additionalProperties, ctx),\n };\n }\n\n // Object with properties → inline object or extracted model\n if (schema.properties) {\n return schemaToInlineObject(schema, ctx);\n }\n\n // Empty object\n return { kind: 'scalar', name: 'object' };\n}\n\nfunction schemaToInlineObject(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n const fields = schemaPropertiesToFields(schema, ctx);\n return { kind: 'inlineObject', fields };\n}\n\n// ─── Field Conversion ─────────────────────────────────────────────────────\n\nfunction schemaPropertiesToFields(schema: NormalizedSchema, ctx: SchemaContext): FieldNode[] {\n const properties = schema.properties ?? {};\n const required = new Set(schema.required ?? []);\n const fields: FieldNode[] = [];\n\n for (const [name, propSchema] of Object.entries(properties)) {\n const propCtx = { ...ctx, path: `${ctx.path}/properties/${name}` };\n const fieldType = schemaToTypeNode(propSchema, propCtx);\n\n // Determine nullable from the type (if it's a union with null)\n let nullable = false;\n let effectiveType = fieldType;\n if (fieldType.kind === 'union') {\n const nonNull = fieldType.members.filter(m => !(m.kind === 'scalar' && m.name === 'null'));\n if (nonNull.length < fieldType.members.length) {\n nullable = true;\n effectiveType = nonNull.length === 1 ? nonNull[0]! : { kind: 'union', members: nonNull };\n }\n }\n\n const visibility = propSchema.readOnly ? ('readonly' as const) : propSchema.writeOnly ? ('writeonly' as const) : ('normal' as const);\n\n fields.push({\n name,\n optional: !required.has(name),\n nullable,\n visibility,\n type: effectiveType,\n default: propSchema.default as string | number | boolean | undefined,\n deprecated: propSchema.deprecated,\n description: ctx.includeComments ? propSchema.description : undefined,\n loc: LOC,\n });\n }\n\n return fields;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction normalizeTypeField(schema: NormalizedSchema): { baseType: string; nullable: boolean } | null {\n if (!schema.type) return null;\n\n if (typeof schema.type === 'string') {\n return { baseType: schema.type, nullable: false };\n }\n\n if (Array.isArray(schema.type)) {\n const types = schema.type as string[];\n const nonNull = types.filter(t => t !== 'null');\n const nullable = types.includes('null');\n if (nonNull.length === 1) {\n return { baseType: nonNull[0]!, nullable };\n }\n // Multiple non-null types — unusual but handle gracefully\n if (nonNull.length === 0) {\n return { baseType: 'null', nullable: false };\n }\n // Multiple types → treat as unknown\n return { baseType: nonNull[0]!, nullable };\n }\n\n return null;\n}\n\nfunction toUnion(schemas: NormalizedSchema[], ctx: SchemaContext): ContractTypeNode {\n const members = schemas.map(s => schemaToTypeNode(s, ctx));\n if (members.length === 1) return members[0]!;\n return { kind: 'union', members };\n}\n\nfunction toDiscriminatedUnion(schemas: NormalizedSchema[], discriminator: string, ctx: SchemaContext): ContractTypeNode {\n const members = schemas.map(s => schemaToTypeNode(s, ctx));\n if (members.length === 1) return members[0]!;\n return { kind: 'discriminatedUnion', discriminator, members };\n}\n\nfunction warnUnsupported(schema: NormalizedSchema, ctx: SchemaContext): void {\n if (schema.xml) ctx.warnings.warn(ctx.path, 'xml metadata is not supported, skipping');\n if (schema.externalDocs) ctx.warnings.info(ctx.path, 'externalDocs is not supported, skipping');\n if (schema.not) ctx.warnings.warn(ctx.path, 'not keyword is not supported, skipping');\n}\n\n/**\n * Extract a named model from an inline object schema (used for request/response bodies).\n */\nexport function extractInlineModel(\n schema: NormalizedSchema,\n suggestedName: string,\n ctx: SchemaContext,\n): { typeNode: ContractTypeNode; model?: ModelNode } {\n // If it's a $ref, just use the ref\n if (schema.$ref) {\n return { typeNode: schemaToTypeNode(schema, ctx) };\n }\n\n // If it's an object with properties, extract as a named model\n if (schema.properties || (schema.type === 'object' && schema.additionalProperties === undefined)) {\n const fields = schemaPropertiesToFields(schema, ctx);\n const model: ModelNode = {\n kind: 'model',\n name: suggestedName,\n fields,\n description: ctx.includeComments ? schema.description : undefined,\n loc: LOC,\n };\n return {\n typeNode: { kind: 'ref', name: suggestedName },\n model,\n };\n }\n\n // Otherwise return the type node directly\n return { typeNode: schemaToTypeNode(schema, ctx) };\n}\n\n/**\n * Sanitize an OpenAPI schema name to a valid .ck identifier (PascalCase).\n */\nexport function sanitizeName(name: string, warnings: WarningCollector): string {\n // Replace dots, hyphens, spaces, and other invalid chars with word boundaries\n const cleaned = name\n .replace(/[^a-zA-Z0-9_$]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n\n if (cleaned !== name) {\n warnings.info(`#/components/schemas/${name}`, `Schema name sanitized: \"${name}\" → \"${cleaned}\"`);\n }\n\n return cleaned || 'UnnamedSchema';\n}\n","import type {\n OpRouteNode,\n OpOperationNode,\n OpParamNode,\n OpRequestNode,\n OpResponseNode,\n OpResponseHeaderNode,\n HttpMethod,\n ModelNode,\n SourceLocation,\n SecurityNode,\n} from '@contractkit/core';\nimport type {\n NormalizedDocument,\n NormalizedPathItem,\n NormalizedOperation,\n NormalizedParameter,\n NormalizedRequestBody,\n NormalizedResponse,\n} from './types.js';\nimport { schemaToTypeNode, extractInlineModel } from './schema-to-ast.js';\nimport type { SchemaContext } from './schema-to-ast.js';\nimport type { WarningCollector } from './warnings.js';\n\nconst LOC: SourceLocation = { file: '', line: 0 };\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete'];\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\nexport interface PathsContext {\n circularRefs: Set<string>;\n warnings: WarningCollector;\n includeComments: boolean;\n namedSchemas: Record<string, unknown>;\n /** Accumulates inline models extracted from request/response bodies. */\n extractedModels: ModelNode[];\n /** Global security from the spec (for detecting explicit overrides). */\n globalSecurity?: Record<string, string[]>[];\n}\n\n/**\n * Convert OpenAPI paths to OpRouteNode[].\n * Returns routes along with a tag mapping for each route.\n */\nexport function pathsToRoutes(doc: NormalizedDocument, ctx: PathsContext): { routes: OpRouteNode[]; routeTags: Map<OpRouteNode, string> } {\n const routes: OpRouteNode[] = [];\n const routeTags = new Map<OpRouteNode, string>();\n const paths = doc.paths ?? {};\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem) continue;\n const result = pathItemToRoute(path, pathItem, ctx);\n if (result) {\n routes.push(result.route);\n routeTags.set(result.route, result.tag);\n }\n }\n\n return { routes, routeTags };\n}\n\n// ─── Path Item → Route ───────────────────────────────────────────────────\n\nfunction pathItemToRoute(path: string, pathItem: NormalizedPathItem, ctx: PathsContext): { route: OpRouteNode; tag: string } | null {\n const operations: OpOperationNode[] = [];\n let primaryTag = 'default';\n\n // Collect path-level parameters\n const pathParams = (pathItem.parameters ?? []).filter(p => p.in === 'path');\n\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n\n const opNode = operationToNode(method, op, path, ctx);\n operations.push(opNode);\n\n // Use first tag of first operation as the route's tag\n if (op.tags && op.tags.length > 0 && primaryTag === 'default') {\n primaryTag = op.tags[0]!;\n }\n }\n\n if (operations.length === 0) return null;\n\n // Build params from path-level + inferred from path template\n const params = buildPathParams(path, pathParams, pathItem, ctx);\n\n const route: OpRouteNode = {\n path,\n operations,\n loc: LOC,\n };\n\n if (params.length > 0) {\n route.params = { kind: 'params', nodes: params };\n }\n\n if (pathItem.description && ctx.includeComments) {\n route.description = pathItem.description;\n }\n\n return { route, tag: primaryTag };\n}\n\n// ─── Operation → Node ─────────────────────────────────────────────────────\n\nfunction operationToNode(method: HttpMethod, op: NormalizedOperation, path: string, ctx: PathsContext): OpOperationNode {\n const pathPrefix = `#/paths/${encodePathSegment(path)}/${method}`;\n const schemaCtx = makeSchemaCtx(ctx, pathPrefix);\n\n const node: OpOperationNode = {\n method,\n responses: [],\n loc: LOC,\n };\n\n // operationId → sdk\n if (op.operationId) {\n node.sdk = op.operationId;\n }\n\n // Description\n if (op.description && ctx.includeComments) {\n node.description = op.description;\n }\n\n // Deprecated\n if (op.deprecated) {\n node.modifiers = ['deprecated'];\n }\n\n // Query and header parameters\n const queryParams: OpParamNode[] = [];\n const headerParams: OpParamNode[] = [];\n\n for (const param of op.parameters ?? []) {\n if (param.in === 'query') {\n queryParams.push(parameterToNode(param, schemaCtx));\n } else if (param.in === 'header') {\n headerParams.push(parameterToNode(param, schemaCtx));\n }\n }\n\n if (queryParams.length > 0) {\n node.query = { kind: 'params', nodes: queryParams };\n }\n if (headerParams.length > 0) {\n node.headers = { kind: 'params', nodes: headerParams };\n }\n\n // Request body\n if (op.requestBody) {\n node.request = requestBodyToNode(op.requestBody, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n }\n\n // Responses\n const responses = op.responses ?? {};\n for (const [code, resp] of Object.entries(responses)) {\n const statusCode = parseInt(code, 10);\n if (isNaN(statusCode)) continue;\n const respNode = responseToNode(statusCode, resp, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n node.responses.push(respNode);\n }\n\n // Security\n if (op.security !== undefined) {\n node.security = convertSecurity(op.security);\n }\n\n return node;\n}\n\n// ─── Parameters ───────────────────────────────────────────────────────────\n\nfunction buildPathParams(path: string, pathLevelParams: NormalizedParameter[], pathItem: NormalizedPathItem, ctx: PathsContext): OpParamNode[] {\n const schemaCtx = makeSchemaCtx(ctx, `#/paths/${encodePathSegment(path)}`);\n\n // Collect all path params from path-level and operation-level\n const paramMap = new Map<string, NormalizedParameter>();\n\n for (const p of pathLevelParams) {\n paramMap.set(p.name, p);\n }\n\n // Also check operation-level path params\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op?.parameters) continue;\n for (const p of op.parameters) {\n if (p.in === 'path' && !paramMap.has(p.name)) {\n paramMap.set(p.name, p);\n }\n }\n }\n\n // Extract param names from path template\n const templateNames = [...path.matchAll(/\\{([^}]+)\\}/g)].map(m => m[1]!);\n\n return templateNames.map(name => {\n const param = paramMap.get(name);\n if (param) {\n return parameterToNode(param, schemaCtx);\n }\n // Infer as uuid if no schema is given\n return {\n name,\n optional: false,\n nullable: false,\n type: { kind: 'scalar' as const, name: 'string' as const },\n loc: LOC,\n };\n });\n}\n\nfunction parameterToNode(param: NormalizedParameter, ctx: SchemaContext): OpParamNode {\n const type = param.schema ? schemaToTypeNode(param.schema, ctx) : { kind: 'scalar' as const, name: 'string' as const };\n\n return {\n name: param.name,\n optional: param.in !== 'path' && !param.required,\n nullable: false,\n type,\n description: ctx.includeComments ? param.description : undefined,\n loc: LOC,\n };\n}\n\n// ─── Request Body ─────────────────────────────────────────────────────────\n\nfunction requestBodyToNode(\n reqBody: NormalizedRequestBody,\n operationName: string,\n schemaCtx: SchemaContext,\n ctx: PathsContext,\n): OpRequestNode | undefined {\n const content = reqBody.content;\n if (!content) return undefined;\n\n const supported = new Set<string>(['application/json', 'application/x-www-form-urlencoded', 'multipart/form-data']);\n const bodies: OpRequestNode['bodies'] = [];\n\n for (const [contentType, mediaType] of Object.entries(content)) {\n if (!supported.has(contentType) || !mediaType?.schema) continue;\n const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Request`, schemaCtx);\n if (model) {\n ctx.extractedModels.push(model);\n }\n bodies.push({\n contentType: contentType as OpRequestNode['bodies'][number]['contentType'],\n bodyType: typeNode,\n });\n }\n\n if (bodies.length === 0) return undefined;\n return { bodies };\n}\n\n// ─── Responses ────────────────────────────────────────────────────────────\n\nfunction responseToNode(\n statusCode: number,\n resp: NormalizedResponse,\n operationName: string,\n schemaCtx: SchemaContext,\n ctx: PathsContext,\n): OpResponseNode {\n const headers = convertResponseHeaders(resp.headers, schemaCtx);\n\n if (!resp.content) {\n return headers ? { statusCode, headers } : { statusCode };\n }\n\n // Pick the first content type\n const [contentType, mediaType] = Object.entries(resp.content)[0] ?? [];\n if (!contentType || !mediaType?.schema) {\n return headers ? { statusCode, headers } : { statusCode };\n }\n\n const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Response${statusCode}`, schemaCtx);\n\n if (model) {\n ctx.extractedModels.push(model);\n }\n\n return {\n statusCode,\n contentType: contentType as 'application/json',\n bodyType: typeNode,\n ...(headers ? { headers } : {}),\n };\n}\n\nfunction convertResponseHeaders(headers: NormalizedResponse['headers'], schemaCtx: SchemaContext): OpResponseHeaderNode[] | undefined {\n if (!headers) return undefined;\n const out: OpResponseHeaderNode[] = [];\n for (const [name, header] of Object.entries(headers)) {\n if (!header) continue;\n const type = header.schema ? schemaToTypeNode(header.schema, schemaCtx) : { kind: 'scalar' as const, name: 'string' as const };\n out.push({\n name,\n optional: !header.required,\n type,\n description: schemaCtx.includeComments ? header.description : undefined,\n });\n }\n return out.length > 0 ? out : undefined;\n}\n\n// ─── Security ─────────────────────────────────────────────────────────────\n\nfunction convertSecurity(security: Record<string, string[]>[]): SecurityNode {\n // Empty array = explicitly no security\n if (security.length === 0) {\n return 'none';\n }\n\n // The DSL's security model is simpler — OpenAPI scopes/roles don't map onto named policies,\n // so any non-empty security requirement is collapsed to \"authenticated, default policy\".\n return { loc: LOC };\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction makeSchemaCtx(ctx: PathsContext, path: string): SchemaContext {\n return {\n circularRefs: ctx.circularRefs,\n warnings: ctx.warnings,\n path,\n includeComments: ctx.includeComments,\n namedSchemas: ctx.namedSchemas as Record<string, never>,\n extractedModels: ctx.extractedModels,\n inlineCounter: 0,\n };\n}\n\nfunction toPascalCase(input: string): string {\n return input\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\nfunction encodePathSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n","import type { CkRootNode, ModelNode, OpRouteNode, ContractTypeNode } from '@contractkit/core';\n\n/**\n * Split models and routes into per-tag CkRootNode instances.\n *\n * Algorithm:\n * 1. Routes are assigned to the file of their first tag (untagged → 'default')\n * 2. Models referenced by exactly one tag go into that tag's file\n * 3. Models referenced by 2+ tags go into 'shared'\n * 4. Orphan models (not referenced by any route) go into 'shared'\n */\nexport function splitByTag(models: ModelNode[], routes: OpRouteNode[], routeTags: Map<OpRouteNode, string>): Map<string, CkRootNode> {\n // Step 1: Group routes by tag\n const routesByTag = new Map<string, OpRouteNode[]>();\n for (const route of routes) {\n const tag = routeTags.get(route) ?? 'default';\n const group = routesByTag.get(tag) ?? [];\n group.push(route);\n routesByTag.set(tag, group);\n }\n\n // Step 2: For each tag, collect which model names are referenced\n const modelsByTag = new Map<string, Set<string>>();\n for (const [tag, tagRoutes] of routesByTag) {\n const refs = new Set<string>();\n for (const route of tagRoutes) {\n collectRouteRefs(route, refs);\n }\n modelsByTag.set(tag, refs);\n }\n\n // Step 3: Determine which tag each model belongs to\n const modelNameToModel = new Map(models.map(m => [m.name, m]));\n const modelAssignment = new Map<string, string>(); // modelName → tag or 'shared'\n\n for (const model of models) {\n const tags: string[] = [];\n for (const [tag, refs] of modelsByTag) {\n if (refs.has(model.name)) {\n tags.push(tag);\n }\n }\n\n if (tags.length === 0) {\n // Orphan model → shared\n modelAssignment.set(model.name, 'shared');\n } else if (tags.length === 1) {\n // Single tag reference → that tag's file\n modelAssignment.set(model.name, tags[0]!);\n } else {\n // Multi-tag reference → shared\n modelAssignment.set(model.name, 'shared');\n }\n }\n\n // Also check transitive: models referenced by shared models should also be shared\n // (simple one-pass — could iterate to fixed point for deep chains)\n for (const model of models) {\n if (modelAssignment.get(model.name) === 'shared') {\n const refs = new Set<string>();\n collectModelRefs(model, refs);\n for (const ref of refs) {\n if (modelNameToModel.has(ref)) {\n const currentTag = modelAssignment.get(ref);\n // Only promote to shared if it was assigned to a specific tag\n // (don't override if already shared)\n if (currentTag && currentTag !== 'shared') {\n // Check if another tag also references this model\n const otherTags = [...modelsByTag.entries()].filter(([t, r]) => t !== currentTag && r.has(ref)).map(([t]) => t);\n if (otherTags.length > 0) {\n modelAssignment.set(ref, 'shared');\n }\n }\n }\n }\n }\n }\n\n // Step 4: Build CkRootNode per tag\n const result = new Map<string, CkRootNode>();\n const allTags = new Set([...routesByTag.keys(), ...new Set(modelAssignment.values())]);\n\n for (const tag of allTags) {\n const tagModels = models.filter(m => modelAssignment.get(m.name) === tag);\n const tagRoutes = routesByTag.get(tag) ?? [];\n\n if (tagModels.length === 0 && tagRoutes.length === 0) continue;\n\n const filename = sanitizeFilename(tag);\n result.set(`${filename}.ck`, {\n kind: 'ckRoot',\n meta: tag !== 'shared' ? { area: tag } : {},\n services: {},\n models: tagModels,\n routes: tagRoutes,\n file: `${filename}.ck`,\n });\n }\n\n return result;\n}\n\n/**\n * Create a single CkRootNode with all models and routes.\n */\nexport function mergeIntoSingle(models: ModelNode[], routes: OpRouteNode[], filename: string = 'api'): CkRootNode {\n return {\n kind: 'ckRoot',\n meta: {},\n services: {},\n models,\n routes,\n file: `${filename}.ck`,\n };\n}\n\n// ─── Reference Collection ─────────────────────────────────────────────────\n\nfunction collectRouteRefs(route: OpRouteNode, refs: Set<string>): void {\n if (route.params) {\n collectParamSourceRefs(route.params, refs);\n }\n for (const op of route.operations) {\n if (op.query) collectParamSourceRefs(op.query, refs);\n if (op.headers) collectParamSourceRefs(op.headers, refs);\n if (op.request) {\n for (const body of op.request.bodies) collectTypeRefs(body.bodyType, refs);\n }\n for (const resp of op.responses) {\n if (resp.bodyType) collectTypeRefs(resp.bodyType, refs);\n }\n }\n}\n\nfunction collectParamSourceRefs(source: unknown, refs: Set<string>): void {\n if (typeof source === 'string') {\n refs.add(source);\n return;\n }\n if (Array.isArray(source)) {\n for (const param of source) {\n if (param && typeof param === 'object' && 'type' in param) {\n collectTypeRefs(param.type as ContractTypeNode, refs);\n }\n }\n return;\n }\n if (source && typeof source === 'object' && 'kind' in source) {\n collectTypeRefs(source as ContractTypeNode, refs);\n }\n}\n\nfunction collectTypeRefs(type: ContractTypeNode, refs: Set<string>): void {\n switch (type.kind) {\n case 'ref':\n refs.add(type.name);\n break;\n case 'array':\n collectTypeRefs(type.item, refs);\n break;\n case 'tuple':\n for (const item of type.items) collectTypeRefs(item, refs);\n break;\n case 'record':\n collectTypeRefs(type.key, refs);\n collectTypeRefs(type.value, refs);\n break;\n case 'union':\n case 'discriminatedUnion':\n case 'intersection':\n for (const member of type.members) collectTypeRefs(member, refs);\n break;\n case 'inlineObject':\n for (const field of type.fields) collectTypeRefs(field.type, refs);\n break;\n case 'lazy':\n collectTypeRefs(type.inner, refs);\n break;\n }\n}\n\nfunction collectModelRefs(model: ModelNode, refs: Set<string>): void {\n if (model.bases) for (const b of model.bases) refs.add(b);\n if (model.type) collectTypeRefs(model.type, refs);\n for (const field of model.fields) {\n collectTypeRefs(field.type, refs);\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction sanitizeFilename(tag: string): string {\n return (\n tag\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '') || 'default'\n );\n}\n","import type {\n CkRootNode,\n ModelNode,\n FieldNode,\n ContractTypeNode,\n OpRouteNode,\n OpOperationNode,\n OpRequestNode,\n OpResponseNode,\n ParamSource,\n SecurityNode,\n SecurityFields,\n ObjectMode,\n RouteModifier,\n} from '@contractkit/core';\n\nconst INDENT = ' '; // 4 spaces\n\n/** Matches a bare identifier that needs no quoting (mirrors serializeDefault). */\nconst IDENT_RE = /^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/;\n\n/**\n * Flatten a description to a single line so it is safe to embed in a trailing\n * `# ...` comment. OpenAPI descriptions routinely contain newlines; an embedded\n * newline would terminate the comment and dump the rest as raw `.ck` source.\n */\nfunction singleLineComment(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Serialize an enum value as a `.ck` enum argument. Bare identifiers are emitted\n * as-is; anything else (spaces, punctuation) is wrapped in a string literal.\n * `.ck` string literals have no escape sequences, so when the value contains a\n * double quote we fall back to single quotes (and vice versa).\n */\nfunction quoteEnumValue(value: string): string {\n if (IDENT_RE.test(value)) return value;\n if (!value.includes('\"')) return `\"${value}\"`;\n if (!value.includes(\"'\")) return `'${value}'`;\n // Value contains both quote styles; `.ck` cannot escape, so keep double\n // quotes and preserve the inner ones as best we can.\n return `\"${value}\"`;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\n/** Options controlling how a {@link CkRootNode} is rendered to `.ck` source. */\nexport interface SerializeOptions {\n /** Emit descriptions as inline # comments. Default: true. */\n includeComments?: boolean;\n}\n\n/**\n * Serialize a `.ck` AST back to formatted `.ck` source text. Emits the options\n * block first, then every model, then every route, separated by blank lines and\n * terminated with a trailing newline. Descriptions become trailing `# ...`\n * comments unless `options.includeComments` is `false`. The output is designed\n * to re-parse cleanly via `parseCk` (see round-trip tests).\n */\nexport function astToCk(root: CkRootNode, options: SerializeOptions = {}): string {\n const { includeComments = true } = options;\n const ctx: Ctx = { includeComments };\n const parts: string[] = [];\n\n // Options block\n const optionsBlock = serializeOptions(root);\n if (optionsBlock) parts.push(optionsBlock);\n\n // Models\n for (const model of root.models) {\n parts.push(serializeModel(model, ctx));\n }\n\n // Routes\n for (const route of root.routes) {\n parts.push(serializeRoute(route, ctx));\n }\n\n return parts.join('\\n\\n') + '\\n';\n}\n\n// ─── Context ──────────────────────────────────────────────────────────────\n\ninterface Ctx {\n includeComments: boolean;\n}\n\n// ─── Options block ────────────────────────────────────────────────────────\n\nfunction serializeOptions(root: CkRootNode): string | null {\n const hasKeys = Object.keys(root.meta).length > 0;\n const hasServices = root.services && Object.keys(root.services).length > 0;\n const hasSecurity = root.security !== undefined;\n\n if (!hasKeys && !hasServices && !hasSecurity) return null;\n\n const lines: string[] = ['options {'];\n\n if (hasKeys) {\n lines.push(`${INDENT}keys: {`);\n for (const [key, value] of Object.entries(root.meta)) {\n lines.push(`${INDENT}${INDENT}${key}: ${value}`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasServices) {\n lines.push(`${INDENT}services: {`);\n for (const [name, path] of Object.entries(root.services)) {\n lines.push(`${INDENT}${INDENT}${name}: \"${path}\"`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasSecurity) {\n lines.push(`${INDENT}security: {`);\n if (root.security === 'none') {\n lines.push(`${INDENT}${INDENT}none`);\n } else {\n const sec = root.security as SecurityFields;\n if (sec.policy !== undefined) {\n const value = sec.policy === false ? 'none' : sec.policy;\n lines.push(`${INDENT}${INDENT}policy: ${value}`);\n }\n }\n lines.push(`${INDENT}}`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n// ─── Models ───────────────────────────────────────────────────────────────\n\nfunction serializeModel(model: ModelNode, ctx: Ctx): string {\n const parts: string[] = [];\n\n // Modifiers: format(input=snake) mode(loose) deprecated\n const prefixes: string[] = [];\n if (model.inputCase && model.inputCase !== 'camel') {\n prefixes.push(`format(input=${model.inputCase})`);\n }\n if (model.mode && model.mode !== 'strict') {\n prefixes.push(`mode(${model.mode})`);\n }\n if (model.deprecated) {\n prefixes.push('deprecated');\n }\n\n const prefix = prefixes.length > 0 ? prefixes.join(' ') + ' ' : '';\n const comment = ctx.includeComments && model.description ? ` # ${singleLineComment(model.description)}` : '';\n\n // Type alias: contract Name: typeExpression\n if (model.type) {\n parts.push(`contract ${prefix}${model.name}: ${serializeType(model.type)}${comment}`);\n return parts.join('');\n }\n\n // Inheritance: contract Name: Base1 & Base2 & { ... }\n if (model.bases && model.bases.length > 0) {\n parts.push(`contract ${prefix}${model.name}: ${model.bases.join(' & ')} & {${comment}`);\n } else {\n parts.push(`contract ${prefix}${model.name}: {${comment}`);\n }\n\n for (const field of model.fields) {\n parts.push(serializeField(field, 1, ctx));\n }\n\n parts.push('}');\n return parts.join('\\n');\n}\n\nfunction serializeField(field: FieldNode, depth: number, ctx: Ctx): string {\n const indent = INDENT.repeat(depth);\n const optional = field.optional ? '?' : '';\n const visibility = field.visibility !== 'normal' ? `${field.visibility} ` : '';\n const deprecated = field.deprecated ? 'deprecated ' : '';\n\n let typeStr = serializeType(field.type);\n\n // Nullable fields: if the type doesn't already contain null, append `| null`\n if (field.nullable && !typeContainsNull(field.type)) {\n typeStr = `${typeStr} | null`;\n }\n\n const defaultVal = field.default !== undefined ? ` = ${serializeDefault(field.default)}` : '';\n const comment = ctx.includeComments && field.description ? ` # ${singleLineComment(field.description)}` : '';\n\n return `${indent}${field.name}${optional}: ${deprecated}${visibility}${typeStr}${defaultVal}${comment}`;\n}\n\nfunction typeContainsNull(type: ContractTypeNode): boolean {\n if (type.kind === 'scalar' && type.name === 'null') return true;\n if (type.kind === 'union') return type.members.some(typeContainsNull);\n return false;\n}\n\nfunction serializeDefault(value: string | number | boolean): string {\n if (typeof value === 'string') {\n // If it looks like an identifier (e.g. enum value), don't quote it\n if (/^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/.test(value)) return value;\n return `\"${value}\"`;\n }\n return String(value);\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────\n\n/**\n * Serialize a single {@link ContractTypeNode} to its inline `.ck` type\n * expression (e.g. `array(User, min=1)`, `string | int`, `enum(asc, desc)`).\n * Recurses through composite types; enum values are quoted as needed via\n * {@link quoteEnumValue}.\n */\nexport function serializeType(type: ContractTypeNode): string {\n switch (type.kind) {\n case 'scalar':\n return serializeScalar(type);\n case 'array':\n return serializeArray(type);\n case 'tuple':\n return `tuple(${type.items.map(serializeType).join(', ')})`;\n case 'record':\n return `record(${serializeType(type.key)}, ${serializeType(type.value)})`;\n case 'enum':\n return `enum(${type.values.map(quoteEnumValue).join(', ')})`;\n case 'literal':\n return serializeLiteral(type);\n case 'union':\n return type.members.map(serializeType).join(' | ');\n case 'discriminatedUnion':\n return `discriminated(by=${type.discriminator}, ${type.members.map(serializeType).join(' | ')})`;\n case 'intersection':\n return type.members.map(serializeType).join(' & ');\n case 'ref':\n return type.name;\n case 'inlineObject':\n return serializeInlineObject(type);\n case 'lazy':\n return `lazy(${serializeType(type.inner)})`;\n }\n}\n\nfunction serializeScalar(type: {\n name: string;\n min?: number | bigint | string;\n max?: number | bigint | string;\n len?: number;\n regex?: string;\n format?: string;\n}): string {\n const args: string[] = [];\n if (type.len !== undefined) args.push(`length=${type.len}`);\n if (type.min !== undefined) args.push(typeof type.min === 'string' ? `min=\"${type.min}\"` : `min=${type.min}`);\n if (type.max !== undefined) args.push(typeof type.max === 'string' ? `max=\"${type.max}\"` : `max=${type.max}`);\n if (type.regex !== undefined) args.push(`regex=${type.regex}`);\n if (type.format !== undefined) args.push(`format=${type.format}`);\n\n if (args.length === 0) return type.name;\n return `${type.name}(${args.join(', ')})`;\n}\n\nfunction serializeArray(type: { item: ContractTypeNode; min?: number; max?: number }): string {\n const args: string[] = [serializeType(type.item)];\n if (type.min !== undefined) args.push(`min=${type.min}`);\n if (type.max !== undefined) args.push(`max=${type.max}`);\n return `array(${args.join(', ')})`;\n}\n\nfunction serializeLiteral(type: { value: string | number | boolean }): string {\n if (typeof type.value === 'string') return `literal(\"${type.value}\")`;\n return `literal(${type.value})`;\n}\n\nfunction serializeInlineObject(type: { fields: FieldNode[]; mode?: ObjectMode }): string {\n const modePrefix = type.mode ? `mode(${type.mode}) ` : '';\n if (type.fields.length === 0) return `${modePrefix}{}`;\n\n const lines: string[] = [`${modePrefix}{`];\n for (const field of type.fields) {\n lines.push(serializeField(field, 2, { includeComments: true }));\n }\n lines.push(`${INDENT}}`);\n return lines.join('\\n');\n}\n\n// ─── Routes ───────────────────────────────────────────────────────────────\n\nfunction serializeRoute(route: OpRouteNode, ctx: Ctx): string {\n const lines: string[] = [];\n\n const modStr = serializeModifiers(route.modifiers);\n const comment = ctx.includeComments && route.description ? ` # ${singleLineComment(route.description)}` : '';\n lines.push(`operation${modStr} ${route.path}: {${comment}`);\n\n // Route-level params\n if (route.params) {\n serializeParamSource(lines, 'params', route.params, route.paramsMode, 1, ctx);\n }\n\n // Route-level security\n if (route.security !== undefined) {\n serializeSecurityBlock(lines, route.security, 1, ctx);\n }\n\n // Operations\n for (const op of route.operations) {\n serializeOperation(lines, op, 1, ctx);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\nfunction serializeOperation(lines: string[], op: OpOperationNode, depth: number, ctx: Ctx): string[] {\n const indent = INDENT.repeat(depth);\n const modStr = serializeModifiers(op.modifiers);\n const comment = ctx.includeComments && op.description ? ` # ${singleLineComment(op.description)}` : '';\n lines.push(`${indent}${op.method}${modStr}: {${comment}`);\n\n const inner = INDENT.repeat(depth + 1);\n\n // Service\n if (op.service) {\n lines.push(`${inner}service: ${op.service}`);\n }\n\n // SDK\n if (op.sdk) {\n lines.push(`${inner}sdk: ${op.sdk}`);\n }\n\n // Signature\n if (op.signature) {\n const sigComment = ctx.includeComments && op.signatureDescription ? ` # ${singleLineComment(op.signatureDescription)}` : '';\n if (op.signaturePolicy) {\n lines.push(`${inner}signature: {`);\n lines.push(`${inner} options: ${op.signature}${sigComment}`);\n lines.push(`${inner} policy: ${op.signaturePolicy}`);\n lines.push(`${inner}}`);\n } else {\n lines.push(`${inner}signature: ${op.signature}${sigComment}`);\n }\n }\n\n // Security\n if (op.security !== undefined) {\n serializeSecurityBlock(lines, op.security, depth + 1, ctx);\n }\n\n // Query\n if (op.query) {\n serializeParamSource(lines, 'query', op.query, op.queryMode, depth + 1, ctx);\n }\n\n // Headers\n if (op.headers) {\n serializeParamSource(lines, 'headers', op.headers, op.headersMode, depth + 1, ctx);\n }\n\n // Request\n if (op.request) {\n serializeRequest(lines, op.request, depth + 1);\n }\n\n // Responses\n if (op.responses.length > 0) {\n serializeResponses(lines, op.responses, depth + 1);\n }\n\n lines.push(`${indent}}`);\n return lines;\n}\n\nfunction serializeModifiers(modifiers?: RouteModifier[]): string {\n if (!modifiers || modifiers.length === 0) return '';\n return `(${modifiers.join(', ')})`;\n}\n\nfunction serializeParamSource(lines: string[], keyword: string, source: ParamSource, mode: ObjectMode | undefined, depth: number, ctx: Ctx): void {\n const indent = INDENT.repeat(depth);\n\n // String reference: `query: TypeName`\n if (source.kind === 'ref') {\n lines.push(`${indent}${keyword}: ${source.name}`);\n return;\n }\n\n // ContractTypeNode reference\n if (source.kind === 'type') {\n lines.push(`${indent}${keyword}: ${serializeType(source.node)}`);\n return;\n }\n\n // Inline param declarations: `params: { name: type }`\n const modeStr = mode ? `mode(${mode}) ` : '';\n lines.push(`${indent}${keyword}: ${modeStr}{`);\n for (const param of source.nodes) {\n const optional = param.optional ? '?' : '';\n let typeStr = serializeType(param.type);\n if (param.nullable && !typeContainsNull(param.type)) {\n typeStr = `${typeStr} | null`;\n }\n const defaultVal = param.default !== undefined ? ` = ${serializeDefault(param.default)}` : '';\n const comment = ctx.includeComments && param.description ? ` # ${singleLineComment(param.description)}` : '';\n lines.push(`${INDENT.repeat(depth + 1)}${param.name}${optional}: ${typeStr}${defaultVal}${comment}`);\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeRequest(lines: string[], request: OpRequestNode, depth: number): void {\n const indent = INDENT.repeat(depth);\n lines.push(`${indent}request: {`);\n for (const body of request.bodies) {\n lines.push(`${INDENT.repeat(depth + 1)}${body.contentType}: ${serializeType(body.bodyType)}`);\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeResponses(lines: string[], responses: OpResponseNode[], depth: number): void {\n const indent = INDENT.repeat(depth);\n lines.push(`${indent}response: {`);\n for (const resp of responses) {\n const hasBody = resp.bodyType && resp.contentType;\n const hasHeaders = resp.headers && resp.headers.length > 0;\n if (hasBody || hasHeaders) {\n lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}: {`);\n if (hasBody) {\n lines.push(`${INDENT.repeat(depth + 2)}${resp.contentType}: ${serializeType(resp.bodyType!)}`);\n }\n if (hasHeaders) {\n lines.push(`${INDENT.repeat(depth + 2)}headers: {`);\n for (const h of resp.headers!) {\n const opt = h.optional ? '?' : '';\n const trail = h.description ? ` # ${singleLineComment(h.description)}` : '';\n lines.push(`${INDENT.repeat(depth + 3)}${h.name}${opt}: ${serializeType(h.type)}${trail}`);\n }\n lines.push(`${INDENT.repeat(depth + 2)}}`);\n }\n lines.push(`${INDENT.repeat(depth + 1)}}`);\n } else {\n lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}:`);\n }\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeSecurityBlock(lines: string[], security: SecurityNode, depth: number, ctx: Ctx): void {\n const indent = INDENT.repeat(depth);\n if (security === 'none') {\n lines.push(`${indent}security: none`);\n return;\n }\n\n const sec = security as SecurityFields;\n if (sec.policy !== undefined) {\n const comment = ctx.includeComments && sec.policyDescription ? ` # ${singleLineComment(sec.policyDescription)}` : '';\n const value = sec.policy === false ? 'none' : sec.policy;\n lines.push(`${indent}security: {`);\n lines.push(`${INDENT.repeat(depth + 1)}policy: ${value}${comment}`);\n lines.push(`${indent}}`);\n } else {\n lines.push(`${indent}security: {}`);\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { parse as parseYaml } from 'yaml';\nimport type { ConvertOptions, ConvertResult, NormalizedDocument } from './types.js';\nimport { WarningCollector } from './warnings.js';\nimport { normalize } from './normalize.js';\nimport { detectCircularRefs } from './circular-refs.js';\nimport { schemasToModels, sanitizeName } from './schema-to-ast.js';\nimport type { SchemaContext } from './schema-to-ast.js';\nimport { pathsToRoutes } from './paths-to-ast.js';\nimport { splitByTag, mergeIntoSingle } from './tag-splitter.js';\nimport { astToCk } from './ast-to-ck.js';\nimport type { NormalizedSchema } from './types.js';\nimport type { ModelNode } from '@contractkit/core';\n\n/**\n * Convert an OpenAPI spec (2.0, 3.0, or 3.1) to Contract Kit .ck source files.\n */\nexport async function convertOpenApiToCk(options: ConvertOptions): Promise<ConvertResult> {\n const { split = 'by-tag', includeComments = true } = options;\n const warnings = new WarningCollector(options.onWarning);\n\n // Step 1: Parse the input into a document object\n const rawDoc = await parseInput(options.input);\n\n // Step 2: Normalize to 3.1 shape\n const doc = normalize(rawDoc, warnings);\n\n // Step 3: Sanitize schema names\n const schemas = sanitizeSchemaNames(doc, warnings);\n\n // Step 4: Detect circular references\n const circularRefs = detectCircularRefs(schemas);\n\n // Step 5: Convert schemas to model AST nodes\n const extractedModels: ModelNode[] = [];\n const schemaCtx: SchemaContext = {\n circularRefs,\n warnings,\n path: '#/components/schemas',\n includeComments,\n namedSchemas: schemas,\n extractedModels,\n inlineCounter: 0,\n };\n\n const models = schemasToModels(schemas, schemaCtx);\n\n // Step 6: Convert paths to route AST nodes\n const { routes, routeTags } = pathsToRoutes(doc, {\n circularRefs,\n warnings,\n includeComments,\n namedSchemas: schemas,\n extractedModels,\n globalSecurity: doc.security,\n });\n\n // Step 7: Split or merge\n const files = new Map<string, string>();\n\n if (split === 'by-tag') {\n const ckRoots = splitByTag(models, routes, routeTags);\n for (const [filename, root] of ckRoots) {\n files.set(filename, astToCk(root, { includeComments }));\n }\n } else {\n const root = mergeIntoSingle(models, routes);\n files.set('api.ck', astToCk(root, { includeComments }));\n }\n\n return { files, warnings: warnings.warnings };\n}\n\n// ─── Input Parsing ────────────────────────────────────────────────────────\n\nasync function parseInput(input: string | Record<string, unknown>): Promise<Record<string, unknown>> {\n // Already a parsed object\n if (typeof input === 'object') {\n return input;\n }\n\n // Try as a file path first\n try {\n const content = readFileSync(input, 'utf-8');\n return parseJsonOrYaml(content);\n } catch {\n // Not a file path — try parsing as JSON/YAML string\n return parseJsonOrYaml(input);\n }\n}\n\nfunction parseJsonOrYaml(content: string): Record<string, unknown> {\n // Try JSON first (faster)\n try {\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n // Fall back to YAML\n return parseYaml(content) as Record<string, unknown>;\n }\n}\n\n// ─── Schema Name Sanitization ─────────────────────────────────────────────\n\nfunction sanitizeSchemaNames(doc: NormalizedDocument, warnings: WarningCollector): Record<string, NormalizedSchema> {\n const original = doc.components?.schemas ?? {};\n const sanitized: Record<string, NormalizedSchema> = {};\n const nameMap = new Map<string, string>(); // original → sanitized\n\n for (const name of Object.keys(original)) {\n const clean = sanitizeName(name, warnings);\n if (sanitized[clean]) {\n warnings.warn(`#/components/schemas/${name}`, `Name collision after sanitization: \"${name}\" and another schema both map to \"${clean}\"`);\n // Disambiguate with a suffix\n let i = 2;\n while (sanitized[`${clean}${i}`]) i++;\n nameMap.set(name, `${clean}${i}`);\n sanitized[`${clean}${i}`] = original[name] as NormalizedSchema;\n } else {\n nameMap.set(name, clean);\n sanitized[clean] = original[name] as NormalizedSchema;\n }\n }\n\n // Update $refs in the document to use sanitized names\n if (nameMap.size > 0) {\n updateRefs(doc, nameMap);\n }\n\n return sanitized;\n}\n\nfunction updateRefs(obj: unknown, nameMap: Map<string, string>): void {\n if (!obj || typeof obj !== 'object') return;\n if (Array.isArray(obj)) {\n for (const item of obj) updateRefs(item, nameMap);\n return;\n }\n\n const record = obj as Record<string, unknown>;\n if (typeof record.$ref === 'string') {\n const match = record.$ref.match(/^#\\/components\\/schemas\\/(.+)$/);\n if (match?.[1] && nameMap.has(match[1])) {\n record.$ref = `#/components/schemas/${nameMap.get(match[1])}`;\n }\n }\n\n for (const value of Object.values(record)) {\n updateRefs(value, nameMap);\n }\n}\n","import type { Warning } from './types.js';\n\nexport class WarningCollector {\n readonly warnings: Warning[] = [];\n private onWarning?: (w: Warning) => void;\n\n constructor(onWarning?: (w: Warning) => void) {\n this.onWarning = onWarning;\n }\n\n warn(path: string, message: string): void {\n this.add({ path, message, severity: 'warn' });\n }\n\n info(path: string, message: string): void {\n this.add({ path, message, severity: 'info' });\n }\n\n private add(warning: Warning): void {\n this.warnings.push(warning);\n this.onWarning?.(warning);\n }\n}\n"],"mappings":"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","names":["normalize","doc","warnings","version","detectVersion","normalizeSwagger2","normalizeOas30","swagger","startsWith","openapi","info","title","basePath","schemes","host","globalConsumes","consumes","globalProduces","produces","result","description","servers","url","paths","components","schemas","securitySchemes","tags","definitions","name","schema","Object","entries","normalizeNullable30","secDefs","securityDefinitions","scheme","convertSecurityScheme2","path","pathItem","normalizePathItem2","security","methods","normalized","pathParams","parameters","method","op","opConsumes","opProduces","params","nonBodyParams","requestBody","param","in","contentType","required","content","encodePathSegment","type","properties","formSchema","props","push","normalizedParam","format","enum","items","default","minimum","maximum","minLength","maxLength","pattern","responses","opResponses","code","resp","headers","convertResponseHeaders2","responseEntry","operationId","summary","length","undefined","deprecated","out","header","rest","keys","flow","flows","implicit","authorizationUrl","scopes","password","tokenUrl","clientCredentials","authorizationCode","_warnings","values","normalizePathItemSchemas","reqBody","mediaType","nullable","key","val","Array","isArray","additionalProperties","combiner","map","s","replace","detectCircularRefs","schemas","circular","Set","visiting","visited","visit","name","has","add","schema","ref","collectRefs","refName","extractRefName","delete","Object","keys","obj","refs","walk","val","Array","isArray","item","record","$ref","push","v","values","match","LOC","file","line","FORMAT_TO_SCALAR","email","uri","url","uuid","date","time","binary","int64","schemasToModels","schemas","ctx","models","name","schema","Object","entries","modelCtx","path","model","schemaToModel","push","extractedModels","warnUnsupported","description","includeComments","undefined","allOf","length","first","second","refMember","$ref","objectMember","properties","baseName","extractRefName","fields","schemaPropertiesToFields","kind","bases","loc","type","additionalProperties","typeNode","schemaToTypeNode","refName","circularRefs","has","inner","warnings","warn","const","value","enum","values","map","String","oneOf","discriminator","propertyName","toDiscriminatedUnion","toUnion","anyOf","members","s","types","normalizeTypeField","schemaToInlineObject","baseType","nullable","stringSchemaToType","integerSchemaToType","numberSchemaToType","arraySchemaToType","objectSchemaToType","format","scalarName","mods","minLength","maxLength","len","min","max","pattern","regex","minimum","maximum","prefixItems","items","item","minItems","maxItems","key","required","Set","propSchema","propCtx","fieldType","effectiveType","nonNull","filter","m","visibility","readOnly","writeOnly","optional","default","deprecated","Array","isArray","t","includes","xml","externalDocs","info","not","extractInlineModel","suggestedName","sanitizeName","cleaned","replace","split","Boolean","part","charAt","toUpperCase","slice","join","LOC","file","line","HTTP_METHODS","pathsToRoutes","doc","ctx","routes","routeTags","Map","paths","path","pathItem","Object","entries","result","pathItemToRoute","push","route","set","tag","operations","primaryTag","pathParams","parameters","filter","p","in","method","op","opNode","operationToNode","tags","length","params","buildPathParams","loc","kind","nodes","description","includeComments","pathPrefix","encodePathSegment","schemaCtx","makeSchemaCtx","node","responses","operationId","sdk","deprecated","modifiers","queryParams","headerParams","param","parameterToNode","query","headers","requestBody","request","requestBodyToNode","toPascalCase","code","resp","statusCode","parseInt","isNaN","respNode","responseToNode","security","undefined","convertSecurity","pathLevelParams","paramMap","name","has","templateNames","matchAll","map","m","get","optional","nullable","type","schema","schemaToTypeNode","required","reqBody","operationName","content","supported","Set","bodies","contentType","mediaType","typeNode","model","extractInlineModel","extractedModels","bodyType","convertResponseHeaders","out","header","circularRefs","warnings","namedSchemas","inlineCounter","input","replace","split","Boolean","part","charAt","toUpperCase","slice","join","s","splitByTag","models","routes","routeTags","routesByTag","Map","route","tag","get","group","push","set","modelsByTag","tagRoutes","refs","Set","collectRouteRefs","modelNameToModel","map","m","name","modelAssignment","model","tags","has","length","collectModelRefs","ref","currentTag","otherTags","entries","filter","t","r","result","allTags","keys","values","tagModels","filename","sanitizeFilename","kind","meta","area","services","file","mergeIntoSingle","params","collectParamSourceRefs","op","operations","query","headers","request","body","bodies","collectTypeRefs","bodyType","resp","responses","source","add","Array","isArray","param","type","item","items","key","value","member","members","field","fields","inner","bases","b","toLowerCase","replace","INDENT","IDENT_RE","singleLineComment","text","replace","trim","quoteEnumValue","value","test","includes","astToCk","root","options","includeComments","ctx","parts","optionsBlock","serializeOptions","push","model","models","serializeModel","route","routes","serializeRoute","join","hasKeys","Object","keys","meta","length","hasServices","services","hasSecurity","security","undefined","lines","key","entries","name","path","sec","policy","prefixes","inputCase","mode","deprecated","prefix","comment","description","type","serializeType","bases","field","fields","serializeField","depth","indent","repeat","optional","visibility","typeStr","nullable","typeContainsNull","defaultVal","default","serializeDefault","kind","members","some","String","serializeScalar","serializeArray","items","map","values","serializeLiteral","discriminator","serializeInlineObject","inner","args","len","min","max","regex","format","item","modePrefix","modStr","serializeModifiers","modifiers","params","serializeParamSource","paramsMode","serializeSecurityBlock","op","operations","serializeOperation","method","service","sdk","signature","sigComment","signatureDescription","signaturePolicy","query","queryMode","headers","headersMode","request","serializeRequest","responses","serializeResponses","keyword","source","node","modeStr","param","nodes","body","bodies","contentType","bodyType","resp","hasBody","hasHeaders","statusCode","h","opt","trail","policyDescription","readFileSync","parse","parseYaml","WarningCollector","warnings","onWarning","warn","path","message","add","severity","info","warning","push","convertOpenApiToCk","options","split","includeComments","warnings","WarningCollector","onWarning","rawDoc","parseInput","input","doc","normalize","schemas","sanitizeSchemaNames","circularRefs","detectCircularRefs","extractedModels","schemaCtx","path","namedSchemas","inlineCounter","models","schemasToModels","routes","routeTags","pathsToRoutes","globalSecurity","security","files","Map","ckRoots","splitByTag","filename","root","set","astToCk","mergeIntoSingle","content","readFileSync","parseJsonOrYaml","JSON","parse","parseYaml","original","components","sanitized","nameMap","name","Object","keys","clean","sanitizeName","warn","i","size","updateRefs","obj","Array","isArray","item","record","$ref","match","has","get","value","values"]}