@contractkit/openapi-to-ck 0.11.0 → 0.12.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 3.28 KB
10
- ESM dist/chunk-Z53MK4FM.js 44.82 KB
10
+ ESM dist/chunk-U7V7LFBV.js 45.52 KB
11
11
  ESM dist/index.js.map 71.00 B
12
12
  ESM dist/plugin.js.map 6.11 KB
13
- ESM dist/chunk-Z53MK4FM.js.map 111.74 KB
14
- ESM ⚡️ Build success in 185ms
13
+ ESM dist/chunk-U7V7LFBV.js.map 113.55 KB
14
+ ESM ⚡️ Build success in 214ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 5204ms
17
- DTS dist/index.d.ts 12.51 KB
16
+ DTS ⚡️ Build success in 4902ms
17
+ DTS dist/index.d.ts 12.87 KB
18
18
  DTS dist/plugin.d.ts 128.00 B
@@ -3,36 +3,36 @@ $ 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 (37 tests) 86ms
7
- ✓ tests/ast-to-ck.test.ts (45 tests) 119ms
8
- ✓ tests/convert.test.ts (17 tests) 1283ms
9
- ✓ tests/coverage.test.ts (17 tests) 418ms
10
- ✓ tests/normalize.test.ts (6 tests) 39ms
11
- ✓ tests/component-refs.test.ts (4 tests) 67ms
12
- ✓ tests/kitchen-sink.test.ts (7 tests) 996ms
13
- ✓ tests/error-responses.test.ts (5 tests) 130ms
14
- ✓ tests/circular-refs.test.ts (8 tests) 17ms
15
- ✓ tests/tag-splitter.test.ts (5 tests) 17ms
6
+ ✓ tests/schema-to-ast.test.ts (37 tests) 89ms
7
+ ✓ tests/ast-to-ck.test.ts (45 tests) 135ms
8
+ ✓ tests/convert.test.ts (17 tests) 1127ms
9
+ ✓ tests/coverage.test.ts (17 tests) 258ms
10
+ ✓ tests/normalize.test.ts (6 tests) 24ms
11
+ ✓ tests/kitchen-sink.test.ts (7 tests) 802ms
12
+ ✓ tests/component-refs.test.ts (4 tests) 155ms
13
+ ✓ tests/circular-refs.test.ts (8 tests) 7ms
14
+ ✓ tests/error-responses.test.ts (5 tests) 156ms
15
+ ✓ tests/tag-splitter.test.ts (5 tests) 11ms
16
16
 
17
17
   Test Files  10 passed (10)
18
18
   Tests  151 passed (151)
19
-  Start at  16:35:30
20
-  Duration  8.18s (transform 2.04s, setup 0ms, import 14.38s, tests 3.17s, environment 1ms)
19
+  Start at  17:30:03
20
+  Duration  7.34s (transform 1.30s, setup 0ms, import 11.71s, tests 2.76s, environment 1ms)
21
21
 
22
22
   % Coverage report from v8
23
- -------------------|---------|----------|---------|---------|----------------------------------------------------------
24
- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
25
- -------------------|---------|----------|---------|---------|----------------------------------------------------------
26
- All files | 83.11 | 73.51 | 94.78 | 85.87 |
27
- src | 83.18 | 74.02 | 95.45 | 85.52 |
28
- ast-to-ck.ts | 100 | 100 | 100 | 100 |
29
- circular-refs.ts | 100 | 90 | 100 | 100 | 20-23
30
- convert.ts | 79.01 | 78.78 | 88.88 | 81.08 | 123-124,137-152,166-171
31
- normalize.ts | 67.52 | 61.2 | 85.71 | 67.59 | 67-68,80,155,197-239,313-331,346-347,356-385,422,426,434
32
- paths-to-ast.ts | 90.68 | 77.23 | 100 | 96.45 | 130,158,168,246,260
33
- schema-to-ast.ts | 89.41 | 80.81 | 100 | 92.21 | 150-151,173,181,195,218-219,227-228,375-382
34
- tag-splitter.ts | 85.71 | 78.94 | 90.9 | 89.02 | 71,153-154,167-168,179-183
35
- warnings.ts | 100 | 100 | 100 | 100 |
36
- tests | 82.14 | 64.7 | 92.59 | 91.11 |
37
- helpers.ts | 82.14 | 64.7 | 92.59 | 91.11 | 142-143,179,184
38
- -------------------|---------|----------|---------|---------|----------------------------------------------------------
23
+ -------------------|---------|----------|---------|---------|-------------------------------------------------------------
24
+ File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
25
+ -------------------|---------|----------|---------|---------|-------------------------------------------------------------
26
+ All files | 81.76 | 72.21 | 94.78 | 84.86 |
27
+ src | 81.73 | 72.63 | 95.45 | 84.46 |
28
+ ast-to-ck.ts | 100 | 100 | 100 | 100 |
29
+ circular-refs.ts | 100 | 90 | 100 | 100 | 20-23
30
+ convert.ts | 79.01 | 78.78 | 88.88 | 81.08 | 123-124,137-152,166-171
31
+ normalize.ts | 67.52 | 61.2 | 85.71 | 67.59 | 67-68,80,155,197-239,313-331,346-347,356-385,422,426,434
32
+ paths-to-ast.ts | 90.68 | 77.23 | 100 | 96.45 | 130,158,168,246,260
33
+ schema-to-ast.ts | 83.41 | 75.8 | 100 | 87.64 | 151-152,174,182,196,219-220,228-229,246-250,286-289,395-402
34
+ tag-splitter.ts | 85.71 | 78.94 | 90.9 | 89.02 | 71,153-154,167-168,179-183
35
+ warnings.ts | 100 | 100 | 100 | 100 |
36
+ tests | 82.14 | 64.7 | 92.59 | 91.11 |
37
+ helpers.ts | 82.14 | 64.7 | 92.59 | 91.11 | 142-143,179,184
38
+ -------------------|---------|----------|---------|---------|-------------------------------------------------------------
package/CHANGELOG.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # @contractkit/openapi-to-ck
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - e102a2c: Add a `decimal` scalar, for money and anything else that has to be exact
8
+
9
+ `number` compiles to `z.coerce.number()` — an IEEE-754 double. Anything monetary has to be exact,
10
+ so contracts either lied about their types or routed the value through `string` by hand. `decimal`
11
+ gives the language a type for it:
12
+
13
+ ```
14
+ contract Payslip: {
15
+ gross: decimal(min=0, scale=2)
16
+ rate: decimal
17
+ }
18
+ ```
19
+
20
+ A decimal travels as a **quoted JSON string** (`{"gross": "1250.00"}`) and becomes a decimal.js
21
+ `Decimal` — the same class Prisma hands you for a `Decimal` column, so a value moves between the
22
+ two with no conversion. Python gets `decimal.Decimal`; OpenAPI gets `type: string, format: decimal`.
23
+
24
+ A raw JSON number is **rejected**, not coerced. By the time one reaches the schema it has already
25
+ been through a double, which is precisely the loss the scalar exists to prevent, so accepting it
26
+ would defeat the point silently.
27
+
28
+ **`scale=` is a validation constraint — at most N decimal places — not a formatting directive.**
29
+ It cannot be one: the router assigns `ctx.body` and Koa serializes it with a `JSON.stringify` we
30
+ have no replacer for, so the wire form is whatever decimal.js normalizes to and `"1250.00"` reads
31
+ back as `"1250"`. The two are the same number; format at the display edge if you need the trailing
32
+ zeros. This is also what `scale` means in OpenAPI `pattern`, pydantic `condecimal(decimal_places=)`
33
+ and Prisma `@db.Decimal(_, n)`, so every downstream mapping stays honest.
34
+
35
+ Generated code sets `Decimal.set({ toExpNeg: -9e15, toExpPos: 9e15 })` so values never serialize in
36
+ exponential notation — without it `0.00000001` ships as `"1e-8"` and any peer validating
37
+ `^-?\d+(\.\d+)?$` rejects it. Note this is global decimal.js configuration and affects every
38
+ `Decimal` in the consuming process.
39
+
40
+ SDK clients rehydrate decimals through generated `reviveX` functions. The `bigint` approach does
41
+ not transfer — it works only because bigint invented a tagged `"123n"` wire encoding, and tagging a
42
+ decimal would corrupt the format for every non-ContractKit consumer. Re-parsing responses through
43
+ the Zod schema is not available either: `XOutput` is a type alias with no runtime value, and models
44
+ default to `z.strictObject`, so any field the server added would throw in every deployed client.
45
+ The revivers mutate in place, which preserves unknown server-added keys.
46
+
47
+ Two placements are rejected at parse time, both errors rather than warnings since no existing
48
+ contract can be relying on them. A decimal inside an **undiscriminated union** cannot be rehydrated
49
+ — the SDK has no way to tell which arm arrived, and a convert-if-string fallback would silently
50
+ rewrite a genuine `string` field in a sibling arm. A decimal in a **response header** has no
51
+ parsing step at all, so the annotation would simply be false at runtime.
52
+
53
+ `min`/`max` are kept as exact decimal strings rather than coerced through `Number()`, and OpenAPI
54
+ carries them in `x-contractkit-min`/`-max` extensions, since JSON Schema's numeric `minimum` and
55
+ `maximum` are ignored on a string type. A contract round-trips through OpenAPI and back with its
56
+ bounds intact.
57
+
58
+ SDKs that scaffold a `package.json` gain `decimal.js` as a dependency when a covered model uses the
59
+ scalar. Existing scaffolds are write-once and are not updated, so add it by hand there.
60
+
61
+ ### Patch Changes
62
+
63
+ - Updated dependencies [e102a2c]
64
+ - @contractkit/core@0.28.0
65
+
3
66
  ## 0.11.0
4
67
 
5
68
  ### Minor Changes
@@ -483,7 +483,8 @@ var FORMAT_TO_SCALAR = {
483
483
  time: "time",
484
484
  duration: "duration",
485
485
  binary: "binary",
486
- int64: "bigint"
486
+ int64: "bigint",
487
+ decimal: "decimal"
487
488
  };
488
489
  function schemasToModels(schemas, ctx) {
489
490
  const models = [];
@@ -670,6 +671,17 @@ function schemaToTypeNode(schema, ctx) {
670
671
  }
671
672
  __name(schemaToTypeNode, "schemaToTypeNode");
672
673
  function stringSchemaToType(schema) {
674
+ if (schema.format === "decimal") {
675
+ const mods2 = {};
676
+ if (schema["x-contractkit-min"] !== void 0) mods2.min = schema["x-contractkit-min"];
677
+ if (schema["x-contractkit-max"] !== void 0) mods2.max = schema["x-contractkit-max"];
678
+ if (schema["x-contractkit-scale"] !== void 0) mods2.scale = schema["x-contractkit-scale"];
679
+ return {
680
+ kind: "scalar",
681
+ name: "decimal",
682
+ ...mods2
683
+ };
684
+ }
673
685
  if (schema.format) {
674
686
  const scalarName = FORMAT_TO_SCALAR[schema.format];
675
687
  if (scalarName) {
@@ -708,6 +720,16 @@ function integerSchemaToType(schema) {
708
720
  }
709
721
  __name(integerSchemaToType, "integerSchemaToType");
710
722
  function numberSchemaToType(schema) {
723
+ if (schema.format === "decimal") {
724
+ const mods2 = {};
725
+ if (schema.minimum !== void 0) mods2.min = String(schema.minimum);
726
+ if (schema.maximum !== void 0) mods2.max = String(schema.maximum);
727
+ return {
728
+ kind: "scalar",
729
+ name: "decimal",
730
+ ...mods2
731
+ };
732
+ }
711
733
  const mods = {};
712
734
  if (schema.minimum !== void 0) mods.min = schema.minimum;
713
735
  if (schema.maximum !== void 0) mods.max = schema.maximum;
@@ -1590,4 +1612,4 @@ export {
1590
1612
  serializeType,
1591
1613
  convertOpenApiToCk
1592
1614
  };
1593
- //# sourceMappingURL=chunk-Z53MK4FM.js.map
1615
+ //# sourceMappingURL=chunk-U7V7LFBV.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 * The transformation is hand-written. An earlier note here claimed `@scalar/openapi-parser`'s\n * `upgrade()` did the heavy lifting; it never did, and that dependency has been dropped.\n *\n * After version normalization, `dereferenceComponents` inlines `$ref`s to reusable non-schema\n * components, so the rest of the pipeline sees only inline parameter, response, request-body and\n * header objects. Schema `$ref`s are deliberately left intact — they become `.ck` model refs.\n */\nexport function normalize(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const version = detectVersion(doc);\n\n const normalized =\n version === '2.0'\n ? normalizeSwagger2(doc, warnings)\n : version === '3.0'\n ? normalizeOas30(doc as unknown as NormalizedDocument, warnings)\n : // 3.1+ — already in target shape\n (doc as unknown as NormalizedDocument);\n\n dereferenceComponents(normalized, warnings);\n return normalized;\n}\n\n// ─── Component $ref inlining ──────────────────────────────────────────────\n\n/** The component sections whose `$ref`s are inlined. `schemas` is deliberately absent. */\nconst DEREF_SECTIONS = ['parameters', 'requestBodies', 'responses', 'headers'] as const;\n\n/** Guards against a `$ref` chain that loops back on itself. */\nconst MAX_REF_DEPTH = 10;\n\n/**\n * Inline `$ref`s to reusable non-schema components.\n *\n * Only `#/components/schemas/*` refs survive conversion — they become `.ck` model references.\n * Everything else (`parameters`, `requestBodies`, `responses`, `headers`) has no `.ck`\n * counterpart, and nothing downstream resolves it: a `$ref`'d parameter used to reach\n * `parameterToNode` with no `name` and print as `undefined: string`, which *parses*, so the\n * corruption was silent. Resolving here means the rest of the pipeline only ever sees inline\n * objects.\n *\n * Sibling keys are kept and win over the target's, matching how OpenAPI 3.1 treats a `$ref`\n * alongside other properties.\n */\nfunction dereferenceComponents(doc: NormalizedDocument, warnings: WarningCollector): void {\n const components = doc.components as Record<string, Record<string, unknown>> | undefined;\n\n const resolve = (node: unknown, path: string, depth = 0): unknown => {\n if (!node || typeof node !== 'object') return node;\n if (Array.isArray(node)) return node.map(item => resolve(item, path, depth));\n\n const obj = node as Record<string, unknown>;\n const ref = obj.$ref;\n if (typeof ref === 'string') {\n const match = /^#\\/components\\/([^/]+)\\/(.+)$/.exec(ref);\n const section = match?.[1];\n // Schema refs are the ones that survive into `.ck`; leave them for `extractRefName`.\n if (section && section !== 'schemas' && (DEREF_SECTIONS as readonly string[]).includes(section)) {\n if (depth >= MAX_REF_DEPTH) {\n warnings.warn(path, `$ref chain too deep to resolve: ${ref}`);\n return obj;\n }\n const target = components?.[section]?.[decodeRefToken(match[2]!)];\n if (target === undefined) {\n warnings.warn(path, `unresolved $ref '${ref}' — the component is not defined`);\n return obj;\n }\n const siblings = { ...obj };\n delete siblings.$ref;\n const resolved = resolve(target, path, depth + 1);\n return { ...(resolved as Record<string, unknown>), ...siblings };\n }\n return obj;\n }\n\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n // A schema subtree can hold `$ref`s of its own, all of them schema refs.\n out[key] = key === 'schema' || key === 'schemas' ? value : resolve(value, `${path}/${key}`, depth);\n }\n return out;\n };\n\n for (const [path, pathItem] of Object.entries(doc.paths ?? {})) {\n doc.paths![path] = resolve(pathItem, `#/paths/${path}`) as typeof pathItem;\n }\n}\n\n/** Undo the `~1`/`~0` escaping a JSON pointer uses for `/` and `~`. */\nfunction decodeRefToken(token: string): string {\n return decodeURIComponent(token).replace(/~1/g, '/').replace(/~0/g, '~');\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', 'trace'];\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', 'trace'];\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 — see {@link insideModel}. */\n circularRefs: Set<string>;\n /**\n * Whether the type being built sits inside a `contract` body. Default `true`.\n *\n * `lazy()` exists to break a definition cycle: `topoSortModels` in the TypeScript plugin\n * emits dependencies before dependents and can only fall back to source order for a cycle,\n * so a reference from one cycle member to another has to be deferred. A reference from an\n * operation — a response body, request body, param, or response header — is not part of any\n * such cycle: it names a model the generated module has already imported and fully\n * evaluated. Wrapping it achieves nothing and makes every contract importing a\n * self-referential schema noisier than it needs to be.\n */\n insideModel: boolean;\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 'idn-email': 'email',\n uri: 'url',\n 'uri-reference': 'url',\n iri: 'url',\n 'iri-reference': 'url',\n url: 'url',\n uuid: 'uuid',\n date: 'date',\n 'date-time': 'datetime',\n time: 'time',\n duration: 'duration',\n binary: 'binary',\n int64: 'bigint',\n decimal: 'decimal',\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 // `additionalProperties: true` says unknown keys are allowed, which is `mode(loose)`.\n // `false` and absent both match `.ck`'s `strict` default, so neither needs a mode.\n ...(schema.additionalProperties === true ? { mode: 'loose' as const } : {}),\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 warnUnrepresentableConstraints(schema, ctx);\n\n // $ref\n if (schema.$ref) {\n const refName = extractRefName(schema.$ref);\n if (refName) {\n if (ctx.insideModel && 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 // `decimal` carries its constraints in extensions rather than in `minimum`/`maximum`, and its\n // `pattern` is derived from `scale` — reimporting that pattern as a `regex=` modifier would\n // both duplicate the constraint and stop the value round-tripping to the same `.ck` source.\n if (schema.format === 'decimal') {\n const mods: Partial<ScalarTypeNode> = {};\n if (schema['x-contractkit-min'] !== undefined) mods.min = schema['x-contractkit-min'];\n if (schema['x-contractkit-max'] !== undefined) mods.max = schema['x-contractkit-max'];\n if (schema['x-contractkit-scale'] !== undefined) mods.scale = schema['x-contractkit-scale'];\n return { kind: 'scalar', name: 'decimal', ...mods };\n }\n\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 // A hand-written spec may say `type: number, format: decimal`. Honour the intent — an exact\n // decimal — even though we never emit that shape ourselves.\n if (schema.format === 'decimal') {\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minimum !== undefined) mods.min = String(schema.minimum);\n if (schema.maximum !== undefined) mods.max = String(schema.maximum);\n return { kind: 'scalar', name: 'decimal', ...mods };\n }\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\n/** JSON Schema keywords with no `.ck` counterpart, warned about rather than silently dropped. */\nconst UNREPRESENTABLE_KEYWORDS = ['exclusiveMinimum', 'exclusiveMaximum', 'multipleOf', 'uniqueItems'] as const;\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 * Report constraints `.ck` has no vocabulary for.\n *\n * Its scalar and array arguments are `min`, `max`, `len`, `regex` and `format`. Folding\n * `exclusiveMinimum` into `min=` would be an off-by-one lie and `multipleOf` has no analogue at\n * all, so the constraint is reported as lost rather than approximated.\n */\nfunction warnUnrepresentableConstraints(schema: NormalizedSchema, ctx: SchemaContext): void {\n for (const keyword of UNREPRESENTABLE_KEYWORDS) {\n if (schema[keyword] !== undefined) ctx.warnings.warn(ctx.path, `${keyword} has no .ck equivalent, dropping the constraint`);\n }\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 // The extracted model is a `contract` body like any other, so references inside it are\n // subject to the same ordering problem an authored one would be.\n const fields = schemaPropertiesToFields(schema, { ...ctx, insideModel: true });\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 // `identStart` excludes digits, so a schema named \"3DModel\" would sanitize to something the\n // parser rejects. Prefix rather than drop the digit, which would collide names.\n const safe = /^[0-9]/.test(cleaned) ? `_${cleaned}` : cleaned;\n\n if (safe !== name) {\n warnings.info(`#/components/schemas/${name}`, `Schema name sanitized: \"${name}\" → \"${safe}\"`);\n }\n\n return safe || '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 };\n\n/** A plain `type/subtype`, which is all `mimeType` in the grammar accepts. */\nconst MIME_RE = /^[a-z0-9][a-z0-9.+_-]*\\/[a-z0-9][a-z0-9.+_-]*$/i;\n\n/**\n * Reduce a summary to something `nameText` can hold.\n *\n * `nameText = (~(\"\\n\" | \"}\" | \" #\" | \"\\t#\") any)+` — the value runs to end of line and stops at\n * a closing brace or a whitespace-preceded `#`. An OpenAPI summary respects none of that, and an\n * unsanitized one would mis-parse the rest of the operation.\n */\nfunction toNameText(summary: string): string {\n return summary\n .replace(/[}#]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete'];\n\n/** Methods a spec may declare that `httpMethod` in the grammar has no keyword for. */\nconst UNSUPPORTED_METHODS = ['head', 'options', 'trace'] as const;\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 /** How bodied 4xx/5xx responses are imported. See `ConvertOptions.errorResponses`. */\n errorResponses: 'documented' | 'emitted';\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 UNSUPPORTED_METHODS) {\n // A grammar limitation, not a converter one — `.ck` has no keyword for these verbs.\n if ((pathItem as Record<string, unknown>)[method]) {\n ctx.warnings.warn(`#/paths/${encodePathSegment(path)}/${method}`, `\\`${method}\\` operations have no .ck equivalent; dropped`);\n }\n }\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 // summary → `name:`, the human-readable label the key exists for. `description` stays the\n // doc comment; when only a summary is given it becomes the name and is not doubled as prose.\n if (op.summary) {\n const name = toNameText(op.summary);\n if (name) node.name = name;\n else ctx.warnings.warn(`${pathPrefix}/summary`, 'summary has no content `.ck` can carry as a name; dropped');\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 // `dereferenceComponents` inlines `#/components/parameters/*` before this runs, so a\n // parameter with no name is one nothing could resolve. Emitting it would print\n // `undefined: string`, which parses — silent corruption is worse than a dropped param.\n if (!param?.name) {\n ctx.warnings.warn(`${pathPrefix}/parameters`, 'skipped a parameter with no name (an unresolved $ref?)');\n continue;\n }\n if (param.in === 'query') {\n queryParams.push(parameterToNode(param, schemaCtx));\n } else if (param.in === 'header') {\n headerParams.push(parameterToNode(param, schemaCtx));\n } else if (param.in === 'cookie') {\n ctx.warnings.warn(`${pathPrefix}/parameters/${param.name}`, 'cookie parameters have no `.ck` equivalent; dropped');\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 // Strictly numeric: `parseInt('4XX')` is 4, which would silently invent a status code.\n if (!/^\\d{3}$/.test(code)) {\n // `default`, `2XX`, `4XX` — the response block is keyed by a numeric status.\n ctx.warnings.warn(`${pathPrefix}/responses/${code}`, `response key '${code}' is not a numeric status code; dropped`);\n continue;\n }\n const statusCode = parseInt(code, 10);\n const respNode = responseToNode(statusCode, resp, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n node.responses.push(respNode);\n }\n\n // Security. A spec-level `security` applies to every operation that does not override it;\n // it used to be collected and never read, so a globally-secured spec imported as unsecured.\n const security = op.security ?? ctx.globalSecurity;\n if (security !== undefined) {\n node.security = convertSecurity(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 bodies: OpRequestNode['bodies'] = [];\n\n for (const [contentType, mediaType] of Object.entries(content)) {\n // `.ck` accepts any RFC 6838 `type/subtype`, so there is no reason to narrow a spec to\n // the three content types this used to allow. What it cannot carry is a parameterised\n // (`; charset=`) or wildcard mime, since `mimeType` is two `mimeChar+` runs.\n if (!MIME_RE.test(contentType)) {\n ctx.warnings.warn(`${schemaCtx.path}/requestBody/content`, `content type '${contentType}' is not a plain type/subtype; skipped`);\n continue;\n }\n if (!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({ contentType, bodyType: typeNode });\n }\n\n if (bodies.length === 0) return undefined;\n return { bodies };\n}\n\n// ─── Responses ────────────────────────────────────────────────────────────\n\n/**\n * Whether an imported status should be marked `(documented)` rather than service-produced.\n *\n * Only applies to a status that carries a block, because that is the only case where the\n * modifier does anything: `isEmitted` in core treats a block as \"the service produces this\", and\n * `isRedundantDocumented` warns when `(documented)` is put on a bare bodyless non-2xx, where the\n * status is already not emitted. 3xx is left alone — `observableResponses` already covers\n * everything below 400, so the marker would change nothing a client sees, and a spec'd redirect\n * body is plausibly service-produced.\n */\nfunction shouldDocument(statusCode: number, braced: boolean, resp: NormalizedResponse, ctx: PathsContext): boolean {\n if (!braced) return false;\n // A spec this project emitted says so outright; prefer it over guessing from the status.\n if (resp['x-contractkit-emit'] === 'documented') return true;\n return statusCode >= 400 && ctx.errorResponses === 'documented';\n}\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 documented = (braced: boolean) => (shouldDocument(statusCode, braced, resp, ctx) ? { emit: 'documented' as const } : {});\n const empty = (): OpResponseNode => ({\n statusCode,\n bodies: [],\n ...(headers ? { headers, hasBlock: true, ...documented(true) } : {}),\n });\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 ...documented(true),\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 // A response body, request body, param or header names an already-imported model.\n insideModel: false,\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, ParamSource } 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\n/**\n * Collect the model names a `params`/`query`/`headers` source refers to.\n *\n * `ParamSource` is a tagged union, and this was written against the shape it had before that:\n * a bare string, an array of params, or a type node. Only `kind: 'ref'` still worked, and only\n * by coincidence — it happens to look like a `ModelRefTypeNode`. `'params'` and `'type'` fell\n * through to `collectTypeRefs`, whose switch has neither case, so a model reached only from a\n * query or header block collected no tags at all and was filed under `shared.ck`.\n */\nfunction collectParamSourceRefs(source: ParamSource, refs: Set<string>): void {\n switch (source.kind) {\n case 'ref':\n refs.add(source.name);\n return;\n case 'params':\n for (const param of source.nodes) collectTypeRefs(param.type, refs);\n return;\n case 'type':\n collectTypeRefs(source.node, refs);\n return;\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 { CkRootNode } from '@contractkit/core';\nimport { printCk, printType } from '@contractkit/core';\n\n/**\n * `.ck` serialization for the OpenAPI importer.\n *\n * This module used to carry its own printer. `.ck` had two of them — this one and the prettier\n * plugin's — and only the prettier copy was covered by the round-trip tests that the\n * `ck-grammar-change` checklist points at, so this one silently fell behind the grammar: it\n * ignored `hasBlock` and the `(documented)` response modifier, could not emit `mcp:`,\n * `plugins:`, `name:`, `override`, `format(output=)` or options-level header globals, and\n * emitted unparseable source for a regex containing `/` or an enum value containing both quote\n * styles.\n *\n * The printer now lives in `@contractkit/core` next to `parseCk`, and this module is a thin\n * adapter over it. A grammar change has one printer to update.\n */\n\n/**\n * Options controlling how a {@link CkRootNode} is rendered to `.ck` source.\n *\n * @deprecated `includeComments` is a no-op and is kept only so existing callers still compile.\n * Comments are controlled upstream: `ConvertOptions.includeComments` gates every `description`\n * assignment in `schema-to-ast.ts` and `paths-to-ast.ts`, so when it is off the descriptions are\n * absent from the AST and there is nothing left for the printer to suppress.\n */\nexport interface SerializeOptions {\n /** No-op. See the deprecation note on {@link SerializeOptions}. */\n includeComments?: boolean;\n}\n\n/**\n * Serialize a `.ck` AST back to formatted `.ck` source text.\n *\n * Delegates to `printCk`, which prints from a `CkRootNode` alone — no Ohm CST and no original\n * source — so programmatically built nodes print correctly.\n */\nexport function astToCk(root: CkRootNode, _options: SerializeOptions = {}): string {\n return printCk(root);\n}\n\n/** Render a `ContractTypeNode` to its `.ck` source string. Re-exported from core. */\nexport const serializeType = printType;\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';\nimport { parseCk, decomposeCk, validateRefs, DiagnosticCollector } 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, errorResponses = 'documented' } = 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 insideModel: true,\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 errorResponses,\n });\n\n // Models extracted from inline request/response body schemas arrive during step 6, after\n // `schemasToModels` has already read the array — without this they are referenced by the\n // generated operations and never defined.\n const known = new Set(models.map(m => m.name));\n for (const extracted of extractedModels) {\n if (known.has(extracted.name)) continue;\n known.add(extracted.name);\n models.push(extracted);\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));\n }\n } else {\n const root = mergeIntoSingle(models, routes);\n files.set('api.ck', astToCk(root));\n }\n\n // Step 8: Check what we are about to hand back actually compiles\n checkGeneratedFiles(files, warnings);\n\n return { files, warnings: warnings.warnings };\n}\n\n/**\n * Re-parse the generated files and report anything that does not survive.\n *\n * The converter builds core AST nodes and prints them, so a bug in either half produces `.ck`\n * that will not compile — and, because the output is written straight to disk, the first sign of\n * it is an error in the user's own build. Spec content is more adversarial than anything a\n * hand-written contract contains (patterns full of punctuation, descriptions full of newlines,\n * schema names that are not identifiers), so it is worth the round trip to find out here.\n *\n * Reference validation runs across all the files together, because `by-tag` deliberately splits\n * a model into one file and its users into another. Parsing alone is not enough: a reference to\n * a contract that was never emitted is perfectly good syntax, which is exactly how the importer\n * shipped operations pointing at inline body models it had dropped.\n */\nfunction checkGeneratedFiles(files: Map<string, string>, warnings: WarningCollector): void {\n const diag = new DiagnosticCollector();\n const roots = [];\n for (const [filename, text] of files) {\n const before = diag.getAll().length;\n const root = parseCk(text, filename, diag);\n if (diag.getAll().length === before) roots.push(root);\n }\n\n if (roots.length === files.size) {\n const decomposed = roots.map(decomposeCk);\n validateRefs(\n decomposed.map(d => d.contract),\n decomposed.map(d => d.op),\n diag,\n );\n }\n\n for (const d of diag.getAll()) {\n if (d.severity !== 'error') continue;\n warnings.warn(d.file, `generated .ck is not valid (line ${d.line}): ${d.message}`);\n }\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","normalized","normalizeSwagger2","normalizeOas30","dereferenceComponents","DEREF_SECTIONS","MAX_REF_DEPTH","components","resolve","node","path","depth","Array","isArray","map","item","obj","ref","$ref","match","exec","section","includes","warn","target","decodeRefToken","undefined","siblings","resolved","out","key","value","Object","entries","pathItem","paths","token","decodeURIComponent","replace","swagger","startsWith","openapi","info","title","basePath","schemes","host","globalConsumes","consumes","globalProduces","produces","result","description","servers","url","schemas","securitySchemes","tags","definitions","name","schema","normalizeNullable30","secDefs","securityDefinitions","scheme","convertSecurityScheme2","normalizePathItem2","security","methods","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","deprecated","header","rest","keys","flow","flows","implicit","authorizationUrl","scopes","password","tokenUrl","clientCredentials","authorizationCode","_warnings","values","normalizePathItemSchemas","reqBody","mediaType","nullable","val","additionalProperties","combiner","s","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","iri","url","uuid","date","time","duration","binary","int64","decimal","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","mode","typeNode","schemaToTypeNode","warnUnrepresentableConstraints","refName","insideModel","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","mods","min","max","scale","scalarName","minLength","maxLength","len","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","UNREPRESENTABLE_KEYWORDS","xml","externalDocs","info","not","keyword","extractInlineModel","suggestedName","sanitizeName","cleaned","replace","split","Boolean","part","charAt","toUpperCase","slice","join","safe","test","LOC","file","line","MIME_RE","toNameText","summary","replace","trim","HTTP_METHODS","UNSUPPORTED_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","warnings","warn","encodePathSegment","op","opNode","operationToNode","tags","length","params","buildPathParams","loc","kind","nodes","description","includeComments","pathPrefix","schemaCtx","makeSchemaCtx","node","responses","operationId","sdk","name","deprecated","modifiers","queryParams","headerParams","param","parameterToNode","query","headers","requestBody","request","requestBodyToNode","toPascalCase","code","resp","test","statusCode","parseInt","respNode","responseToNode","security","globalSecurity","undefined","convertSecurity","pathLevelParams","paramMap","has","templateNames","matchAll","map","m","get","optional","nullable","type","schema","schemaToTypeNode","required","reqBody","operationName","content","bodies","contentType","mediaType","typeNode","model","extractInlineModel","extractedModels","bodyType","shouldDocument","braced","errorResponses","convertResponseHeaders","documented","emit","empty","hasBlock","suffix","out","header","circularRefs","namedSchemas","inlineCounter","insideModel","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","param","nodes","type","node","item","items","key","value","member","members","field","fields","inner","bases","b","toLowerCase","replace","printCk","printType","astToCk","root","_options","printCk","serializeType","printType","readFileSync","parse","parseYaml","WarningCollector","warnings","onWarning","warn","path","message","add","severity","info","warning","push","parseCk","decomposeCk","validateRefs","DiagnosticCollector","convertOpenApiToCk","options","split","includeComments","errorResponses","warnings","WarningCollector","onWarning","rawDoc","parseInput","input","doc","normalize","schemas","sanitizeSchemaNames","circularRefs","detectCircularRefs","extractedModels","schemaCtx","path","namedSchemas","inlineCounter","insideModel","models","schemasToModels","routes","routeTags","pathsToRoutes","globalSecurity","security","known","Set","map","m","name","extracted","has","add","push","files","Map","ckRoots","splitByTag","filename","root","set","astToCk","mergeIntoSingle","checkGeneratedFiles","diag","DiagnosticCollector","roots","text","before","getAll","length","parseCk","size","decomposed","decomposeCk","validateRefs","d","contract","op","severity","warn","file","line","message","content","readFileSync","parseJsonOrYaml","JSON","parse","parseYaml","original","components","sanitized","nameMap","Object","keys","clean","sanitizeName","i","updateRefs","obj","Array","isArray","item","record","$ref","match","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-Z53MK4FM.js";
14
+ } from "./chunk-U7V7LFBV.js";
15
15
  export {
16
16
  astToCk,
17
17
  convertOpenApiToCk,
package/dist/plugin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __name,
3
3
  convertOpenApiToCk
4
- } from "./chunk-Z53MK4FM.js";
4
+ } from "./chunk-U7V7LFBV.js";
5
5
 
6
6
  // src/plugin.ts
7
7
  import { writeFileSync, mkdirSync } from "fs";
@@ -1 +1 @@
1
- {"version":3,"file":"schema-to-ast.d.ts","sourceRoot":"","sources":["../src/schema-to-ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAkB,SAAS,EAA6B,MAAM,mBAAmB,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,MAAM,WAAW,aAAa;IAC1B,8EAA8E;IAC9E,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,kDAAkD;IAClD,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,+DAA+D;IAC/D,eAAe,EAAE,SAAS,EAAE,CAAC;IAC7B,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;CACzB;AAyBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,GAAG,EAAE,aAAa,GAAG,SAAS,EAAE,CAa1G;AA2DD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,aAAa,GAAG,gBAAgB,CAkG/F;AAuLD;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,gBAAgB,EACxB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,aAAa,GACnB;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,CA0BnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAkB7E"}
1
+ {"version":3,"file":"schema-to-ast.d.ts","sourceRoot":"","sources":["../src/schema-to-ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAkB,SAAS,EAA6B,MAAM,mBAAmB,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,MAAM,WAAW,aAAa;IAC1B,8EAA8E;IAC9E,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,kDAAkD;IAClD,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,+DAA+D;IAC/D,eAAe,EAAE,SAAS,EAAE,CAAC;IAC7B,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;CACzB;AA0BD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,GAAG,EAAE,aAAa,GAAG,SAAS,EAAE,CAa1G;AA2DD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,aAAa,GAAG,gBAAgB,CAkG/F;AA0MD;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,gBAAgB,EACxB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,aAAa,GACnB;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,CA0BnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAkB7E"}
package/dist/types.d.ts CHANGED
@@ -75,6 +75,14 @@ export interface NormalizedSchema {
75
75
  xml?: unknown;
76
76
  externalDocs?: unknown;
77
77
  not?: unknown;
78
+ /**
79
+ * `decimal` bounds and scale, as emitted by plugin-openapi. JSON Schema's numeric
80
+ * `minimum`/`maximum` are ignored on a string type and would round-trip the value through a
81
+ * float, so the exact values ride in extensions instead.
82
+ */
83
+ 'x-contractkit-scale'?: number;
84
+ 'x-contractkit-min'?: string;
85
+ 'x-contractkit-max'?: string;
78
86
  }
79
87
  /** Normalized OpenAPI 3.1 document (post-upgrade, post-dereference). */
80
88
  export interface NormalizedDocument {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractkit/openapi-to-ck",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Convert OpenAPI specs (2.0/3.0/3.1) to Contract Kit .ck files",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "yaml": "^2.8.3",
32
- "@contractkit/core": "0.27.0"
32
+ "@contractkit/core": "0.28.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@repo/config-eslint": "0.3.1",
@@ -53,6 +53,7 @@ const FORMAT_TO_SCALAR: Record<string, ScalarTypeNode['name']> = {
53
53
  duration: 'duration',
54
54
  binary: 'binary',
55
55
  int64: 'bigint',
56
+ decimal: 'decimal',
56
57
  };
57
58
 
58
59
  // ─── Public API ───────────────────────────────────────────────────────────
@@ -238,6 +239,17 @@ export function schemaToTypeNode(schema: NormalizedSchema, ctx: SchemaContext):
238
239
  // ─── Type-Specific Converters ─────────────────────────────────────────────
239
240
 
240
241
  function stringSchemaToType(schema: NormalizedSchema): ContractTypeNode {
242
+ // `decimal` carries its constraints in extensions rather than in `minimum`/`maximum`, and its
243
+ // `pattern` is derived from `scale` — reimporting that pattern as a `regex=` modifier would
244
+ // both duplicate the constraint and stop the value round-tripping to the same `.ck` source.
245
+ if (schema.format === 'decimal') {
246
+ const mods: Partial<ScalarTypeNode> = {};
247
+ if (schema['x-contractkit-min'] !== undefined) mods.min = schema['x-contractkit-min'];
248
+ if (schema['x-contractkit-max'] !== undefined) mods.max = schema['x-contractkit-max'];
249
+ if (schema['x-contractkit-scale'] !== undefined) mods.scale = schema['x-contractkit-scale'];
250
+ return { kind: 'scalar', name: 'decimal', ...mods };
251
+ }
252
+
241
253
  // Check format first
242
254
  if (schema.format) {
243
255
  const scalarName = FORMAT_TO_SCALAR[schema.format];
@@ -268,6 +280,14 @@ function integerSchemaToType(schema: NormalizedSchema): ContractTypeNode {
268
280
  }
269
281
 
270
282
  function numberSchemaToType(schema: NormalizedSchema): ContractTypeNode {
283
+ // A hand-written spec may say `type: number, format: decimal`. Honour the intent — an exact
284
+ // decimal — even though we never emit that shape ourselves.
285
+ if (schema.format === 'decimal') {
286
+ const mods: Partial<ScalarTypeNode> = {};
287
+ if (schema.minimum !== undefined) mods.min = String(schema.minimum);
288
+ if (schema.maximum !== undefined) mods.max = String(schema.maximum);
289
+ return { kind: 'scalar', name: 'decimal', ...mods };
290
+ }
271
291
  const mods: Partial<ScalarTypeNode> = {};
272
292
  if (schema.minimum !== undefined) mods.min = schema.minimum;
273
293
  if (schema.maximum !== undefined) mods.max = schema.maximum;
package/src/types.ts CHANGED
@@ -79,6 +79,14 @@ export interface NormalizedSchema {
79
79
  xml?: unknown;
80
80
  externalDocs?: unknown;
81
81
  not?: unknown;
82
+ /**
83
+ * `decimal` bounds and scale, as emitted by plugin-openapi. JSON Schema's numeric
84
+ * `minimum`/`maximum` are ignored on a string type and would round-trip the value through a
85
+ * float, so the exact values ride in extensions instead.
86
+ */
87
+ 'x-contractkit-scale'?: number;
88
+ 'x-contractkit-min'?: string;
89
+ 'x-contractkit-max'?: string;
82
90
  }
83
91
 
84
92
  /** Normalized OpenAPI 3.1 document (post-upgrade, post-dereference). */
@@ -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 * The transformation is hand-written. An earlier note here claimed `@scalar/openapi-parser`'s\n * `upgrade()` did the heavy lifting; it never did, and that dependency has been dropped.\n *\n * After version normalization, `dereferenceComponents` inlines `$ref`s to reusable non-schema\n * components, so the rest of the pipeline sees only inline parameter, response, request-body and\n * header objects. Schema `$ref`s are deliberately left intact — they become `.ck` model refs.\n */\nexport function normalize(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const version = detectVersion(doc);\n\n const normalized =\n version === '2.0'\n ? normalizeSwagger2(doc, warnings)\n : version === '3.0'\n ? normalizeOas30(doc as unknown as NormalizedDocument, warnings)\n : // 3.1+ — already in target shape\n (doc as unknown as NormalizedDocument);\n\n dereferenceComponents(normalized, warnings);\n return normalized;\n}\n\n// ─── Component $ref inlining ──────────────────────────────────────────────\n\n/** The component sections whose `$ref`s are inlined. `schemas` is deliberately absent. */\nconst DEREF_SECTIONS = ['parameters', 'requestBodies', 'responses', 'headers'] as const;\n\n/** Guards against a `$ref` chain that loops back on itself. */\nconst MAX_REF_DEPTH = 10;\n\n/**\n * Inline `$ref`s to reusable non-schema components.\n *\n * Only `#/components/schemas/*` refs survive conversion — they become `.ck` model references.\n * Everything else (`parameters`, `requestBodies`, `responses`, `headers`) has no `.ck`\n * counterpart, and nothing downstream resolves it: a `$ref`'d parameter used to reach\n * `parameterToNode` with no `name` and print as `undefined: string`, which *parses*, so the\n * corruption was silent. Resolving here means the rest of the pipeline only ever sees inline\n * objects.\n *\n * Sibling keys are kept and win over the target's, matching how OpenAPI 3.1 treats a `$ref`\n * alongside other properties.\n */\nfunction dereferenceComponents(doc: NormalizedDocument, warnings: WarningCollector): void {\n const components = doc.components as Record<string, Record<string, unknown>> | undefined;\n\n const resolve = (node: unknown, path: string, depth = 0): unknown => {\n if (!node || typeof node !== 'object') return node;\n if (Array.isArray(node)) return node.map(item => resolve(item, path, depth));\n\n const obj = node as Record<string, unknown>;\n const ref = obj.$ref;\n if (typeof ref === 'string') {\n const match = /^#\\/components\\/([^/]+)\\/(.+)$/.exec(ref);\n const section = match?.[1];\n // Schema refs are the ones that survive into `.ck`; leave them for `extractRefName`.\n if (section && section !== 'schemas' && (DEREF_SECTIONS as readonly string[]).includes(section)) {\n if (depth >= MAX_REF_DEPTH) {\n warnings.warn(path, `$ref chain too deep to resolve: ${ref}`);\n return obj;\n }\n const target = components?.[section]?.[decodeRefToken(match[2]!)];\n if (target === undefined) {\n warnings.warn(path, `unresolved $ref '${ref}' — the component is not defined`);\n return obj;\n }\n const siblings = { ...obj };\n delete siblings.$ref;\n const resolved = resolve(target, path, depth + 1);\n return { ...(resolved as Record<string, unknown>), ...siblings };\n }\n return obj;\n }\n\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n // A schema subtree can hold `$ref`s of its own, all of them schema refs.\n out[key] = key === 'schema' || key === 'schemas' ? value : resolve(value, `${path}/${key}`, depth);\n }\n return out;\n };\n\n for (const [path, pathItem] of Object.entries(doc.paths ?? {})) {\n doc.paths![path] = resolve(pathItem, `#/paths/${path}`) as typeof pathItem;\n }\n}\n\n/** Undo the `~1`/`~0` escaping a JSON pointer uses for `/` and `~`. */\nfunction decodeRefToken(token: string): string {\n return decodeURIComponent(token).replace(/~1/g, '/').replace(/~0/g, '~');\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', 'trace'];\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', 'trace'];\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 — see {@link insideModel}. */\n circularRefs: Set<string>;\n /**\n * Whether the type being built sits inside a `contract` body. Default `true`.\n *\n * `lazy()` exists to break a definition cycle: `topoSortModels` in the TypeScript plugin\n * emits dependencies before dependents and can only fall back to source order for a cycle,\n * so a reference from one cycle member to another has to be deferred. A reference from an\n * operation — a response body, request body, param, or response header — is not part of any\n * such cycle: it names a model the generated module has already imported and fully\n * evaluated. Wrapping it achieves nothing and makes every contract importing a\n * self-referential schema noisier than it needs to be.\n */\n insideModel: boolean;\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 'idn-email': 'email',\n uri: 'url',\n 'uri-reference': 'url',\n iri: 'url',\n 'iri-reference': 'url',\n url: 'url',\n uuid: 'uuid',\n date: 'date',\n 'date-time': 'datetime',\n time: 'time',\n duration: 'duration',\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 // `additionalProperties: true` says unknown keys are allowed, which is `mode(loose)`.\n // `false` and absent both match `.ck`'s `strict` default, so neither needs a mode.\n ...(schema.additionalProperties === true ? { mode: 'loose' as const } : {}),\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 warnUnrepresentableConstraints(schema, ctx);\n\n // $ref\n if (schema.$ref) {\n const refName = extractRefName(schema.$ref);\n if (refName) {\n if (ctx.insideModel && 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\n/** JSON Schema keywords with no `.ck` counterpart, warned about rather than silently dropped. */\nconst UNREPRESENTABLE_KEYWORDS = ['exclusiveMinimum', 'exclusiveMaximum', 'multipleOf', 'uniqueItems'] as const;\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 * Report constraints `.ck` has no vocabulary for.\n *\n * Its scalar and array arguments are `min`, `max`, `len`, `regex` and `format`. Folding\n * `exclusiveMinimum` into `min=` would be an off-by-one lie and `multipleOf` has no analogue at\n * all, so the constraint is reported as lost rather than approximated.\n */\nfunction warnUnrepresentableConstraints(schema: NormalizedSchema, ctx: SchemaContext): void {\n for (const keyword of UNREPRESENTABLE_KEYWORDS) {\n if (schema[keyword] !== undefined) ctx.warnings.warn(ctx.path, `${keyword} has no .ck equivalent, dropping the constraint`);\n }\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 // The extracted model is a `contract` body like any other, so references inside it are\n // subject to the same ordering problem an authored one would be.\n const fields = schemaPropertiesToFields(schema, { ...ctx, insideModel: true });\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 // `identStart` excludes digits, so a schema named \"3DModel\" would sanitize to something the\n // parser rejects. Prefix rather than drop the digit, which would collide names.\n const safe = /^[0-9]/.test(cleaned) ? `_${cleaned}` : cleaned;\n\n if (safe !== name) {\n warnings.info(`#/components/schemas/${name}`, `Schema name sanitized: \"${name}\" → \"${safe}\"`);\n }\n\n return safe || '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 };\n\n/** A plain `type/subtype`, which is all `mimeType` in the grammar accepts. */\nconst MIME_RE = /^[a-z0-9][a-z0-9.+_-]*\\/[a-z0-9][a-z0-9.+_-]*$/i;\n\n/**\n * Reduce a summary to something `nameText` can hold.\n *\n * `nameText = (~(\"\\n\" | \"}\" | \" #\" | \"\\t#\") any)+` — the value runs to end of line and stops at\n * a closing brace or a whitespace-preceded `#`. An OpenAPI summary respects none of that, and an\n * unsanitized one would mis-parse the rest of the operation.\n */\nfunction toNameText(summary: string): string {\n return summary\n .replace(/[}#]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete'];\n\n/** Methods a spec may declare that `httpMethod` in the grammar has no keyword for. */\nconst UNSUPPORTED_METHODS = ['head', 'options', 'trace'] as const;\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 /** How bodied 4xx/5xx responses are imported. See `ConvertOptions.errorResponses`. */\n errorResponses: 'documented' | 'emitted';\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 UNSUPPORTED_METHODS) {\n // A grammar limitation, not a converter one — `.ck` has no keyword for these verbs.\n if ((pathItem as Record<string, unknown>)[method]) {\n ctx.warnings.warn(`#/paths/${encodePathSegment(path)}/${method}`, `\\`${method}\\` operations have no .ck equivalent; dropped`);\n }\n }\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 // summary → `name:`, the human-readable label the key exists for. `description` stays the\n // doc comment; when only a summary is given it becomes the name and is not doubled as prose.\n if (op.summary) {\n const name = toNameText(op.summary);\n if (name) node.name = name;\n else ctx.warnings.warn(`${pathPrefix}/summary`, 'summary has no content `.ck` can carry as a name; dropped');\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 // `dereferenceComponents` inlines `#/components/parameters/*` before this runs, so a\n // parameter with no name is one nothing could resolve. Emitting it would print\n // `undefined: string`, which parses — silent corruption is worse than a dropped param.\n if (!param?.name) {\n ctx.warnings.warn(`${pathPrefix}/parameters`, 'skipped a parameter with no name (an unresolved $ref?)');\n continue;\n }\n if (param.in === 'query') {\n queryParams.push(parameterToNode(param, schemaCtx));\n } else if (param.in === 'header') {\n headerParams.push(parameterToNode(param, schemaCtx));\n } else if (param.in === 'cookie') {\n ctx.warnings.warn(`${pathPrefix}/parameters/${param.name}`, 'cookie parameters have no `.ck` equivalent; dropped');\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 // Strictly numeric: `parseInt('4XX')` is 4, which would silently invent a status code.\n if (!/^\\d{3}$/.test(code)) {\n // `default`, `2XX`, `4XX` — the response block is keyed by a numeric status.\n ctx.warnings.warn(`${pathPrefix}/responses/${code}`, `response key '${code}' is not a numeric status code; dropped`);\n continue;\n }\n const statusCode = parseInt(code, 10);\n const respNode = responseToNode(statusCode, resp, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n node.responses.push(respNode);\n }\n\n // Security. A spec-level `security` applies to every operation that does not override it;\n // it used to be collected and never read, so a globally-secured spec imported as unsecured.\n const security = op.security ?? ctx.globalSecurity;\n if (security !== undefined) {\n node.security = convertSecurity(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 bodies: OpRequestNode['bodies'] = [];\n\n for (const [contentType, mediaType] of Object.entries(content)) {\n // `.ck` accepts any RFC 6838 `type/subtype`, so there is no reason to narrow a spec to\n // the three content types this used to allow. What it cannot carry is a parameterised\n // (`; charset=`) or wildcard mime, since `mimeType` is two `mimeChar+` runs.\n if (!MIME_RE.test(contentType)) {\n ctx.warnings.warn(`${schemaCtx.path}/requestBody/content`, `content type '${contentType}' is not a plain type/subtype; skipped`);\n continue;\n }\n if (!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({ contentType, bodyType: typeNode });\n }\n\n if (bodies.length === 0) return undefined;\n return { bodies };\n}\n\n// ─── Responses ────────────────────────────────────────────────────────────\n\n/**\n * Whether an imported status should be marked `(documented)` rather than service-produced.\n *\n * Only applies to a status that carries a block, because that is the only case where the\n * modifier does anything: `isEmitted` in core treats a block as \"the service produces this\", and\n * `isRedundantDocumented` warns when `(documented)` is put on a bare bodyless non-2xx, where the\n * status is already not emitted. 3xx is left alone — `observableResponses` already covers\n * everything below 400, so the marker would change nothing a client sees, and a spec'd redirect\n * body is plausibly service-produced.\n */\nfunction shouldDocument(statusCode: number, braced: boolean, resp: NormalizedResponse, ctx: PathsContext): boolean {\n if (!braced) return false;\n // A spec this project emitted says so outright; prefer it over guessing from the status.\n if (resp['x-contractkit-emit'] === 'documented') return true;\n return statusCode >= 400 && ctx.errorResponses === 'documented';\n}\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 documented = (braced: boolean) => (shouldDocument(statusCode, braced, resp, ctx) ? { emit: 'documented' as const } : {});\n const empty = (): OpResponseNode => ({\n statusCode,\n bodies: [],\n ...(headers ? { headers, hasBlock: true, ...documented(true) } : {}),\n });\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 ...documented(true),\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 // A response body, request body, param or header names an already-imported model.\n insideModel: false,\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, ParamSource } 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\n/**\n * Collect the model names a `params`/`query`/`headers` source refers to.\n *\n * `ParamSource` is a tagged union, and this was written against the shape it had before that:\n * a bare string, an array of params, or a type node. Only `kind: 'ref'` still worked, and only\n * by coincidence — it happens to look like a `ModelRefTypeNode`. `'params'` and `'type'` fell\n * through to `collectTypeRefs`, whose switch has neither case, so a model reached only from a\n * query or header block collected no tags at all and was filed under `shared.ck`.\n */\nfunction collectParamSourceRefs(source: ParamSource, refs: Set<string>): void {\n switch (source.kind) {\n case 'ref':\n refs.add(source.name);\n return;\n case 'params':\n for (const param of source.nodes) collectTypeRefs(param.type, refs);\n return;\n case 'type':\n collectTypeRefs(source.node, refs);\n return;\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 { CkRootNode } from '@contractkit/core';\nimport { printCk, printType } from '@contractkit/core';\n\n/**\n * `.ck` serialization for the OpenAPI importer.\n *\n * This module used to carry its own printer. `.ck` had two of them — this one and the prettier\n * plugin's — and only the prettier copy was covered by the round-trip tests that the\n * `ck-grammar-change` checklist points at, so this one silently fell behind the grammar: it\n * ignored `hasBlock` and the `(documented)` response modifier, could not emit `mcp:`,\n * `plugins:`, `name:`, `override`, `format(output=)` or options-level header globals, and\n * emitted unparseable source for a regex containing `/` or an enum value containing both quote\n * styles.\n *\n * The printer now lives in `@contractkit/core` next to `parseCk`, and this module is a thin\n * adapter over it. A grammar change has one printer to update.\n */\n\n/**\n * Options controlling how a {@link CkRootNode} is rendered to `.ck` source.\n *\n * @deprecated `includeComments` is a no-op and is kept only so existing callers still compile.\n * Comments are controlled upstream: `ConvertOptions.includeComments` gates every `description`\n * assignment in `schema-to-ast.ts` and `paths-to-ast.ts`, so when it is off the descriptions are\n * absent from the AST and there is nothing left for the printer to suppress.\n */\nexport interface SerializeOptions {\n /** No-op. See the deprecation note on {@link SerializeOptions}. */\n includeComments?: boolean;\n}\n\n/**\n * Serialize a `.ck` AST back to formatted `.ck` source text.\n *\n * Delegates to `printCk`, which prints from a `CkRootNode` alone — no Ohm CST and no original\n * source — so programmatically built nodes print correctly.\n */\nexport function astToCk(root: CkRootNode, _options: SerializeOptions = {}): string {\n return printCk(root);\n}\n\n/** Render a `ContractTypeNode` to its `.ck` source string. Re-exported from core. */\nexport const serializeType = printType;\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';\nimport { parseCk, decomposeCk, validateRefs, DiagnosticCollector } 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, errorResponses = 'documented' } = 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 insideModel: true,\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 errorResponses,\n });\n\n // Models extracted from inline request/response body schemas arrive during step 6, after\n // `schemasToModels` has already read the array — without this they are referenced by the\n // generated operations and never defined.\n const known = new Set(models.map(m => m.name));\n for (const extracted of extractedModels) {\n if (known.has(extracted.name)) continue;\n known.add(extracted.name);\n models.push(extracted);\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));\n }\n } else {\n const root = mergeIntoSingle(models, routes);\n files.set('api.ck', astToCk(root));\n }\n\n // Step 8: Check what we are about to hand back actually compiles\n checkGeneratedFiles(files, warnings);\n\n return { files, warnings: warnings.warnings };\n}\n\n/**\n * Re-parse the generated files and report anything that does not survive.\n *\n * The converter builds core AST nodes and prints them, so a bug in either half produces `.ck`\n * that will not compile — and, because the output is written straight to disk, the first sign of\n * it is an error in the user's own build. Spec content is more adversarial than anything a\n * hand-written contract contains (patterns full of punctuation, descriptions full of newlines,\n * schema names that are not identifiers), so it is worth the round trip to find out here.\n *\n * Reference validation runs across all the files together, because `by-tag` deliberately splits\n * a model into one file and its users into another. Parsing alone is not enough: a reference to\n * a contract that was never emitted is perfectly good syntax, which is exactly how the importer\n * shipped operations pointing at inline body models it had dropped.\n */\nfunction checkGeneratedFiles(files: Map<string, string>, warnings: WarningCollector): void {\n const diag = new DiagnosticCollector();\n const roots = [];\n for (const [filename, text] of files) {\n const before = diag.getAll().length;\n const root = parseCk(text, filename, diag);\n if (diag.getAll().length === before) roots.push(root);\n }\n\n if (roots.length === files.size) {\n const decomposed = roots.map(decomposeCk);\n validateRefs(\n decomposed.map(d => d.contract),\n decomposed.map(d => d.op),\n diag,\n );\n }\n\n for (const d of diag.getAll()) {\n if (d.severity !== 'error') continue;\n warnings.warn(d.file, `generated .ck is not valid (line ${d.line}): ${d.message}`);\n }\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","normalized","normalizeSwagger2","normalizeOas30","dereferenceComponents","DEREF_SECTIONS","MAX_REF_DEPTH","components","resolve","node","path","depth","Array","isArray","map","item","obj","ref","$ref","match","exec","section","includes","warn","target","decodeRefToken","undefined","siblings","resolved","out","key","value","Object","entries","pathItem","paths","token","decodeURIComponent","replace","swagger","startsWith","openapi","info","title","basePath","schemes","host","globalConsumes","consumes","globalProduces","produces","result","description","servers","url","schemas","securitySchemes","tags","definitions","name","schema","normalizeNullable30","secDefs","securityDefinitions","scheme","convertSecurityScheme2","normalizePathItem2","security","methods","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","deprecated","header","rest","keys","flow","flows","implicit","authorizationUrl","scopes","password","tokenUrl","clientCredentials","authorizationCode","_warnings","values","normalizePathItemSchemas","reqBody","mediaType","nullable","val","additionalProperties","combiner","s","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","iri","url","uuid","date","time","duration","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","mode","typeNode","schemaToTypeNode","warnUnrepresentableConstraints","refName","insideModel","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","UNREPRESENTABLE_KEYWORDS","xml","externalDocs","info","not","keyword","extractInlineModel","suggestedName","sanitizeName","cleaned","replace","split","Boolean","part","charAt","toUpperCase","slice","join","safe","test","LOC","file","line","MIME_RE","toNameText","summary","replace","trim","HTTP_METHODS","UNSUPPORTED_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","warnings","warn","encodePathSegment","op","opNode","operationToNode","tags","length","params","buildPathParams","loc","kind","nodes","description","includeComments","pathPrefix","schemaCtx","makeSchemaCtx","node","responses","operationId","sdk","name","deprecated","modifiers","queryParams","headerParams","param","parameterToNode","query","headers","requestBody","request","requestBodyToNode","toPascalCase","code","resp","test","statusCode","parseInt","respNode","responseToNode","security","globalSecurity","undefined","convertSecurity","pathLevelParams","paramMap","has","templateNames","matchAll","map","m","get","optional","nullable","type","schema","schemaToTypeNode","required","reqBody","operationName","content","bodies","contentType","mediaType","typeNode","model","extractInlineModel","extractedModels","bodyType","shouldDocument","braced","errorResponses","convertResponseHeaders","documented","emit","empty","hasBlock","suffix","out","header","circularRefs","namedSchemas","inlineCounter","insideModel","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","param","nodes","type","node","item","items","key","value","member","members","field","fields","inner","bases","b","toLowerCase","replace","printCk","printType","astToCk","root","_options","printCk","serializeType","printType","readFileSync","parse","parseYaml","WarningCollector","warnings","onWarning","warn","path","message","add","severity","info","warning","push","parseCk","decomposeCk","validateRefs","DiagnosticCollector","convertOpenApiToCk","options","split","includeComments","errorResponses","warnings","WarningCollector","onWarning","rawDoc","parseInput","input","doc","normalize","schemas","sanitizeSchemaNames","circularRefs","detectCircularRefs","extractedModels","schemaCtx","path","namedSchemas","inlineCounter","insideModel","models","schemasToModels","routes","routeTags","pathsToRoutes","globalSecurity","security","known","Set","map","m","name","extracted","has","add","push","files","Map","ckRoots","splitByTag","filename","root","set","astToCk","mergeIntoSingle","checkGeneratedFiles","diag","DiagnosticCollector","roots","text","before","getAll","length","parseCk","size","decomposed","decomposeCk","validateRefs","d","contract","op","severity","warn","file","line","message","content","readFileSync","parseJsonOrYaml","JSON","parse","parseYaml","original","components","sanitized","nameMap","Object","keys","clean","sanitizeName","i","updateRefs","obj","Array","isArray","item","record","$ref","match","get","value","values"]}