@haddowg/json-api-codegen 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/{index-Ch2PJH9Y.d.mts → index-C0T-tofN.d.mts} +2 -2
- package/dist/{index-Ch2PJH9Y.d.mts.map → index-C0T-tofN.d.mts.map} +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-D4apiVHe.mjs → src-Qe0YLO-w.mjs} +15 -5
- package/dist/src-Qe0YLO-w.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/src-D4apiVHe.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-D4apiVHe.mjs","names":["REF_PREFIX","JSON_API_MEDIA_TYPE","refName","isSchema","isSchema","REF_PREFIX","isSchema","parse","parseYaml"],"sources":["../src/unwrap-refs.ts","../src/build-descriptor.ts","../src/build-examples.ts","../src/contract.ts","../src/declared-links.ts","../src/source.ts","../src/error-codes.ts","../src/provenance.ts","../src/emit.ts","../src/emit-examples.ts","../src/emit-schemas.ts","../src/reader.ts","../src/index.ts"],"sourcesContent":["import type { OpenApiDocument } from './openapi'\n\n/**\n * Keywords that annotate a schema without constraining it. A single-entry `allOf` wrapper is\n * read as its `$ref` only when the wrapper carries nothing else, plus any `x-` extension.\n */\nconst ANNOTATIONS = new Set([\n 'title',\n 'description',\n 'example',\n 'examples',\n 'default',\n 'deprecated',\n 'readOnly',\n 'writeOnly',\n '$comment',\n])\n\nconst unwrapped = new WeakMap<OpenApiDocument, OpenApiDocument>()\n\n/**\n * The document with every `{ allOf: [{ $ref }], ...annotations }` node rewritten as\n * `{ $ref, ...annotations }`. From generator contract 9 the projector wraps a `$ref` that\n * carries an `example`, `examples` or `default` this way, because OAS 3.0 tooling ignores a\n * `$ref`'s siblings. Reading the wrapper as its `$ref` keeps every lookup that follows a `$ref`\n * working, and keeps the annotations for the TSDoc. The input is not modified.\n */\nexport function unwrapRefs(doc: OpenApiDocument): OpenApiDocument {\n let out = unwrapped.get(doc)\n if (out === undefined) {\n out = unwrapNode(doc) as OpenApiDocument\n unwrapped.set(doc, out)\n unwrapped.set(out, out)\n }\n return out\n}\n\nfunction unwrapNode(node: unknown): unknown {\n if (Array.isArray(node)) {\n return node.map(unwrapNode)\n }\n if (typeof node !== 'object' || node === null) {\n return node\n }\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(node)) {\n out[key] = unwrapNode(value)\n }\n const ref = wrappedRef(out)\n if (ref === undefined) {\n return out\n }\n const { allOf: _allOf, ...annotations } = out\n return { $ref: ref, ...annotations }\n}\n\n/** The `$ref` a node wraps in a single-entry `allOf`, when that is all the node constrains. */\nfunction wrappedRef(node: Record<string, unknown>): string | undefined {\n const allOf = node['allOf']\n if (!Array.isArray(allOf) || allOf.length !== 1 || '$ref' in node) {\n return undefined\n }\n const entry: unknown = allOf[0]\n if (typeof entry !== 'object' || entry === null) {\n return undefined\n }\n const keys = Object.keys(entry)\n const ref = (entry as Record<string, unknown>)['$ref']\n if (keys.length !== 1 || typeof ref !== 'string') {\n return undefined\n }\n const annotationsOnly = Object.keys(node).every(\n (key) => key === 'allOf' || ANNOTATIONS.has(key) || key.startsWith('x-'),\n )\n return annotationsOnly ? ref : undefined\n}\n","import type {\n ActionDescriptor,\n ApiDescriptor,\n AtomicDescriptor,\n Cardinality,\n ClientIdPolicy,\n CountableDescriptor,\n InputMediaKind,\n MenuDescriptor,\n PaginatorDescriptor,\n PaginatorKind,\n PaginatorRole,\n PaginatorStrategy,\n PivotDescriptor,\n RawMediaKind,\n RawOutputMedia,\n RelationDescriptor,\n RelationMutations,\n ResourceDescriptor,\n} from '@haddowg/json-api-client'\nimport { ATOMIC_EXT, CANONICAL_PAGE_KEYS } from '@haddowg/json-api-client'\nimport type {\n HttpMethod,\n OpenApiDocument,\n OperationObject,\n PathItemObject,\n SchemaObject,\n SchemaOrBool,\n SecurityRequirement,\n} from './openapi'\nimport { unwrapRefs } from './unwrap-refs'\n\nconst REF_PREFIX = '#/components/schemas/'\nconst JSON_API_MEDIA_TYPE = 'application/vnd.api+json'\n\n/** Sort a record's keys for deterministic, snapshot-stable output. */\nfunction sortRecord<V>(record: Record<string, V>): Record<string, V> {\n const out: Record<string, V> = {}\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created key array\n for (const key of Object.keys(record).sort()) {\n out[key] = record[key]!\n }\n return out\n}\n\n/** Resolve a local schema name from a `#/components/schemas/X` ref. */\nfunction refName(ref: string): string | undefined {\n return ref.startsWith(REF_PREFIX) ? ref.slice(REF_PREFIX.length) : undefined\n}\n\nfunction isSchema(value: SchemaOrBool | undefined): value is SchemaObject {\n return typeof value === 'object' && value !== null\n}\n\n/** The operationId prefixes of a relation's related read and its relationship endpoint. */\nconst RELATED_OPERATION = 'fetchRelated'\nconst RELATIONSHIP_OPERATIONS = [\n 'fetchRelationship',\n 'updateRelationship',\n 'addRelationship',\n 'removeRelationship',\n] as const\n\n/** Where a relation's endpoints live, read from their operationIds. */\ninterface RelationEndpoints {\n related?: string\n relationship?: string\n /** The `$ref` of a relationship mutation's request body (its request pivot shape). */\n requestRef?: string\n}\n\n/** The set of `type` keys a JSON type node declares, with `\"null\"` removed. */\nfunction typeKeys(type: string | readonly string[] | undefined): string[] {\n if (type === undefined) {\n return []\n }\n return (Array.isArray(type) ? type : [type]).filter((t) => t !== 'null')\n}\n\nexport class DescriptorBuilder {\n private readonly schemas: Record<string, SchemaObject>\n private readonly paths: Record<string, PathItemObject>\n /** Lazily-built wire-type -> collection-level paginator kind (for per-relation divergence, D6a). */\n private typePaginators?: Map<string, PaginatorDescriptor>\n /** The names of the document's `oauth2` security schemes, under which operations list scopes. */\n private readonly scopeSchemes: ReadonlySet<string>\n /** The document's default security, which an operation without its own inherits. */\n private readonly defaultSecurity: readonly SecurityRequirement[]\n\n constructor(source: OpenApiDocument) {\n const doc = unwrapRefs(source)\n this.schemas = doc.components?.schemas ?? {}\n this.paths = doc.paths ?? {}\n this.scopeSchemes = new Set(\n Object.entries(doc.components?.securitySchemes ?? {})\n .filter(([, scheme]) => scheme?.type === 'oauth2')\n .map(([name]) => name),\n )\n this.defaultSecurity = doc.security ?? []\n }\n\n /**\n * The OAuth scopes an operation needs (generator contract 16): those its `security` lists under\n * an `oauth2` scheme, in order and without repeats. `undefined` when it lists none.\n */\n private scopes(op: OperationObject | undefined): string[] | undefined {\n if (op === undefined || this.scopeSchemes.size === 0) {\n return undefined\n }\n const out = new Set<string>()\n for (const requirement of op.security ?? this.defaultSecurity) {\n for (const [scheme, scopes] of Object.entries(requirement)) {\n if (this.scopeSchemes.has(scheme) && Array.isArray(scopes)) {\n for (const scope of scopes) {\n out.add(scope)\n }\n }\n }\n }\n return out.size === 0 ? undefined : [...out]\n }\n\n /**\n * The scopes each of a type's CRUD, related and relationship operations needs, keyed by the\n * operationId without the type (`fetchOne`, `fetchRelated.author`). Operations needing none are\n * left out; actions carry their own.\n */\n private operationScopes(wireType: string): Record<string, string[]> {\n const out: Record<string, string[]> = {}\n for (const item of Object.values(this.paths)) {\n for (const op of Object.values(item) as (OperationObject | undefined)[]) {\n const id = op?.operationId\n if (typeof id !== 'string') {\n continue\n }\n const dot = id.indexOf('.')\n const prefix = id.slice(0, dot)\n const rest = id.slice(dot + 1)\n if (dot < 0 || prefix === 'action' || prefix === 'atomic') {\n continue\n }\n let key: string\n if (rest === wireType) {\n key = prefix\n } else if (rest.startsWith(`${wireType}.`)) {\n key = `${prefix}.${rest.slice(wireType.length + 1)}`\n } else {\n continue\n }\n const scopes = this.scopes(op)\n if (scopes !== undefined) {\n out[key] = scopes\n }\n }\n }\n return sortRecord(out)\n }\n\n /**\n * The collection-level paginator kind for a WIRE type (`tracks`), memoised. Resolves each\n * resource schema's wire type (its `type.const`) to the paginator of its collection GET — the\n * baseline a per-relation related-endpoint paginator is compared against (D6a).\n */\n private typePaginator(wireType: string): PaginatorDescriptor {\n if (this.typePaginators === undefined) {\n this.typePaginators = new Map()\n for (const [name, schema] of Object.entries(this.schemas)) {\n const type = this.resourceType(name, schema)\n if (type !== undefined) {\n this.typePaginators.set(type, this.paginator(name.slice(0, -'Resource'.length)))\n }\n }\n }\n return this.typePaginators.get(wireType) ?? 'none'\n }\n\n build(): ApiDescriptor {\n const out: Record<string, ResourceDescriptor> = {}\n for (const [name, schema] of Object.entries(this.schemas)) {\n const wireType = this.resourceType(name, schema)\n if (wireType === undefined) {\n continue\n }\n const base = name.slice(0, -'Resource'.length)\n const collection = this.collectionPath(base)\n const actions = collection ? this.actions(collection) : {}\n const descriptor: ResourceDescriptor = {\n attributes: this.attributes(base),\n relations: this.relations(wireType, base, schema, collection),\n paths: this.operationPaths(base),\n paginator: this.paginator(base),\n clientId: this.clientId(base),\n }\n const countable = this.countable(collection)\n if (countable !== undefined) {\n descriptor.countable = countable\n }\n const includable = this.includable(collection)\n if (includable !== undefined) {\n descriptor.includable = includable\n }\n const sortable = this.sortable(collection)\n if (sortable !== undefined) {\n descriptor.sortable = sortable\n }\n const filterable = this.filterable(collection)\n if (filterable !== undefined) {\n descriptor.filterable = filterable\n }\n if (Object.keys(actions).length > 0) {\n descriptor.actions = actions\n }\n const scopes = this.operationScopes(wireType)\n if (Object.keys(scopes).length > 0) {\n descriptor.scopes = scopes\n }\n // A synthetic stub for an unregistered related type — core's `permissiveResourceObject`\n // emits a `<Rel>Resource` carrying ONLY a `type` const (no `id`/`attributes`) so linkage\n // refs resolve — is reachable only through a parent's `.related()` (which works via the\n // parent's own paths). Admitting it would surface a fully-typed top-level `client.<stub>`\n // whose every method throws, so drop it (D27). A REAL registered resource carries the full\n // `type/id/attributes/…` object shape and stays, even with no attributes/collection of its\n // own; only the type-const-only stub (with no operation paths) is dropped.\n const isTypeOnlyStub = Object.keys(schema.properties ?? {}).every((prop) => prop === 'type')\n if (isTypeOnlyStub && Object.keys(descriptor.paths).length === 0) {\n continue\n }\n out[wireType] = descriptor\n }\n return sortRecord(out)\n }\n\n /**\n * The server-level Atomic Operations capability: the path whose `POST` requestBody\n * declares the atomic ext media type ({@link ATOMIC_EXT}). `null` when no such endpoint\n * exists. Server-level, so it rides {@link buildAtomic}, not the per-type descriptor.\n */\n buildAtomic(): AtomicDescriptor | null {\n for (const [path, item] of Object.entries(this.paths)) {\n const content = item.post?.requestBody?.content ?? {}\n if (Object.keys(content).some(isAtomicMediaType)) {\n const scopes = this.scopes(item.post)\n return scopes === undefined ? { path } : { path, scopes }\n }\n }\n return null\n }\n\n /**\n * A resource schema is one whose name ends in `Resource` (but not\n * `ResourceIdentifier`) and carries `properties.type.const` (a string) — that const\n * is the descriptor key (the wire type). Never inferred from the schema name.\n */\n private resourceType(name: string, schema: SchemaObject): string | undefined {\n if (!name.endsWith('Resource') || name.endsWith('ResourceIdentifier')) {\n return undefined\n }\n const constValue = schema.properties?.['type']\n if (isSchema(constValue) && typeof constValue.const === 'string') {\n return constValue.const\n }\n return undefined\n }\n\n /** Follow a `$ref` to its identifier/resource schema and read `properties.type.const`. */\n private resolveConst(ref: string): string | undefined {\n const target = refName(ref)\n if (target === undefined) {\n return undefined\n }\n const typeProp = this.schemas[target]?.properties?.['type']\n return isSchema(typeProp) && typeof typeProp.const === 'string' ? typeProp.const : undefined\n }\n\n private attributes(base: string): Record<string, string> {\n const attrs = this.schemas[`${base}Attributes`]\n const props = attrs?.properties\n if (props === undefined) {\n return {}\n }\n const out: Record<string, string> = {}\n for (const [name, prop] of Object.entries(props)) {\n if (isSchema(prop)) {\n out[name] = formatHint(prop)\n }\n }\n return sortRecord(out)\n }\n\n /**\n * The relations of a type: every relation its resource renders, plus each write-only relation\n * the create and update bodies accept. A write-only relation is one whose body property carries\n * `writeOnly: true` (generator contract 8) or, in an older document, one the resource doesn't\n * render. A pivot relation reads its response pivot off the rendered relationship and its\n * request pivot off the write bodies.\n */\n private relations(\n wireType: string,\n base: string,\n resource: SchemaObject,\n collection: string | undefined,\n ): Record<string, RelationDescriptor> {\n const relProps = isSchema(resource.properties?.['relationships'])\n ? (resource.properties['relationships'].properties ?? {})\n : {}\n const writes = this.writeRelationships(base)\n const endpoints = this.relationEndpoints(wireType)\n const out: Record<string, RelationDescriptor> = {}\n const add = (name: string, component: SchemaObject | undefined, writeOnly: boolean): void => {\n const parsed = component ? this.relationFromComponent(component) : undefined\n if (parsed === undefined) {\n // A relationship component the codegen can't parse (an unknown linkage shape) is\n // dropped silently otherwise — a drift class (the grammar has grown pivot/polymorphic/\n // nested forms), so warn rather than emit a client missing the relation (D28).\n // eslint-disable-next-line no-console\n console.warn(\n `json-api codegen: relationship \"${name}\" has an unrecognized linkage shape; dropping it from the descriptor.`,\n )\n return\n }\n const descriptor: RelationDescriptor = { ...parsed }\n if (writeOnly) {\n delete descriptor.readPivot\n descriptor.writeOnly = true\n }\n if (descriptor.pivot === true) {\n const writePivot = this.writePivot(\n writes.get(name)?.ref ?? endpoints.get(name)?.requestRef,\n component!,\n )\n if (writePivot !== undefined) {\n descriptor.writePivot = writePivot\n }\n }\n out[name] =\n collection === undefined\n ? descriptor\n : this.withRelationExposure(descriptor, collection, name, endpoints.get(name))\n }\n\n for (const [name, prop] of Object.entries(relProps)) {\n if (!isSchema(prop) || typeof prop.$ref !== 'string' || writes.get(name)?.writeOnly) {\n continue\n }\n add(name, this.schemas[refName(prop.$ref) ?? ''], false)\n }\n for (const [name, write] of writes) {\n if (write.writeOnly || !(name in relProps)) {\n add(name, this.schemas[refName(write.ref) ?? ''], true)\n }\n }\n return sortRecord(out)\n }\n\n /**\n * The relationships the create and update bodies accept: each one's component `$ref` and\n * whether the body marks it `writeOnly`.\n */\n private writeRelationships(base: string): Map<string, { ref: string; writeOnly: boolean }> {\n const out = new Map<string, { ref: string; writeOnly: boolean }>()\n for (const request of [`${base}CreateRequest`, `${base}UpdateRequest`]) {\n const data = this.schemas[request]?.properties?.['data']\n const relationships = isSchema(data) ? data.properties?.['relationships'] : undefined\n const props = isSchema(relationships) ? (relationships.properties ?? {}) : {}\n for (const [name, prop] of Object.entries(props)) {\n if (!isSchema(prop) || typeof prop.$ref !== 'string') {\n continue\n }\n const writeOnly = prop['writeOnly'] === true || out.get(name)?.writeOnly === true\n out.set(name, { ref: out.get(name)?.ref ?? prop.$ref, writeOnly })\n }\n }\n return out\n }\n\n /**\n * Each relation's related and relationship paths, keyed by relation name, from the\n * operationIds the projector stamps (`fetchRelated.<type>.<relation>`, …). A relation's path\n * segment is its URI field name, which may differ from its name, so the paths are never\n * derived from the name when an operationId names them.\n */\n private relationEndpoints(wireType: string): Map<string, RelationEndpoints> {\n const out = new Map<string, RelationEndpoints>()\n const entry = (rel: string): RelationEndpoints => {\n let found = out.get(rel)\n if (found === undefined) {\n found = {}\n out.set(rel, found)\n }\n return found\n }\n for (const [path, item] of Object.entries(this.paths)) {\n for (const [method, op] of Object.entries(item) as [HttpMethod, OperationObject][]) {\n const id = op?.operationId\n if (typeof id !== 'string') {\n continue\n }\n const dot = id.indexOf('.')\n const prefix = id.slice(0, dot)\n const rest = id.slice(dot + 1)\n if (dot < 0 || !rest.startsWith(`${wireType}.`)) {\n continue\n }\n const rel = rest.slice(wireType.length + 1)\n if (prefix === RELATED_OPERATION) {\n entry(rel).related = path\n } else if ((RELATIONSHIP_OPERATIONS as readonly string[]).includes(prefix)) {\n const found = entry(rel)\n found.relationship = path\n const ref = method === 'get' ? undefined : this.requestBodyRef(op)\n if (ref !== undefined) {\n found.requestRef = ref\n }\n }\n }\n }\n return out\n }\n\n /**\n * The per-relation mutation capability, derived from the HTTP methods the relationship\n * endpoint (`{collection}/{id}/relationships/{rel}`) advertises. For a to-many:\n * `add` <- POST, `remove` <- DELETE, `replace` <- PATCH. For a to-one: `set` <- PATCH.\n * Only `true` verbs are emitted (a missing verb is simply absent). Returns `undefined`\n * when the relation exposes no relationship endpoint at all.\n */\n private relationMutations(\n path: string,\n cardinality: RelationDescriptor['cardinality'],\n ): RelationMutations | undefined {\n const item = this.paths[path]\n if (item === undefined) {\n return undefined\n }\n const mutations: RelationMutations = {}\n if (cardinality === 'many') {\n if (item.post) {\n mutations.add = true\n }\n if (item.delete) {\n mutations.remove = true\n }\n if (item.patch) {\n mutations.replace = true\n }\n } else if (item.patch) {\n mutations.set = true\n }\n return mutations\n }\n\n /**\n * Attach the per-relation endpoint-exposure signal to a relation descriptor (D24). The bundle\n * can suppress a relation's related or relationship endpoint (`withoutRelatedEndpoint()` /\n * `withoutRelationshipEndpoint()`, ADR 0027), which the OpenAPI reflects by simply omitting that\n * relation's path — but codegen synthesizes generic `{rel}` templates, erasing the per-relation\n * distinction. So mark `related: false` / `relationship: false` when this relation's specific\n * path is absent, and ALWAYS emit an explicit `mutations` object (the verb flags when the\n * relationship endpoint exists, else `{}`) so the client gates a suppressed relation OFF rather\n * than failing open (offering `.get()`/`.related()`/mutations that 404).\n */\n private withRelationExposure(\n descriptor: RelationDescriptor,\n collection: string,\n name: string,\n endpoints: RelationEndpoints | undefined,\n ): RelationDescriptor {\n const out: RelationDescriptor = { ...descriptor }\n const relatedPath = endpoints?.related ?? `${collection}/{id}/${name}`\n const relationshipPath = endpoints?.relationship ?? `${collection}/{id}/relationships/${name}`\n // The client fills `{rel}` with this segment, so a relation served under its URI field name\n // (`/articles/{id}/published-by` for `publisher`) is reached at its real path.\n const segment = (endpoints?.related ?? endpoints?.relationship)?.split('/').pop()\n if (segment !== undefined && segment !== name) {\n out.uriField = segment\n }\n const relatedGet = this.operation(relatedPath, 'get')\n if (relatedGet === undefined) {\n out.related = false\n }\n const mutations = this.relationMutations(relationshipPath, descriptor.cardinality)\n if (mutations === undefined) {\n out.relationship = false\n out.mutations = {}\n } else {\n out.mutations = mutations\n }\n // The related/relationship reads may advertise their own `withCount` (`_self_` + the relation's\n // countable relations) with a negotiation profile — capture it so a typed `.related()`/`.get()`\n // can send `withCount` and negotiate the profile the endpoint requires (D3).\n const countable =\n withCountParam(relatedGet) ?? withCountParam(this.operation(relationshipPath, 'get'))\n if (countable !== undefined) {\n out.countable = countable\n }\n // A to-many related endpoint can advertise a DIFFERENT paginator than the related type's\n // top-level collection (D6a). Read the related-endpoint kind (preferring the related over the\n // relationship endpoint) and carry it ONLY when it diverges from the related type's collection\n // paginator — the client falls back to that type's paginator otherwise, so parity stays silent.\n if (descriptor.cardinality === 'many') {\n const relatedPaginator =\n this.paginatorOf(relatedGet) === 'none'\n ? this.paginatorOf(this.operation(relationshipPath, 'get'))\n : this.paginatorOf(relatedGet)\n const relatedType = descriptor.types[0]\n const typePaginator = relatedType !== undefined ? this.typePaginator(relatedType) : 'none'\n if (\n relatedPaginator !== 'none' &&\n JSON.stringify(relatedPaginator) !== JSON.stringify(typePaginator)\n ) {\n out.paginator = relatedPaginator\n }\n }\n return out\n }\n\n /**\n * Collect the custom actions for a type from its `{collection}/-actions/{name}` and\n * `{collection}/{id}/-actions/{name}` paths. The action name is the last segment; scope\n * is `resource` when the path carries `/{id}/`, else `collection`. `input` is `document`\n * (a JSON:API requestBody), `none` (no requestBody) or `raw` (a non-JSON:API body);\n * `output` is `document` (a 2xx returns a JSON:API document) or `none` (only `204`). An action\n * answering to several methods gives one entry per method (see {@link pickOperations}).\n */\n private actions(collection: string): Record<string, ActionDescriptor> {\n const out: Record<string, ActionDescriptor> = {}\n const collectionPrefix = `${collection}/-actions/`\n const resourcePrefix = `${collection}/{id}/-actions/`\n for (const [path, item] of Object.entries(this.paths)) {\n let scope: ActionDescriptor['scope']\n let name: string\n if (path.startsWith(resourcePrefix)) {\n scope = 'resource'\n name = path.slice(resourcePrefix.length)\n } else if (path.startsWith(collectionPrefix)) {\n scope = 'collection'\n name = path.slice(collectionPrefix.length)\n } else {\n continue\n }\n // The action name is a single trailing segment.\n if (name.length === 0 || name.includes('/')) {\n continue\n }\n // A path item may advertise several methods. The preferred one (POST, else the first) keeps\n // the bare name, so a client generated before contract 15 keeps compiling.\n const picked = pickOperations(item)\n if (picked.length === 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `json-api codegen: custom action path \"${path}\" advertises no usable operation; skipping.`,\n )\n continue\n }\n for (const [index, { method, op }] of picked.entries()) {\n const key = index === 0 ? name : methodActionName(name, method)\n if (key in out) {\n // eslint-disable-next-line no-console\n console.warn(\n `json-api codegen: the ${method.toUpperCase()} operation of custom action path \"${path}\" would be named \"${key}\", which another action already uses; skipping.`,\n )\n continue\n }\n out[key] = this.action(scope, path, method, op)\n }\n }\n return sortRecord(out)\n }\n\n /** The descriptor for one operation of a custom action. */\n private action(\n scope: ActionDescriptor['scope'],\n path: string,\n method: HttpMethod,\n op: OperationObject,\n ): ActionDescriptor {\n const input = actionInput(op)\n const output = actionOutput(op)\n const action: ActionDescriptor = { scope, path, input, output }\n // Only carried when non-POST (POST is the runtime default), keeping the common descriptor tiny.\n if (method !== 'post') {\n action.method = method.toUpperCase()\n }\n // A document input names its resource type so the client can accept FLAT input and build the\n // envelope (+ remap 422 pointers), matching `create`/`update` ergonomics.\n if (input === 'document') {\n const inputType = this.documentPrimary(actionRequestRef(op))?.type\n if (inputType !== undefined) {\n action.inputType = inputType\n }\n }\n // A document output names its primary resource type + cardinality so the client materialises\n // the response into that resource view (matching reads), not the raw wire envelope.\n if (output === 'document') {\n const primary = this.documentPrimary(this.firstOkJsonApiRef(op))\n if (primary !== undefined) {\n action.outputType = primary.type\n action.outputCardinality = primary.cardinality\n }\n }\n // A raw-input action carries its declared (non-JSON:API) media type so the client sends\n // the right `Content-Type` rather than a wildcard the server may reject.\n if (input === 'raw') {\n const contentType = rawContentType(op)\n if (contentType !== undefined) {\n action.contentType = contentType\n }\n }\n // Generator contract 10: media types other than JSON:API under a 2xx, picked by `Accept`.\n const rawOutput = this.rawOutput(op)\n if (rawOutput.length > 0) {\n action.rawOutput = rawOutput\n }\n // Several request media types, picked by `Content-Type`. One is already `input`/`contentType`.\n const requestContent = Object.entries(op.requestBody?.content ?? {})\n if (requestContent.length > 1) {\n action.inputMedia = requestContent.map(([mediaType, media]) => ({\n mediaType,\n kind: this.inputMediaKind(mediaType, media.schema),\n }))\n }\n // Generator contract 15: the flags the action declares, each only when declared.\n const safety = op['x-safety']\n for (const flag of ['readOnly', 'destructive', 'idempotent'] as const) {\n const value = safety?.[flag]\n if (typeof value === 'boolean') {\n action[flag] = value\n }\n }\n // Generator contract 16: the scopes its operation's `security` lists.\n const scopes = this.scopes(op)\n if (scopes !== undefined) {\n action.scopes = scopes\n }\n // Generator contract 17: a location document carrying the URL the action produced.\n const okSchema = okJsonApiSchema(op)\n const mediaType = okSchema === undefined ? undefined : locationMediaType(okSchema)\n if (mediaType !== undefined) {\n action.location = { mediaType }\n }\n return action\n }\n\n /**\n * The non-JSON:API media types an action answers with under its 2xx responses, each once, in\n * the document's order, with how the client reads its body.\n */\n private rawOutput(op: OperationObject): RawOutputMedia[] {\n const out: RawOutputMedia[] = []\n for (const [code, response] of Object.entries(op.responses ?? {})) {\n if (!code.startsWith('2')) {\n continue\n }\n for (const [mediaType, media] of Object.entries(response.content ?? {})) {\n if (isJsonApiMediaType(mediaType) || out.some((entry) => entry.mediaType === mediaType)) {\n continue\n }\n out.push({ mediaType, kind: this.rawMediaKind(mediaType, media.schema) })\n }\n }\n return out\n }\n\n /**\n * How the client reads or sends a non-JSON:API body: `binary` for `format: binary` (or no schema\n * on a type that isn't text or JSON), `text` for any other string schema (or no schema on a\n * `text/*` type), `json` for any other schema (or no schema on a JSON type).\n */\n private rawMediaKind(mediaType: string, schema: SchemaObject | undefined): RawMediaKind {\n const resolved = this.resolveSchema(schema)\n if (resolved === undefined) {\n if (mediaType.startsWith('text/')) {\n return 'text'\n }\n return isJsonMediaType(mediaType) ? 'json' : 'binary'\n }\n if (resolved.type === 'string') {\n return resolved.format === 'binary' ? 'binary' : 'text'\n }\n return 'json'\n }\n\n /** How the client sends one of an action's several request media types. */\n private inputMediaKind(mediaType: string, schema: SchemaObject | undefined): InputMediaKind {\n if (isJsonApiMediaType(mediaType)) {\n return 'document'\n }\n if (mediaType.startsWith('multipart/')) {\n return 'multipart'\n }\n if (mediaType === 'application/x-www-form-urlencoded') {\n return 'form'\n }\n return this.rawMediaKind(mediaType, schema)\n }\n\n /** A schema with a component `$ref` followed, else the schema as is. */\n private resolveSchema(schema: SchemaObject | undefined): SchemaObject | undefined {\n if (schema === undefined || typeof schema.$ref !== 'string') {\n return schema\n }\n const name = refName(schema.$ref)\n return name === undefined ? schema : (this.schemas[name] ?? schema)\n }\n\n /**\n * The wire type (and cardinality) of a document component's primary `data` — a `$ref` to a\n * resource, an inline object carrying `properties.type.const` (a create-request body), or an\n * array of resource/identifier refs (a collection). `undefined` when the type can't be resolved.\n */\n private documentPrimary(\n ref: string | undefined,\n ): { type: string; cardinality: Cardinality } | undefined {\n if (typeof ref !== 'string') {\n return undefined\n }\n const component = refName(ref)\n const data = component === undefined ? undefined : this.schemas[component]?.properties?.['data']\n if (!isSchema(data)) {\n return undefined\n }\n if (isSchema(data.items)) {\n const itemRef = data.items.$ref\n const many = typeof itemRef === 'string' ? this.resolveConst(itemRef) : undefined\n return many === undefined ? undefined : { type: many, cardinality: 'many' }\n }\n const one = this.dataConst(data)\n return one === undefined ? undefined : { type: one, cardinality: 'one' }\n }\n\n /** The wire type of a single `data` schema — a `$ref` to a resource, or an inline `type.const`. */\n private dataConst(data: SchemaObject): string | undefined {\n if (typeof data.$ref === 'string') {\n return this.resolveConst(data.$ref)\n }\n const typeProp = data.properties?.['type']\n return isSchema(typeProp) && typeof typeProp.const === 'string' ? typeProp.const : undefined\n }\n\n /** The `$ref` of the first 2xx JSON:API response body on an operation (the output document). */\n private firstOkJsonApiRef(op: OperationObject): string | undefined {\n for (const [code, response] of Object.entries(op.responses ?? {})) {\n if (!code.startsWith('2')) {\n continue\n }\n const schema = response.content?.[JSON_API_MEDIA_TYPE]?.schema\n // A response offering a location document too names its other document in a `oneOf`.\n const ref = schema === undefined ? undefined : documentArms(schema)[0]?.$ref\n if (typeof ref === 'string') {\n return ref\n }\n }\n return undefined\n }\n\n /** Resolve a relationship component's `data` into a {@link RelationDescriptor}. */\n private relationFromComponent(component: SchemaObject): RelationDescriptor | undefined {\n const data = component.properties?.['data']\n if (!isSchema(data)) {\n return undefined\n }\n\n // to-many: data.type === 'array'\n if (data.type === 'array') {\n const items = data.items\n if (items === undefined) {\n return undefined\n }\n if (typeof items.$ref === 'string') {\n // monomorphic to-many\n const type = this.resolveConst(items.$ref)\n return type === undefined ? undefined : { cardinality: 'many', types: [type], pivot: false }\n }\n if (Array.isArray(items.allOf)) {\n // pivot to-many: the $ref is the allOf entry that carries it\n const type = this.constFromAllOf(items.allOf)\n if (type === undefined) {\n return undefined\n }\n const relation: RelationDescriptor = { cardinality: 'many', types: [type], pivot: true }\n const readPivot = this.pivotDescriptor(pivotNodeFromAllOf(items.allOf), 'read')\n if (readPivot !== undefined) {\n relation.readPivot = readPivot\n }\n return relation\n }\n if (Array.isArray(items.anyOf)) {\n // polymorphic to-many, a union even of one type (generator contract 16)\n const types = this.constsFromRefs(items.anyOf)\n return types.length === 0\n ? undefined\n : { cardinality: 'many', types, polymorphic: true, pivot: false }\n }\n return undefined\n }\n\n // to-one: data.anyOf with the non-null entries being $refs (or pivot allOfs);\n // a polymorphic to-one nests its $refs one level deeper in another anyOf.\n if (Array.isArray(data.anyOf)) {\n const types: string[] = []\n let pivot = false\n let polymorphic = false\n let readPivot: PivotDescriptor | undefined\n for (const entry of data.anyOf) {\n if (typeof entry.$ref === 'string') {\n const type = this.resolveConst(entry.$ref)\n if (type !== undefined) {\n types.push(type)\n }\n } else if (Array.isArray(entry.allOf)) {\n const type = this.constFromAllOf(entry.allOf)\n if (type !== undefined) {\n types.push(type)\n pivot = true\n readPivot = this.pivotDescriptor(pivotNodeFromAllOf(entry.allOf), 'read')\n }\n } else if (Array.isArray(entry.anyOf)) {\n // polymorphic to-one: the non-null entry is itself an anyOf of $refs, even of one\n types.push(...this.constsFromRefs(entry.anyOf))\n polymorphic = true\n }\n }\n if (types.length === 0) {\n return undefined\n }\n const relation: RelationDescriptor = polymorphic\n ? { cardinality: 'one', types, polymorphic: true, pivot }\n : { cardinality: 'one', types, pivot }\n if (readPivot !== undefined) {\n relation.readPivot = readPivot\n }\n return relation\n }\n\n return undefined\n }\n\n /**\n * The request pivot of a pivot relation: read off the component a write body (or a\n * relationship mutation) refs, falling back to the rendered relationship's pivot minus its\n * `readOnly` fields when no request shape is published (before generator contract 8).\n */\n private writePivot(ref: string | undefined, fallback: SchemaObject): PivotDescriptor | undefined {\n const component = ref === undefined ? undefined : this.schemas[refName(ref) ?? '']\n return this.pivotDescriptor(\n pivotNodeOf(component ?? fallback) ?? pivotNodeOf(fallback),\n 'write',\n )\n }\n\n /**\n * A {@link PivotDescriptor} from a member's `meta.pivot` schema: field hints, the required\n * fields and the nullable ones. Generator contract 8 refs a `<Type><Rel>Pivot` (response) or\n * `<Type><Rel>WritePivot` (request) component, each with its own `required`. An older document\n * inlines one shared schema in the write context, so a read takes every field as rendered and a\n * write drops the `readOnly` ones. `undefined` when the schema has no fields.\n */\n private pivotDescriptor(\n node: SchemaObject | undefined,\n side: 'read' | 'write',\n ): PivotDescriptor | undefined {\n if (node === undefined) {\n return undefined\n }\n const shared = typeof node.$ref !== 'string'\n const schema = shared ? node : this.schemas[refName(node.$ref as string) ?? '']\n const fields: Record<string, string> = {}\n const nullable: string[] = []\n for (const [name, prop] of Object.entries(schema?.properties ?? {})) {\n if (!isSchema(prop) || prop[side === 'read' ? 'writeOnly' : 'readOnly'] === true) {\n continue\n }\n fields[name] = formatHint(prop)\n if (isNullable(prop)) {\n nullable.push(name)\n }\n }\n const names = Object.keys(fields)\n if (names.length === 0) {\n return undefined\n }\n const required =\n shared && side === 'read' ? names : names.filter((name) => schema?.required?.includes(name))\n const out: PivotDescriptor = { fields: sortRecord(fields) }\n if (required.length < names.length) {\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created array\n out.required = required.sort()\n }\n if (nullable.length > 0) {\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created array\n out.nullable = nullable.sort()\n }\n return out\n }\n\n /** Pull the related type from the `$ref` entry of an `allOf` (the pivot shape). */\n private constFromAllOf(allOf: readonly SchemaObject[]): string | undefined {\n for (const entry of allOf) {\n if (typeof entry.$ref === 'string') {\n const type = this.resolveConst(entry.$ref)\n if (type !== undefined) {\n return type\n }\n }\n }\n return undefined\n }\n\n /** Resolve every `$ref` entry in a list to its wire type. */\n private constsFromRefs(entries: readonly SchemaObject[]): string[] {\n const types: string[] = []\n for (const entry of entries) {\n if (typeof entry.$ref === 'string') {\n const type = this.resolveConst(entry.$ref)\n if (type !== undefined) {\n types.push(type)\n }\n }\n }\n return types\n }\n\n private clientId(base: string): ClientIdPolicy {\n const create = this.schemas[`${base}CreateRequest`]\n const data = isSchema(create?.properties?.['data']) ? create.properties['data'] : undefined\n if (data === undefined) {\n return 'forbidden'\n }\n if (data.properties?.['id'] === false) {\n return 'forbidden'\n }\n return data.required?.includes('id') ? 'required' : 'optional'\n }\n\n /**\n * Find the collection path for a type, then derive each per-operation path that\n * actually exists. The collection path P is the one whose POST requestBody refs\n * `<Base>CreateRequest`, else the GET whose 200 response refs `<Base>Collection`.\n */\n private operationPaths(base: string): Record<string, string> {\n const collection = this.collectionPath(base)\n const out: Record<string, string> = {}\n if (collection === undefined) {\n return out\n }\n\n if (this.operation(collection, 'get')) {\n out['fetchMany'] = collection\n }\n if (this.operation(collection, 'post')) {\n out['create'] = collection\n }\n\n const item = `${collection}/{id}`\n if (this.operation(item, 'get')) {\n out['fetchOne'] = item\n }\n if (this.operation(item, 'patch')) {\n out['update'] = item\n }\n if (this.operation(item, 'delete')) {\n out['delete'] = item\n }\n\n if (this.hasRelatedPath(collection)) {\n out['fetchRelated'] = `${collection}/{id}/{rel}`\n }\n if (this.hasRelationshipPath(collection)) {\n out['fetchRelationship'] = `${collection}/{id}/relationships/{rel}`\n }\n\n return sortRecord(out)\n }\n\n private collectionPath(base: string): string | undefined {\n let byCollection: string | undefined\n for (const [path, item] of Object.entries(this.paths)) {\n const post = item.post\n if (post && refEndsWith(this.requestBodyRef(post), `${base}CreateRequest`)) {\n return path\n }\n // Only a genuine top-level collection qualifies for the response-ref fallback —\n // a parent-scoped *related* collection (e.g. `/users/{id}/playlists`) also refs\n // `<Base>Collection` but is not a fetchMany endpoint for that type.\n if (\n byCollection === undefined &&\n !path.includes('/{id}/') &&\n refEndsWith(this.okResponseRef(item.get), `${base}Collection`)\n ) {\n byCollection = path\n }\n }\n return byCollection\n }\n\n /** Any `P/{id}/<rel>` related path (excludes relationships/ and custom `-actions`). */\n private hasRelatedPath(collection: string): boolean {\n const prefix = `${collection}/{id}/`\n return Object.keys(this.paths).some((path) => {\n if (!path.startsWith(prefix)) {\n return false\n }\n const rest = path.slice(prefix.length)\n return rest.length > 0 && !rest.includes('/') && !rest.startsWith('-')\n })\n }\n\n private hasRelationshipPath(collection: string): boolean {\n const prefix = `${collection}/{id}/relationships/`\n return Object.keys(this.paths).some(\n (path) => path.startsWith(prefix) && !path.slice(prefix.length).includes('/'),\n )\n }\n\n /** Detect the paginator from the fetchMany operation's page parameters. */\n private paginator(base: string): PaginatorDescriptor {\n const collection = this.collectionPath(base)\n return this.paginatorOf(this.operation(collection ?? '', 'get'), collection)\n }\n\n /**\n * Detect the paginator an operation advertises. A page schema stamped with `x-paginator`\n * (contract 3) names its strategy and the wire key for each role, so it decides both. Without\n * the stamp, the strategy is inferred from canonical member names (see {@link kindOfMembers}).\n * Anything unrecognised warns and generates as unpaginated. `label` (a path) names the endpoint\n * in the warning; without it nothing is logged.\n */\n private paginatorOf(op: OperationObject | undefined, label?: string): PaginatorDescriptor {\n const warn = (problem: string): 'none' => {\n if (label !== undefined) {\n // eslint-disable-next-line no-console\n console.warn(\n `json-api codegen: endpoint \"${label}\" ${problem}; treating it as unpaginated.`,\n )\n }\n return 'none'\n }\n\n const schema = op?.parameters?.find((param) => param.name === 'page')?.schema\n if (schema?.['x-paginator'] !== undefined) {\n return stampedPaginator(schema, warn)\n }\n\n const { members, menu } = this.pageMembers(op)\n if (menu === undefined) {\n const kind = kindOfMembers(members)\n if (kind !== undefined) {\n return kind\n }\n }\n // A page parameter matching no single known kind is a drift the client would silently treat\n // as unpaginated; warn rather than swallow it (D28).\n if (menu !== undefined) {\n return warn(\n `advertises a selectable page strategy menu (${menu\n .map((arm) => kindOfMembers(arm) ?? sortedList(arm))\n .join(' | ')}) without an x-paginator stamp naming its default`,\n )\n }\n return members.size > 0\n ? warn(\n `advertises page parameters matching no known paginator kind (members ${sortedList(members)})`,\n )\n : 'none'\n }\n\n /**\n * The `page` members an operation accepts, from either wire form: one `page` parameter\n * (`style: deepObject`) whose schema `properties` name the members, as `haddowg/json-api` v1\n * projects it, or the older flattened `page[number]`/`page[size]` parameters. A `oneOf` page\n * schema (a MultiPaginator menu) yields each arm's members in `menu` instead, minus the\n * `kind` discriminator.\n */\n private pageMembers(op: OperationObject | undefined): {\n members: Set<string>\n menu?: Set<string>[]\n } {\n const members = new Set<string>()\n let menu: Set<string>[] | undefined\n for (const param of op?.parameters ?? []) {\n const name = param.name\n if (name === 'page') {\n const arms = param.schema?.oneOf\n if (arms !== undefined) {\n menu = arms.map(\n (arm) => new Set(Object.keys(arm.properties ?? {}).filter((m) => m !== 'kind')),\n )\n }\n for (const member of Object.keys(param.schema?.properties ?? {})) {\n members.add(member)\n }\n } else if (name?.startsWith('page[') === true && name.endsWith(']')) {\n members.add(name.slice('page['.length, -1))\n }\n }\n return menu === undefined ? { members } : { members, menu }\n }\n\n /**\n * The `withCount` capability (Countable profile) for a type's COLLECTION read (`list`): the\n * count tokens (`schema.items.enum`) + the negotiation profile (`x-profile`) carried by the\n * collection GET's `withCount` query parameter. Returns `undefined` when the collection\n * doesn't exist or advertises no `withCount`. The profile URI is never hardcoded — it is read\n * from the parameter's `x-profile`.\n *\n * Deliberately scoped to the collection GET only. The per-endpoint token sets differ\n * (a collection counts e.g. `tracks`; a related/relationship endpoint counts `_self_` and its\n * own relations), so a single per-type `countable` can only honestly describe one endpoint.\n * The fluent surface exposes `withCount` on `list` (the collection), so `countable` mirrors\n * that endpoint — a related-GET fallback would advertise tokens `list` cannot legally send.\n */\n private countable(collection: string | undefined): CountableDescriptor | undefined {\n if (collection === undefined) {\n return undefined\n }\n return withCountParam(this.operation(collection, 'get'))\n }\n\n /**\n * The relation paths the read endpoints accept in `include` — the `include` query\n * parameter's `schema.items.enum` (already including nested dotted paths) on the collection\n * GET. Returns `undefined` when the collection advertises no `include` (nothing includable).\n *\n * Read from the collection GET to mirror {@see sortable}/{@see filterable}: the whole builder\n * is collection-centric (a type with no collection path gets no `paths` at all), and the bundle\n * advertises the same `include` enum on the collection and single-resource GETs.\n */\n private includable(collection: string | undefined): readonly string[] | undefined {\n if (collection === undefined) {\n return undefined\n }\n const tokens = paramItemsEnum(this.operation(collection, 'get'), 'include')\n return tokens !== undefined && tokens.length > 0 ? tokens : undefined\n }\n\n /**\n * The sort tokens the COLLECTION read accepts — the `sort` query parameter's\n * `schema.items.enum` (signed field names) on the collection GET. Returns `undefined` when\n * the collection advertises no `sort` parameter (sorting unsupported).\n */\n private sortable(collection: string | undefined): readonly string[] | undefined {\n if (collection === undefined) {\n return undefined\n }\n const tokens = paramItemsEnum(this.operation(collection, 'get'), 'sort')\n return tokens !== undefined && tokens.length > 0 ? tokens : undefined\n }\n\n /**\n * The filter keys the COLLECTION read accepts in `filter[...]` (the `filter[<key>]` parameter\n * names, `<key>` extracted), sorted for deterministic output. Returns `undefined` when the\n * collection advertises no `filter[...]` parameters (filtering unsupported). Value shapes are\n * deliberately not captured — `filter` values stay `unknown` (out of scope for v0.1).\n */\n private filterable(collection: string | undefined): readonly string[] | undefined {\n if (collection === undefined) {\n return undefined\n }\n const keys: string[] = []\n for (const param of this.operation(collection, 'get')?.parameters ?? []) {\n const name = param.name\n if (typeof name === 'string' && name.startsWith('filter[') && name.endsWith(']')) {\n keys.push(name.slice('filter['.length, -1))\n }\n }\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created key array\n return keys.length > 0 ? keys.sort() : undefined\n }\n\n private operation(path: string, method: HttpMethod): OperationObject | undefined {\n return this.paths[path]?.[method]\n }\n\n private requestBodyRef(op: OperationObject | undefined): string | undefined {\n return op?.requestBody?.content?.['application/vnd.api+json']?.schema?.$ref\n }\n\n private okResponseRef(op: OperationObject | undefined): string | undefined {\n return op?.responses?.['200']?.content?.['application/vnd.api+json']?.schema?.$ref\n }\n}\n\n/** The `meta.pivot` schema node of a pivot `allOf` entry list, if any. */\nfunction pivotNodeFromAllOf(allOf: readonly SchemaObject[]): SchemaObject | undefined {\n for (const entry of allOf) {\n const meta = entry.properties?.['meta']\n const pivot = isSchema(meta) ? meta.properties?.['pivot'] : undefined\n if (isSchema(pivot)) {\n return pivot\n }\n }\n return undefined\n}\n\n/**\n * The `meta.pivot` schema node of a relationship component or document: its to-many `items`\n * `allOf`, or a to-one `anyOf` entry's `allOf`.\n */\nfunction pivotNodeOf(component: SchemaObject): SchemaObject | undefined {\n const data = component.properties?.['data']\n if (!isSchema(data)) {\n return undefined\n }\n if (Array.isArray(data.items?.allOf)) {\n return pivotNodeFromAllOf(data.items.allOf)\n }\n for (const entry of data.anyOf ?? []) {\n if (Array.isArray(entry.allOf)) {\n return pivotNodeFromAllOf(entry.allOf)\n }\n }\n return undefined\n}\n\n/** Whether a schema admits `null`: a `null` type, or a `null` branch in `anyOf`/`oneOf`. */\nfunction isNullable(schema: SchemaObject): boolean {\n const type = schema.type\n if (type === 'null' || (Array.isArray(type) && type.includes('null'))) {\n return true\n }\n return [...(schema.anyOf ?? []), ...(schema.oneOf ?? [])].some((branch) => branch.type === 'null')\n}\n\n/** A schema's wire format hint: explicit `format`, else the JSON type, else a ref-enum is `string`. */\nfunction formatHint(schema: SchemaObject): string {\n if (typeof schema.format === 'string') {\n return schema.format\n }\n const types = typeKeys(schema.type)\n if (types.length > 0) {\n return types[0]!\n }\n // A $ref (typically an enum component) renders as a string union.\n if (typeof schema.$ref === 'string') {\n return 'string'\n }\n // A nullable `$ref` is `anyOf: [{ $ref }, { type: 'null' }]`: hint the value branch.\n const isNullOnly = (branch: SchemaObject): boolean =>\n branch.type !== undefined && typeKeys(branch.type).length === 0\n const branches = (schema.anyOf ?? schema.oneOf ?? []).filter((branch) => !isNullOnly(branch))\n if (branches.length === 1) {\n return formatHint(branches[0]!)\n }\n return 'unknown'\n}\n\nfunction refEndsWith(ref: string | undefined, suffix: string): boolean {\n return ref !== undefined && refName(ref) === suffix\n}\n\n/**\n * Read the {@link CountableDescriptor} off an operation's `withCount` query parameter: the\n * count tokens from its `schema.items.enum` and the negotiation profile from `x-profile`.\n * Returns `undefined` when the operation has no `withCount` parameter, or when one is present\n * but carries no `x-profile` (a `withCount` we can't tell a client how to negotiate). An empty\n * or absent token enum yields `[]` tokens (the profile alone is still actionable).\n */\nfunction withCountParam(op: OperationObject | undefined): CountableDescriptor | undefined {\n for (const param of op?.parameters ?? []) {\n if (param.name !== 'withCount') {\n continue\n }\n const profile = param['x-profile']\n if (typeof profile !== 'string') {\n return undefined\n }\n const enumValues = param.schema?.items?.enum\n const tokens = Array.isArray(enumValues)\n ? enumValues.filter((v): v is string => typeof v === 'string')\n : []\n return { tokens, profile }\n }\n return undefined\n}\n\n/**\n * The string members of an array-valued query parameter's `schema.items.enum` (the shape the\n * `include` and `sort` parameters use). Returns `undefined` when the operation carries no\n * parameter of that name, or one whose schema declares no enum.\n */\nfunction paramItemsEnum(\n op: OperationObject | undefined,\n paramName: string,\n): readonly string[] | undefined {\n for (const param of op?.parameters ?? []) {\n if (param.name !== paramName) {\n continue\n }\n const enumValues = param.schema?.items?.enum\n return Array.isArray(enumValues)\n ? enumValues.filter((v): v is string => typeof v === 'string')\n : undefined\n }\n return undefined\n}\n\n/**\n * True for the Atomic Operations ext media type — `application/vnd.api+json` carrying the\n * atomic `ext` parameter ({@link ATOMIC_EXT}). Tolerant of quoting/whitespace so any of\n * `ext=\"…\"` / `ext=…` matches.\n */\nfunction isAtomicMediaType(mediaType: string): boolean {\n return mediaType.startsWith(JSON_API_MEDIA_TYPE) && mediaType.includes(ATOMIC_EXT)\n}\n\n/** Whether a media type is JSON:API, with or without `ext` / `profile` parameters. */\nfunction isJsonApiMediaType(mediaType: string): boolean {\n return mediaType.split(';')[0]!.trim().toLowerCase() === JSON_API_MEDIA_TYPE\n}\n\n/** Whether a non-JSON:API media type carries JSON: `application/json` or a `+json` suffix. */\nfunction isJsonMediaType(mediaType: string): boolean {\n const essence = mediaType.split(';')[0]!.trim().toLowerCase()\n return essence === 'application/json' || essence.endsWith('+json')\n}\n\n/** The HTTP methods an action operation may be advertised under, in resolution preference order. */\nconst ACTION_METHODS: readonly HttpMethod[] = ['post', 'get', 'put', 'patch', 'delete']\n\n/**\n * The operations an action is invoked over, the preferred one first: POST when advertised (the\n * common default), else the first advertised method. The other methods follow only when their\n * `operationId` differs from the preferred one's, as contract 15 makes it for an action answering\n * to several methods. An older document gave every method one id, and its client exposed only the\n * preferred one. Empty when the path item carries no operation at all.\n */\nfunction pickOperations(item: PathItemObject): { method: HttpMethod; op: OperationObject }[] {\n const available = ACTION_METHODS.filter((method) => item[method] !== undefined)\n const preferred = available.includes('post') ? 'post' : available[0]\n if (preferred === undefined) {\n return []\n }\n const first = item[preferred]!\n const out = [{ method: preferred, op: first }]\n for (const method of available) {\n const op = item[method]!\n if (method !== preferred && op.operationId !== first.operationId) {\n out.push({ method, op })\n }\n }\n return out\n}\n\n/**\n * The name a multi-method action's other methods go under: the action's name and the method,\n * joined the way the name joins its words. So `export` gives `exportGet` and `bulk-import` gives\n * `bulk-import-get`. Core refuses action ids that differ only in case or punctuation, so the\n * name can't clash with another action's.\n */\nfunction methodActionName(name: string, method: HttpMethod): string {\n const separator = /[-_.]/.exec(name)?.[0]\n return separator === undefined\n ? `${name}${method[0]!.toUpperCase()}${method.slice(1)}`\n : `${name}${separator}${method}`\n}\n\n/** The body shape a custom action accepts: a JSON:API document, none, or a raw payload. */\nfunction actionInput(op: OperationObject): ActionDescriptor['input'] {\n const content = op.requestBody?.content\n if (content === undefined || Object.keys(content).length === 0) {\n return 'none'\n }\n return JSON_API_MEDIA_TYPE in content ? 'document' : 'raw'\n}\n\n/** The `$ref` of an action's JSON:API request body (a `document` input), or `undefined`. */\nfunction actionRequestRef(op: OperationObject): string | undefined {\n const ref = op.requestBody?.content?.[JSON_API_MEDIA_TYPE]?.schema?.$ref\n return typeof ref === 'string' ? ref : undefined\n}\n\n/** The declared media type of a `raw`-input action — the first non-JSON:API content type. */\nfunction rawContentType(op: OperationObject): string | undefined {\n const content = op.requestBody?.content\n if (content === undefined) {\n return undefined\n }\n return Object.keys(content).find((mediaType) => mediaType !== JSON_API_MEDIA_TYPE)\n}\n\n/**\n * What a custom action returns from its first 2xx response: a `meta`-only document (a `$ref` to the\n * shared `MetaDocument` — no `data`), a resource `document` (any other JSON:API body), or `none`\n * (only a `204`).\n */\nfunction actionOutput(op: OperationObject): ActionDescriptor['output'] {\n const schema = okJsonApiSchema(op)\n if (schema === undefined) {\n return 'none'\n }\n const arm = documentArms(schema)[0]\n if (arm === undefined) {\n return locationMediaType(schema) === undefined ? 'document' : 'location'\n }\n return typeof arm.$ref === 'string' && refName(arm.$ref) === 'MetaDocument' ? 'meta' : 'document'\n}\n\n/** The JSON:API schema of an operation's first success response that declares one. */\nfunction okJsonApiSchema(op: OperationObject): SchemaObject | undefined {\n for (const [code, response] of Object.entries(op.responses ?? {})) {\n if (!code.startsWith('2')) {\n continue\n }\n const schema = response.content?.[JSON_API_MEDIA_TYPE]?.schema\n if (schema !== undefined) {\n return schema\n }\n }\n return undefined\n}\n\n/** Whether a schema is a location document: a `$ref` to `LocationDocument`, or an `allOf` with one. */\nfunction isLocationSchema(schema: SchemaObject): boolean {\n const isRef = (entry: SchemaObject) =>\n typeof entry.$ref === 'string' && refName(entry.$ref) === 'LocationDocument'\n return isRef(schema) || (schema.allOf?.some(isRef) ?? false)\n}\n\n/**\n * The documents a success response's schema offers besides a location document (generator\n * contract 17): each `oneOf` member that isn't one, or the schema itself when it isn't one.\n */\nfunction documentArms(schema: SchemaObject): SchemaObject[] {\n const arms = schema.oneOf ?? [schema]\n return arms.filter((arm) => !isLocationSchema(arm))\n}\n\n/**\n * The media type a location document's `links.location.type` is fixed to (generator contract\n * 17), `application/octet-stream` when the schema fixes none, or `undefined` when the schema\n * offers no location document.\n */\nfunction locationMediaType(schema: SchemaObject): string | undefined {\n const location = (schema.oneOf ?? [schema]).find(isLocationSchema)\n if (location === undefined) {\n return undefined\n }\n for (const entry of location.allOf ?? []) {\n const links = entry.properties?.['links']\n const link = isSchema(links) ? links.properties?.['location'] : undefined\n const type = isSchema(link) ? link.properties?.['type'] : undefined\n if (isSchema(type) && typeof type.const === 'string') {\n return type.const\n }\n }\n return 'application/octet-stream'\n}\n\n/** Build the {@link ApiDescriptor} from a parsed OpenAPI document. */\nexport function buildDescriptor(doc: OpenApiDocument): ApiDescriptor {\n return new DescriptorBuilder(doc).build()\n}\n\n/** Detect the server-level Atomic Operations capability (`null` when none). */\nexport function buildAtomic(doc: OpenApiDocument): AtomicDescriptor | null {\n return new DescriptorBuilder(doc).buildAtomic()\n}\n\n/**\n * Classify a page member set: `number`+`size` = `page`; `offset`+`limit` = `offset`; either\n * cursor bound (`after`/`before`) = `cursor` (link-driven, D44); `number` alone = `fixed` (the\n * server fixes the size); no members = `none`; anything else = `undefined` (unrecognised).\n */\nfunction kindOfMembers(members: ReadonlySet<string>): PaginatorKind | undefined {\n if (members.has('number') && members.has('size')) {\n return 'page'\n }\n if (members.has('offset') && members.has('limit')) {\n return 'offset'\n }\n if (members.has('after') || members.has('before')) {\n return 'cursor'\n }\n if (members.size === 1 && members.has('number')) {\n return 'fixed'\n }\n return members.size === 0 ? 'none' : undefined\n}\n\n// oxlint-disable-next-line no-array-sort -- sorting a freshly-created array\nconst sortedList = (members: ReadonlySet<string>): string => [...members].sort().join(', ')\n\nconst STRATEGIES: readonly PaginatorStrategy[] = ['page', 'offset', 'cursor', 'fixed']\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/**\n * Read a page schema's `x-paginator` stamp. A strategy keeps the wire key the stamp names for\n * each of its roles (a missing role keeps its canonical name) and collapses to the bare kind when\n * every key is canonical. A `multi` stamp reads each `oneOf` arm by its `kind` const: an arm's own\n * stamp decides it, an unstamped arm falls back to name inference, and an arm neither recognises\n * is left out of the menu.\n */\nfunction stampedPaginator(\n schema: SchemaObject,\n warn: (problem: string) => 'none',\n): PaginatorDescriptor {\n const stamp = schema['x-paginator']\n const strategy = isRecord(stamp) ? stamp['strategy'] : undefined\n if (!isRecord(stamp) || typeof strategy !== 'string') {\n return warn('stamps a malformed x-paginator')\n }\n if (strategy === 'multi') {\n return stampedMenu(schema, stamp, warn)\n }\n if (!(STRATEGIES as readonly string[]).includes(strategy)) {\n return warn(`stamps an x-paginator strategy \"${strategy}\" this codegen does not know`)\n }\n const kind = strategy as PaginatorStrategy\n const canonical: Partial<Record<PaginatorRole, string>> = CANONICAL_PAGE_KEYS[kind]\n const stamped = isRecord(stamp['keys']) ? stamp['keys'] : {}\n const keys: Partial<Record<PaginatorRole, string>> = {}\n let renamed = false\n for (const [role, fallback] of Object.entries(canonical) as [PaginatorRole, string][]) {\n const key = typeof stamped[role] === 'string' ? stamped[role] : fallback\n keys[role] = key\n renamed ||= key !== fallback\n }\n return renamed ? { strategy: kind, keys } : kind\n}\n\nfunction stampedMenu(\n schema: SchemaObject,\n stamp: Record<string, unknown>,\n warn: (problem: string) => 'none',\n): PaginatorDescriptor {\n const arms: Record<string, MenuDescriptor['arms'][string]> = {}\n for (const arm of schema.oneOf ?? []) {\n const discriminator = arm.properties?.['kind']\n const kind = isRecord(discriminator) ? discriminator['const'] : undefined\n if (typeof kind !== 'string') {\n warn('offers a page strategy menu arm without a kind const, which is left out')\n continue\n }\n const paginator =\n arm['x-paginator'] !== undefined\n ? stampedPaginator(arm, (problem) =>\n warn(`offers a menu arm \"${kind}\" that ${problem}, which is left out`),\n )\n : (kindOfMembers(new Set(Object.keys(arm.properties ?? {}).filter((m) => m !== 'kind'))) ??\n warn(`offers a menu arm \"${kind}\" matching no known paginator kind, which is left out`))\n if (typeof paginator === 'object' && paginator.strategy === 'multi') {\n warn(`nests a page strategy menu in arm \"${kind}\", which is left out`)\n continue\n }\n if (paginator !== 'none') {\n arms[kind] = paginator\n }\n }\n const fallback = stamp['default']\n if (typeof fallback !== 'string' || arms[fallback] === undefined) {\n return warn(\n `stamps a page strategy menu whose default ${typeof fallback === 'string' ? `\"${fallback}\"` : '(missing)'} is not one of its generated arms`,\n )\n }\n return { strategy: 'multi', default: fallback, arms }\n}\n","import type {\n ActionDescriptor,\n ApiDescriptor,\n ApiExamples,\n MediaExamples,\n OperationExamples,\n ResourceExamples,\n} from '@haddowg/json-api-client'\nimport type { HttpMethod, MediaTypeObject, OpenApiDocument, OperationObject } from './openapi'\n\n/** Operations that belong to no single type, so they have no place under one. */\nconst SERVER_OPERATIONS = new Set(['action', 'atomic'])\n\n/** The `example` of each media type that declares one, in the document's order. */\nfunction mediaExamples(\n content: Readonly<Record<string, MediaTypeObject>> | undefined,\n): MediaExamples | undefined {\n const out: Record<string, unknown> = {}\n for (const [mediaType, media] of Object.entries(content ?? {})) {\n if (media !== null && typeof media === 'object' && 'example' in media) {\n out[mediaType] = media.example\n }\n }\n return Object.keys(out).length === 0 ? undefined : out\n}\n\n/**\n * The request example and the `2xx` response examples of one operation, or `undefined` when it\n * declares none. Error responses are shared components rather than per-operation, so they are\n * left out.\n */\nexport function operationExamples(op: OperationObject | undefined): OperationExamples | undefined {\n if (op === undefined) {\n return undefined\n }\n const out: { request?: MediaExamples; responses?: Record<string, MediaExamples> } = {}\n const request = mediaExamples(op.requestBody?.content)\n if (request !== undefined) {\n out.request = request\n }\n for (const [status, response] of Object.entries(op.responses ?? {})) {\n const examples = status.startsWith('2') ? mediaExamples(response.content) : undefined\n if (examples !== undefined) {\n out.responses ??= {}\n out.responses[status] = examples\n }\n }\n return out.request === undefined && out.responses === undefined ? undefined : out\n}\n\n/** The operation an action is invoked over: its declared method, else `POST`. */\nexport function actionOperation(\n doc: OpenApiDocument,\n action: ActionDescriptor,\n): OperationObject | undefined {\n const method = (action.method ?? 'POST').toLowerCase() as HttpMethod\n return doc.paths?.[action.path]?.[method]\n}\n\nfunction sorted<V>(record: Record<string, V>): Record<string, V> {\n const out: Record<string, V> = {}\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created key array\n for (const key of Object.keys(record).sort()) {\n out[key] = record[key]!\n }\n return out\n}\n\n/**\n * Collect the worked examples a contract 12 document puts on each operation, per type. A type's\n * operations are found by the `operationId`s the projector stamps (`create.albums`,\n * `fetchRelated.albums.tracks`) and keyed by that id without the type; its actions are keyed by\n * name, as the descriptor keys them. Types, operations and parts with no example are left out, so\n * a document without examples gives `{}`.\n */\nexport function buildExamples(doc: OpenApiDocument, descriptor: ApiDescriptor): ApiExamples {\n const operations = new Map<string, Record<string, OperationExamples>>()\n for (const item of Object.values(doc.paths ?? {})) {\n for (const op of Object.values(item) as (OperationObject | undefined)[]) {\n const id = op?.operationId\n if (typeof id !== 'string') {\n continue\n }\n // JSON:API member names can't hold a `.`, so the type is always the second segment.\n const [prefix, type, ...relation] = id.split('.')\n if (\n prefix === undefined ||\n type === undefined ||\n SERVER_OPERATIONS.has(prefix) ||\n !Object.hasOwn(descriptor, type)\n ) {\n continue\n }\n const examples = operationExamples(op)\n if (examples === undefined) {\n continue\n }\n let byName = operations.get(type)\n if (byName === undefined) {\n byName = {}\n operations.set(type, byName)\n }\n byName[[prefix, ...relation].join('.')] = examples\n }\n }\n\n const out: Record<string, ResourceExamples> = {}\n for (const [type, resource] of Object.entries(descriptor)) {\n const entry: {\n operations?: Record<string, OperationExamples>\n actions?: Record<string, OperationExamples>\n } = {}\n const byName = operations.get(type)\n if (byName !== undefined) {\n entry.operations = sorted(byName)\n }\n for (const [name, action] of Object.entries(resource.actions ?? {})) {\n const examples = operationExamples(actionOperation(doc, action))\n if (examples !== undefined) {\n entry.actions ??= {}\n entry.actions[name] = examples\n }\n }\n if (entry.operations !== undefined || entry.actions !== undefined) {\n out[type] = entry\n }\n }\n return out\n}\n","import type { OpenApiDocument } from './openapi'\n\n/** Below this the document predates the structures this codegen reads. */\nexport const MINIMUM_CONTRACT = 1\n\n/** Above this the document carries structures this codegen does not read. */\nexport const MAXIMUM_CONTRACT = 17\n\n/**\n * Check the document's `info.x-generator.contract` against the range this codegen reads. A\n * document older than the range throws; a newer one returns a warning, because its new\n * structures would go unread and the client would silently miss what the server offers. A\n * document with no contract (json-api before 1.1.0) passes.\n */\nexport function checkContract(doc: OpenApiDocument): string | undefined {\n const contract = doc.info?.['x-generator']?.contract\n if (typeof contract !== 'number') {\n return undefined\n }\n if (contract < MINIMUM_CONTRACT) {\n throw new Error(\n `the document declares contract ${contract}, which predates what this codegen reads (it supports ${MINIMUM_CONTRACT} to ${MAXIMUM_CONTRACT}). Use an older codegen release, or regenerate the document from a newer server.`,\n )\n }\n if (contract > MAXIMUM_CONTRACT) {\n return `the document declares contract ${contract} and this codegen reads up to ${MAXIMUM_CONTRACT}. It describes capabilities that were not generated; upgrade the codegen to pick them up.`\n }\n return undefined\n}\n","import type { SchemaObject, SchemaOrBool } from './openapi'\n\nconst LINK_OBJECT_REF = '#/components/schemas/LinkObject'\n\n/**\n * A link a resource type declares by name (generator contract 14). A link with meta or static\n * members is a link `object`, whose schema lists `href`, each static member as a `const` and its\n * `meta`. A link with neither is `bare`: the server renders it as a URL string.\n */\nexport interface DeclaredLink {\n name: string\n kind: 'object' | 'bare'\n /** The link's own schema, which carries its description and example. */\n schema: SchemaObject\n}\n\nfunction isSchema(value: SchemaOrBool | undefined): value is SchemaObject {\n return typeof value === 'object' && value !== null\n}\n\n/**\n * The declared links on a `<Type>ResourceLinks` component, in document order. `self` is never\n * declared, and a link the server builds itself, such as an action's link, points at\n * `RenderedLink`, so neither is read. A server that renders its links as strings points those at\n * `LinkObject` instead, so they read as bare links, which is the shape they render in. Expects\n * the document's single-entry `allOf` wrappers already read as their `$ref`.\n */\nexport function readDeclaredLinks(component: SchemaObject | undefined): DeclaredLink[] {\n const out: DeclaredLink[] = []\n for (const [name, schema] of Object.entries(component?.properties ?? {})) {\n if (name === 'self' || !isSchema(schema)) {\n continue\n }\n if (schema.$ref === LINK_OBJECT_REF) {\n out.push({ name, kind: 'bare', schema })\n } else if (schema.$ref === undefined && isSchema(schema.properties?.['href'])) {\n out.push({ name, kind: 'object', schema })\n }\n }\n return out\n}\n","/**\n * Helpers for writing strings read from the OpenAPI document into generated TypeScript. Every\n * name, literal and comment the emitters take from the document goes through one of these.\n */\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/** Line terminators as JavaScript counts them. */\nconst LINE_BREAK = /\\r\\n|[\\n\\r\\u2028\\u2029]/\n\n/** A string as a TS string literal. U+2028/U+2029 are escaped too, which JSON leaves raw. */\nexport function stringLiteral(value: string): string {\n return JSON.stringify(value)\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029')\n}\n\n/**\n * A JSON value as a TS literal, indented two spaces with the value's key order kept. A\n * `__proto__` key becomes computed so it stays an own key, and U+2028/U+2029 are escaped.\n */\nexport function jsonLiteral(value: unknown): string {\n return JSON.stringify(value, null, 2)\n .replace(/^(\\s*)\"__proto__\":/gm, '$1[\"__proto__\"]:')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029')\n}\n\n/** True when a string is a bare identifier. */\nexport function isIdentifier(value: string): boolean {\n return IDENTIFIER.test(value)\n}\n\n/**\n * A property key for an object literal or an interface: bare when it's an identifier, quoted\n * otherwise. `__proto__` is written as a computed key, which a runtime literal keeps as an own\n * property instead of setting the prototype.\n */\nexport function propertyKey(name: string): string {\n if (name === '__proto__') {\n return `[${stringLiteral(name)}]`\n }\n return isIdentifier(name) ? name : stringLiteral(name)\n}\n\n/** Text that can sit inside a block comment: any `*\\/` is broken up so it can't close it. */\nexport function commentText(text: string): string {\n return text.replace(/\\*\\//g, '* /')\n}\n\n/** {@link commentText} split into lines, for a multi-line block comment. */\nexport function commentLines(text: string): string[] {\n return commentText(text).split(LINE_BREAK)\n}\n\n/** {@link commentText} on one line, for a single comment line such as the provenance header. */\nexport function commentLine(text: string): string {\n return commentText(text).split(LINE_BREAK).join(' ')\n}\n\n/** Words a type alias can't be named: reserved words and the built-in type names. */\nconst RESERVED_TYPE_NAMES = new Set([\n 'any',\n 'bigint',\n 'boolean',\n 'break',\n 'case',\n 'catch',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'else',\n 'enum',\n 'export',\n 'extends',\n 'false',\n 'finally',\n 'for',\n 'function',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'interface',\n 'let',\n 'never',\n 'new',\n 'null',\n 'number',\n 'object',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'static',\n 'string',\n 'super',\n 'switch',\n 'symbol',\n 'this',\n 'throw',\n 'true',\n 'try',\n 'typeof',\n 'undefined',\n 'unknown',\n 'var',\n 'void',\n 'while',\n 'with',\n 'yield',\n])\n\n/** True when `name` can be used as is for an exported type. */\nexport function isTypeName(name: string): boolean {\n return isIdentifier(name) && !RESERVED_TYPE_NAMES.has(name)\n}\n","import type { OpenApiDocument, SchemaObject, SchemaOrBool } from './openapi'\nimport { commentLines, propertyKey, stringLiteral } from './source'\n\nconst REF_PREFIX = '#/components/schemas/'\nconst ERROR_DOCUMENT = /^ErrorDocument(\\d{3})?$/\n\n/** One documented error code, with whatever the document says about it. */\nexport interface DocumentedErrorCode {\n code: string\n /** The `<Code>Error` component's `description`, when the document has one (contract 4). */\n description?: string\n /** Example `detail` values, from the component's `detail` property (`example` / `examples`). */\n examples: unknown[]\n}\n\n/** The server's error catalogue as the codegen reads it. */\nexport interface ErrorCatalogue {\n /** Every code any error document offers, sorted by code. */\n codes: DocumentedErrorCode[]\n /**\n * Per status, the codes its `ErrorDocument<NNN>` offers, sorted by code. A status whose\n * document offers only the generic `Error` maps to an empty list.\n */\n byStatus: Map<number, string[]>\n}\n\nfunction isSchema(value: SchemaOrBool | undefined): value is SchemaObject {\n return typeof value === 'object' && value !== null\n}\n\n/** A schema node and its `allOf` members, where a code variant keeps its narrowing. */\nfunction layers(schema: SchemaObject): SchemaObject[] {\n return [schema, ...(schema.allOf ?? []).filter((member) => member.$ref === undefined)]\n}\n\nfunction property(schema: SchemaObject, name: string): SchemaObject | undefined {\n for (const layer of layers(schema)) {\n const prop = layer.properties?.[name]\n if (isSchema(prop)) {\n return prop\n }\n }\n return undefined\n}\n\nfunction examplesOf(detail: SchemaObject | undefined): unknown[] {\n if (detail === undefined) {\n return []\n }\n const examples = Array.isArray(detail['examples']) ? [...(detail['examples'] as unknown[])] : []\n if ('example' in detail && !examples.includes(detail['example'])) {\n examples.unshift(detail['example'])\n }\n return examples\n}\n\n/**\n * Read the documented error codes off a document's error documents. `ErrorDocument` and each\n * `ErrorDocument<NNN>` offer their codes as `errors.items.anyOf` branches that `$ref` a\n * `<Code>Error` component; a branch with a `code` const names a code, and the generic `Error`\n * branch (no const) names none.\n */\nexport function readErrorCatalogue(doc: OpenApiDocument): ErrorCatalogue {\n const schemas = doc.components?.schemas ?? {}\n const codes = new Map<string, DocumentedErrorCode>()\n const byStatus = new Map<number, string[]>()\n\n for (const [name, schema] of Object.entries(schemas)) {\n const match = ERROR_DOCUMENT.exec(name)\n if (match === null) {\n continue\n }\n const items = property(schema, 'errors')?.items\n const branches = items === undefined ? [] : [...(items.anyOf ?? []), ...(items.oneOf ?? [])]\n const documentCodes = new Set<string>()\n for (const branch of branches) {\n const component =\n typeof branch.$ref === 'string' && branch.$ref.startsWith(REF_PREFIX)\n ? schemas[branch.$ref.slice(REF_PREFIX.length)]\n : branch\n const code = component === undefined ? undefined : property(component, 'code')?.const\n if (component === undefined || typeof code !== 'string') {\n continue\n }\n documentCodes.add(code)\n if (!codes.has(code)) {\n const description = layers(component)\n .map((layer) => layer.description?.trim())\n .find((text) => text !== undefined && text !== '')\n codes.set(code, {\n code,\n ...(description ? { description } : {}),\n examples: examplesOf(property(component, 'detail')),\n })\n }\n }\n if (match[1] !== undefined) {\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created array\n byStatus.set(Number(match[1]), [...documentCodes].sort())\n }\n }\n\n return {\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created array\n codes: [...codes.values()].sort((a, b) => (a.code < b.code ? -1 : a.code > b.code ? 1 : 0)),\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created array\n byStatus: new Map([...byStatus].sort(([a], [b]) => a - b)),\n }\n}\n\n/** A TSDoc block for one code: its description, then each example detail as an `@example`. */\nfunction codeDoc(entry: DocumentedErrorCode, indent: string): string | undefined {\n const lines: string[] = []\n if (entry.description !== undefined) {\n lines.push(...commentLines(entry.description))\n }\n for (const example of entry.examples) {\n if (lines.length > 0) {\n lines.push('')\n }\n const text = typeof example === 'string' ? example : JSON.stringify(example)\n lines.push(...commentLines(`@example ${text}`))\n }\n if (lines.length === 0) {\n return undefined\n }\n if (lines.length === 1) {\n return `${indent}/** ${lines[0]!} */`\n }\n return [\n `${indent}/**`,\n ...lines.map((line) => `${indent} * ${line}`.trimEnd()),\n `${indent} */`,\n ].join('\\n')\n}\n\n/**\n * Emit `ErrorCodes`, a const object keyed by every documented code with its TSDoc on the key\n * (editors show TSDoc on an object key, not on a string-literal union member), the `ErrorCode`\n * union derived from it, and `ErrorCodeByStatus`, the codes each status's error document offers.\n * A document with no code catalogue gets an empty `ErrorCodes` and `ErrorCode = string`, so the\n * bound guard still takes any code.\n */\nexport function emitErrorCodes(catalogue: ErrorCatalogue): string {\n const codeTypes =\n catalogue.codes.length === 0\n ? [\n '/** The documented error codes. This document catalogues none. */',\n 'export const ErrorCodes = {} as const',\n '',\n '/** The documented error codes. This document catalogues none, so any code is accepted. */',\n 'export type ErrorCode = string',\n ].join('\\n')\n : [\n '/**',\n ' * Every error code this server documents, keyed by itself. Hover a key for what the code',\n ' * means: `hasErrorCode(error, ErrorCodes.RESOURCE_NOT_FOUND)`.',\n ' */',\n 'export const ErrorCodes = {',\n ...catalogue.codes.flatMap((entry) => {\n const doc = codeDoc(entry, ' ')\n const member = ` ${propertyKey(entry.code)}: ${stringLiteral(entry.code)},`\n return doc === undefined ? [member] : [doc, member]\n }),\n '} as const',\n '',\n '/**',\n ' * Every error code this server documents. An error may still carry a code that is not',\n ' * listed: the catalogue is open.',\n ' */',\n 'export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes]',\n ].join('\\n')\n\n const statusLines = [...catalogue.byStatus].map(([status, codes]) => {\n const members = codes.map((c) => stringLiteral(c))\n const line = ` ${status}: ${members.length === 0 ? 'never' : members.join(' | ')}`\n return line.length <= 100\n ? line\n : ` ${status}:\\n${members.map((m) => ` | ${m}`).join('\\n')}`\n })\n const byStatus = [\n '/**',\n ' * The documented error codes per HTTP status. `never` marks a status whose error document',\n ' * documents no specific code.',\n ' */',\n statusLines.length === 0\n ? 'export interface ErrorCodeByStatus {}'\n : `export interface ErrorCodeByStatus {\\n${statusLines.join('\\n')}\\n}`,\n ].join('\\n')\n\n const guard = [\n '/**',\n ' * True when `err` is a `JsonApiError` and any of its error objects carries `code`. Only takes a',\n ' * documented code; match an undocumented one with `hasErrorCode` from',\n \" * '@haddowg/json-api-client'.\",\n ' */',\n 'export const hasErrorCode = hasErrorCodeRuntime as ErrorCodeGuard<ErrorCode>',\n ].join('\\n')\n\n return [codeTypes, byStatus, guard].join('\\n\\n')\n}\n","import { createHash } from 'node:crypto'\nimport type { OpenApiDocument } from './openapi'\nimport { commentLine } from './source'\n\n/**\n * A deterministic provenance record identifying the spec a client was generated from.\n * Stamped into every generated artifact's header so a reader (and the `--check` drift\n * gate) can tell which spec produced the committed output. Deliberately timestamp-free\n * — the same spec must always produce byte-identical output so `--check` can compare.\n */\nexport interface Provenance {\n /** `<title> <version>` from the document's `info` (falls back to `unknown` parts). */\n readonly source: string\n /** The first declared server URL, or `undefined` when none is declared. */\n readonly server: string | undefined\n /** A SHA-256 (first 16 hex chars) of the canonicalised source document. */\n readonly hash: string\n}\n\n/**\n * Canonicalise a JSON value with object keys sorted recursively, so the content hash is\n * insensitive to key ordering in the served document (two byte-different-but-equivalent\n * specs hash the same). Arrays keep their order (it is significant in OpenAPI).\n */\nfunction canonicalise(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(canonicalise)\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created key array\n for (const key of Object.keys(value).sort()) {\n out[key] = canonicalise((value as Record<string, unknown>)[key])\n }\n return out\n }\n return value\n}\n\n/** A SHA-256 over an arbitrary JSON value (canonicalised), truncated to 16 hex chars (64 bits). */\nexport function hashJson(value: unknown): string {\n return createHash('sha256')\n .update(JSON.stringify(canonicalise(value)))\n .digest('hex')\n .slice(0, 16)\n}\n\n/**\n * Derive the provenance record for a source OpenAPI document. The `source` identifier is\n * `<info.title> <info.version>` (each part `unknown` when absent); the `hash` is a stable\n * content hash of the whole document.\n */\nexport function deriveProvenance(doc: OpenApiDocument): Provenance {\n const title = doc.info?.title ?? 'unknown'\n const version = doc.info?.version ?? 'unknown'\n return {\n source: `${title} ${version}`,\n server: doc.servers?.[0]?.url,\n hash: hashJson(doc),\n }\n}\n\n/**\n * Render the provenance record as the JSDoc header lines stamped into a generated artifact\n * (each already prefixed with ` * `), with the document's text kept to one comment line. Deterministic: no timestamp, so re-generating from the\n * same spec yields byte-identical output.\n */\nexport function provenanceLines(provenance: Provenance): string[] {\n const lines = [\n ` * Source spec: ${commentLine(provenance.source)}`,\n ` * Spec hash: ${provenance.hash}`,\n ]\n if (provenance.server !== undefined) {\n lines.splice(1, 0, ` * Server: ${commentLine(provenance.server)}`)\n }\n return lines\n}\n","import {\n type ActionDescriptor,\n type ApiDescriptor,\n type AtomicDescriptor,\n HANDLE_RESERVED,\n type ResourceDescriptor,\n} from '@haddowg/json-api-client'\nimport { buildAtomic } from './build-descriptor'\nimport { type DeclaredLink, readDeclaredLinks } from './declared-links'\nimport { actionOperation, operationExamples } from './build-examples'\nimport { emitErrorCodes, readErrorCatalogue } from './error-codes'\nimport type { OpenApiDocument, OperationObject, SchemaObject, SchemaOrBool } from './openapi'\nimport { deriveProvenance, provenanceLines, type Provenance } from './provenance'\nimport { commentLines, isTypeName, propertyKey, stringLiteral } from './source'\nimport { unwrapRefs } from './unwrap-refs'\n\nconst REF_PREFIX = '#/components/schemas/'\nconst JSON_API_MEDIA_TYPE = 'application/vnd.api+json'\n\n/** A loose JSON:API document shape — the fallback an action body/result types as when its component can't be resolved. */\nconst LOOSE_DOCUMENT = 'Record<string, unknown>'\n\n/** The per-action alias names wired into `ActionTypes`. */\ninterface ActionAliasNames {\n input?: string\n output?: string\n /** JSON-like raw response media type -> its alias. */\n responses?: Map<string, string>\n /** JSON-like request media type -> its alias. */\n requests?: Map<string, string>\n}\n\n/** A relation name that will later collide with a fluent-surface verb. */\nexport interface VerbCollision {\n type: string\n relation: string\n}\n\n/**\n * The reserved relation names: the members the read handle actually shadows (kept in sync\n * via the runtime's {@link HANDLE_RESERVED}) plus the future Phase-3 write verbs. A relation\n * named like any of these must route through `.rel(name)`, so the codegen warns at build time.\n * (`type`/`id` from {@link HANDLE_RESERVED} can never be JSON:API relation names.)\n */\nconst RESERVED_VERBS = new Set<string>([\n ...HANDLE_RESERVED,\n 'update',\n 'delete',\n 'create',\n 'list',\n 'actions',\n])\n\n/**\n * Find relations whose name shadows a reserved fluent-surface member (a handle accessor or a\n * future write verb). Such relations are routed via `.rel(name)`; the codegen warns at build time.\n */\nexport function detectVerbCollisions(descriptor: ApiDescriptor): VerbCollision[] {\n const collisions: VerbCollision[] = []\n for (const type of Object.keys(descriptor)) {\n for (const relation of Object.keys(descriptor[type]!.relations)) {\n if (RESERVED_VERBS.has(relation)) {\n collisions.push({ type, relation })\n }\n }\n }\n return collisions\n}\n\nfunction refName(ref: string): string | undefined {\n return ref.startsWith(REF_PREFIX) ? ref.slice(REF_PREFIX.length) : undefined\n}\n\nfunction isSchema(value: SchemaOrBool | undefined): value is SchemaObject {\n return typeof value === 'object' && value !== null\n}\n\n/** PascalCase a JSON:API wire type for use in a TS identifier (e.g. `public-profiles` -> `PublicProfiles`). */\nfunction pascalCase(value: string): string {\n return value\n .split(/[^a-zA-Z0-9]+/)\n .filter((part) => part.length > 0)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n}\n\n/** The identifier stem for a wire type's interfaces, `Type`-prefixed when it would start with a digit. */\nfunction typeStem(type: string): string {\n const pascal = pascalCase(type)\n return /^[A-Za-z]/.test(pascal) ? pascal : `Type${pascal}`\n}\n\n/** Names the generated module declares or relies on, which an enum alias must not take. */\nconst MODULE_NAMES = [\n 'ActionTypes',\n 'ApiDescriptor',\n 'Attributes',\n 'ClientOptions',\n 'ErrorCode',\n 'ErrorCodeByStatus',\n 'ErrorCodeGuard',\n 'ErrorCodes',\n 'Links',\n 'Record',\n 'ResourceLinks',\n 'ResourceMap',\n 'WriteAttributes',\n]\n\n/**\n * Render a description as a JSDoc comment at the given indent — single-line when it fits,\n * a block otherwise. Returns `undefined` for empty text. Neutralises any `*\\/` so a\n * description can never terminate the comment early.\n */\nfunction jsDoc(text: string | undefined, indent: string): string | undefined {\n const trimmed = text?.trim()\n if (!trimmed) {\n return undefined\n }\n const lines = commentLines(trimmed)\n if (lines.length === 1) {\n return `${indent}/** ${lines[0]} */`\n }\n return [\n `${indent}/**`,\n ...lines.map((line) => `${indent} * ${line}`.trimEnd()),\n `${indent} */`,\n ].join('\\n')\n}\n\n/** The validation keywords a member's TSDoc states, each as a tag of the same name. */\nconst CONSTRAINT_KEYWORDS = [\n 'format',\n 'pattern',\n 'minLength',\n 'maxLength',\n 'minimum',\n 'exclusiveMinimum',\n 'maximum',\n 'exclusiveMaximum',\n 'multipleOf',\n 'minItems',\n 'maxItems',\n 'uniqueItems',\n 'minProperties',\n 'maxProperties',\n] as const\n\n/** A tag value as TSDoc text: strings bare, a pattern or anything structured as code. */\nfunction tagValue(keyword: string, value: unknown): string {\n if (keyword === 'pattern' || (typeof value !== 'string' && typeof value !== 'number')) {\n return `\\`${typeof value === 'string' ? value : JSON.stringify(value)}\\``\n }\n return String(value)\n}\n\n/**\n * The TSDoc for an attribute: its description, then a tag per constraint the schema declares\n * (`@minLength 1`, `@pattern …`), its `@defaultValue`, any `@example` and `@deprecated`. Each\n * schema states the constraints of the context it describes, so a read member and its create\n * and update counterparts can document different bounds. The keywords are read off the member\n * and any inline `anyOf`/`oneOf` branch; a `$ref`'d component documents itself.\n */\nfunction memberDoc(schema: SchemaObject): string | undefined {\n const layers = [\n schema,\n ...[...(schema.anyOf ?? []), ...(schema.oneOf ?? [])].filter(\n (branch) => branch.$ref === undefined,\n ),\n ]\n const tags: string[] = []\n for (const keyword of CONSTRAINT_KEYWORDS) {\n for (const layer of layers) {\n const value = layer[keyword]\n if (value === undefined || value === false) {\n continue\n }\n tags.push(value === true ? `@${keyword}` : `@${keyword} ${tagValue(keyword, value)}`)\n break\n }\n }\n if ('default' in schema) {\n tags.push(`@defaultValue \\`${JSON.stringify(schema['default'])}\\``)\n }\n const examples = Array.isArray(schema['examples']) ? [...(schema['examples'] as unknown[])] : []\n if ('example' in schema && !examples.includes(schema['example'])) {\n examples.unshift(schema['example'])\n }\n for (const example of examples) {\n tags.push(`@example ${typeof example === 'string' ? example : JSON.stringify(example)}`)\n }\n if (schema['deprecated'] === true) {\n tags.push('@deprecated')\n }\n const description = schema.description?.trim()\n if (tags.length === 0) {\n return description\n }\n return description ? `${description}\\n\\n${tags.join('\\n')}` : tags.join('\\n')\n}\n\n/** An `ActionTypes` media map: `{ 'text/csv': Alias; … }`. */\nfunction mediaMap(aliases: Map<string, string>): string {\n const entries = [...aliases].map(([mediaType, alias]) => `${stringLiteral(mediaType)}: ${alias}`)\n return `{ ${entries.join('; ')} }`\n}\n\n/** The schema of `mediaType` under an operation's first 2xx response that lists it. */\nfunction firstSuccessSchema(\n op: OperationObject | undefined,\n mediaType: string,\n): SchemaObject | undefined {\n for (const [code, response] of Object.entries(op?.responses ?? {})) {\n const media = code.startsWith('2') ? response.content?.[mediaType] : undefined\n if (media !== undefined) {\n return media.schema\n }\n }\n return undefined\n}\n\n/**\n * An action's summary and description as JSDoc, leaving out the prose the projector writes for an\n * action whose author gave none (\"Invoke the `name` action\", \"Invokes the `name` custom action on\n * …\"), which says nothing the name doesn't.\n */\nfunction actionDoc(name: string, op: OperationObject | undefined): string | undefined {\n const summary = op?.summary?.trim()\n const description = op?.description?.trim()\n const parts: string[] = []\n if (summary && summary !== `Invoke the \\`${name}\\` action`) {\n parts.push(summary)\n }\n const generated = new RegExp(`^Invokes the \\`${escapeRegExp(name)}\\` custom action on [^.]*\\\\.$`)\n if (description && !generated.test(description)) {\n parts.push(description)\n }\n return parts.length === 0 ? undefined : parts.join('\\n\\n')\n}\n\n/**\n * What an action declares about its effects (generator contract 15), as one sentence, or\n * `undefined` when it declares nothing.\n */\nfunction safetyDoc(action: ActionDescriptor): string | undefined {\n const flags: [boolean | undefined, string][] = [\n [action.readOnly, 'read-only'],\n [action.destructive, 'destructive'],\n [action.idempotent, 'idempotent'],\n ]\n const words = flags\n .filter(([value]) => value !== undefined)\n .map(([value, word]) => (value === true ? word : `not ${word}`))\n if (words.length === 0) {\n return undefined\n }\n const list =\n words.length === 1 ? words[0]! : `${words.slice(0, -1).join(', ')} and ${words.at(-1)!}`\n return `The server declares this action ${list}.`\n}\n\n/**\n * What an action that answers with a URL returns (generator contract 17), as JSDoc, or\n * `undefined` for any other action.\n */\nfunction locationDoc(action: ActionDescriptor): string | undefined {\n if (action.location === undefined) {\n return undefined\n }\n const serving = `a URL serving \\`${action.location.mediaType}\\``\n return action.output === 'location'\n ? `Returns ${serving} as an \\`ActionLocation\\`. The client doesn't follow it.`\n : `May return ${serving} instead, as an \\`ActionLocation\\`. The client doesn't follow it.`\n}\n\n/** A list of scopes as inline code joined into prose: `a`, `b` and `c`. */\nfunction scopeList(scopes: readonly string[]): string {\n const quoted = scopes.map((scope) => `\\`${scope}\\``)\n return quoted.length === 1\n ? quoted[0]!\n : `${quoted.slice(0, -1).join(', ')} and ${quoted.at(-1)!}`\n}\n\n/** The sentence naming the OAuth scopes an operation needs (generator contract 16). */\nfunction scopeDoc(scopes: readonly string[] | undefined): string | undefined {\n if (scopes === undefined || scopes.length === 0) {\n return undefined\n }\n return `Needs the OAuth ${scopes.length === 1 ? 'scope' : 'scopes'} ${scopeList(scopes)}.`\n}\n\n/** The descriptor's `paths` keys, by the operation whose scopes they carry. */\nconst PATH_OPERATIONS: Readonly<Record<string, string>> = {\n fetchMany: 'fetchCollection',\n create: 'create',\n fetchOne: 'fetchOne',\n update: 'update',\n delete: 'delete',\n}\n\n/** A relation's operations, in the order its JSDoc lists their scopes. */\nconst RELATION_OPERATIONS = [\n 'fetchRelated',\n 'fetchRelationship',\n 'updateRelationship',\n 'addRelationship',\n 'removeRelationship',\n] as const\n\n/** The OAuth scopes each of a relation's endpoints needs, one line per operation, or `undefined`. */\nfunction relationScopeDoc(\n scopes: Readonly<Record<string, readonly string[]>> | undefined,\n relation: string,\n): string | undefined {\n const lines = RELATION_OPERATIONS.flatMap((operation) => {\n const needed = scopes?.[`${operation}.${relation}`]\n return needed === undefined || needed.length === 0\n ? []\n : [`- \\`${operation}\\` needs ${scopeList(needed)}`]\n })\n return lines.length === 0 ? undefined : ['OAuth scopes:', '', ...lines].join('\\n')\n}\n\n/** The most lines of example JSON an action's `@example` shows; a longer one is left out. */\nexport const EXAMPLE_DOC_MAX_LINES = 80\n\n/** Whether a media type carries JSON: JSON:API, `application/json` or a `+json` suffix. */\nfunction isJsonMedia(mediaType: string): boolean {\n const essence = mediaType.split(';')[0]!.trim().toLowerCase()\n return essence === 'application/json' || essence.endsWith('+json')\n}\n\n/** The media type to show: JSON:API when it has an example, else the first that does. */\nfunction shownMedia(examples: Readonly<Record<string, unknown>>): string | undefined {\n return JSON_API_MEDIA_TYPE in examples ? JSON_API_MEDIA_TYPE : Object.keys(examples)[0]\n}\n\n/**\n * An `@example` for an action: its request body when it declares one, else its first success\n * response, as a fenced block of pretty-printed JSON (a text body as is). A body over\n * {@link EXAMPLE_DOC_MAX_LINES} lines is named but not shown. The fence is longer than any run of\n * backticks in the body, so the body can't close it.\n */\nfunction exampleDoc(op: OperationObject | undefined): string | undefined {\n const examples = operationExamples(op)\n if (examples === undefined) {\n return undefined\n }\n let label: string\n let media: Readonly<Record<string, unknown>>\n if (examples.request !== undefined) {\n label = 'Request body'\n media = examples.request\n } else {\n const first = Object.entries(examples.responses ?? {})[0]\n if (first === undefined) {\n return undefined\n }\n label = `Response \\`${first[0]}\\``\n media = first[1]\n }\n const mediaType = shownMedia(media)\n if (mediaType === undefined) {\n return undefined\n }\n if (mediaType !== JSON_API_MEDIA_TYPE) {\n label += ` as \\`${mediaType}\\``\n }\n const value = media[mediaType]\n const raw = typeof value === 'string' && !isJsonMedia(mediaType)\n const text = raw ? value.replace(/(?:\\r\\n|\\r|\\n)+$/, '') : JSON.stringify(value, null, 2)\n const lines = text.split(/\\r\\n|\\r|\\n/).length\n if (lines > EXAMPLE_DOC_MAX_LINES) {\n return `@example ${label}\\nThe example is ${lines} lines long, too long to show here.`\n }\n const longest = Math.max(0, ...(text.match(/`+/g) ?? []).map((run) => run.length))\n const fence = '`'.repeat(Math.max(3, longest + 1))\n const language = raw ? '' : 'json'\n return `@example ${label}\\n${fence}${language}\\n${text}\\n${fence}`\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nexport class Emitter {\n private readonly schemas: Record<string, SchemaObject>\n /** Wire type -> the schema `Base` (the `<Base>Resource` name minus `Resource`). */\n private readonly baseByType: Map<string, string>\n /** Enum component names referenced by an attribute, in first-seen order. */\n private readonly usedEnums = new Map<string, SchemaObject>()\n /**\n * Component-schema names whose dedicated interface is emitted (e.g. `AlbumsAttributes`,\n * `AlbumsCreateAttributes`). A `$ref` to one of these resolves to the interface name\n * rather than being re-expanded structurally — so an action envelope nests the precise,\n * already-named attribute type. Populated as interfaces are emitted.\n */\n private readonly emittedInterfaces = new Set<string>()\n /** Enum component name -> the alias name it's emitted under. */\n private readonly enumNames = new Map<string, string>()\n /** Type names already spoken for: the module's own, the per-type interfaces and enum aliases. */\n private readonly takenNames: Set<string>\n /** Component names mid-expansion in {@link tsType} — a cycle guard for self/mutually-referential `$ref`s. */\n private readonly expanding = new Set<string>()\n /**\n * The per-action alias names actually emitted, keyed `type -> actionName -> { input?; output? }`.\n * Populated by {@link actionTypeAliases}; consumed by {@link actionTypesMap} so the action\n * type-map only references aliases that exist (a `none` input/output contributes neither).\n */\n private readonly actionAliasNames = new Map<string, Map<string, ActionAliasNames>>()\n /** Raw body components already emitted as a named alias, by component name. */\n private readonly rawBodyAliases = new Map<string, string>()\n /** JSDoc for entries of the `resourceMap` literal, keyed by their path joined with `/`. */\n private readonly literalDocs = new Map<string, string>()\n\n /** Wire type -> the links it declares, for the types that declare any. */\n private readonly declaredLinks = new Map<string, DeclaredLink[]>()\n\n /** Provenance of the source document, stamped into the generated header for drift tracking. */\n private readonly provenance: Provenance\n\n private readonly doc: OpenApiDocument\n\n constructor(\n source: OpenApiDocument,\n private readonly descriptor: ApiDescriptor,\n private readonly atomic: AtomicDescriptor | null,\n ) {\n this.doc = unwrapRefs(source)\n this.schemas = this.doc.components?.schemas ?? {}\n this.baseByType = this.indexBases()\n this.provenance = deriveProvenance(source)\n this.takenNames = new Set(MODULE_NAMES)\n for (const type of Object.keys(descriptor)) {\n const base = this.baseByType.get(type)\n const links =\n base === undefined ? [] : readDeclaredLinks(this.schemas[`${base}ResourceLinks`])\n if (links.length > 0) {\n this.declaredLinks.set(type, links)\n }\n }\n for (const type of Object.keys(descriptor)) {\n const stem = typeStem(type)\n for (const suffix of ['Attributes', 'CreateAttributes', 'UpdateAttributes', 'Links']) {\n this.takenNames.add(`${stem}${suffix}`)\n }\n for (const [name, action] of Object.entries(descriptor[type]?.actions ?? {})) {\n this.takenNames.add(`${stem}${pascalCase(name)}Input`)\n this.takenNames.add(`${stem}${pascalCase(name)}Output`)\n for (const { mediaType } of action.rawOutput ?? []) {\n this.takenNames.add(`${stem}${pascalCase(name)}${pascalCase(mediaType)}Output`)\n }\n for (const { mediaType } of action.inputMedia ?? []) {\n this.takenNames.add(`${stem}${pascalCase(name)}${pascalCase(mediaType)}Input`)\n }\n const single = action.contentType\n if (\n single !== undefined &&\n (single.startsWith('multipart/') || single === 'application/x-www-form-urlencoded')\n ) {\n this.takenNames.add(`${stem}${pascalCase(name)}${pascalCase(single)}Input`)\n }\n const op = actionOperation(this.doc, action)\n // A multi-method action's other methods are keyed apart from the name the server prose uses.\n const wireName = action.path.slice(action.path.lastIndexOf('/') + 1)\n const parts = [\n actionDoc(wireName, op),\n locationDoc(action),\n safetyDoc(action),\n scopeDoc(action.scopes),\n exampleDoc(op),\n ].filter((part) => part !== undefined)\n const doc = parts.length === 0 ? undefined : parts.join('\\n\\n')\n if (doc !== undefined) {\n this.literalDocs.set(`${type}/actions/${name}`, doc)\n }\n }\n const scopes = descriptor[type]?.scopes\n for (const [key, operation] of Object.entries(PATH_OPERATIONS)) {\n const doc = scopeDoc(scopes?.[operation])\n if (doc !== undefined && descriptor[type]?.paths[key] !== undefined) {\n this.literalDocs.set(`${type}/paths/${key}`, doc)\n }\n }\n for (const relation of Object.keys(descriptor[type]?.relations ?? {})) {\n const doc = relationScopeDoc(scopes, relation)\n if (doc !== undefined) {\n this.literalDocs.set(`${type}/relations/${relation}`, doc)\n }\n }\n }\n }\n\n /**\n * The alias an enum component is emitted under: its own name when that's a usable type name,\n * else one derived from it (with a warning), kept clear of every other name in the module.\n */\n private enumName(component: string): string {\n const known = this.enumNames.get(component)\n if (known !== undefined) {\n return known\n }\n let name = component\n if (!isTypeName(component) || this.takenNames.has(component)) {\n const pascal = pascalCase(component)\n let stem = /^[A-Za-z]/.test(pascal) ? pascal : `Enum${pascal}`\n if (!isTypeName(stem) || this.takenNames.has(stem)) {\n stem = `${stem}Enum`\n }\n name = stem\n for (let n = 2; this.takenNames.has(name); n++) {\n name = `${stem}${n}`\n }\n console.warn(\n `Enum component ${stringLiteral(component)} can't be used as a TypeScript type name; emitting it as ${name}.`,\n )\n }\n this.takenNames.add(name)\n this.enumNames.set(component, name)\n return name\n }\n\n /** Map each declared wire type back to the `Base` of its resource schema. */\n private indexBases(): Map<string, string> {\n const out = new Map<string, string>()\n for (const [name, schema] of Object.entries(this.schemas)) {\n if (!name.endsWith('Resource') || name.endsWith('ResourceIdentifier')) {\n continue\n }\n const typeProp = schema.properties?.['type']\n if (isSchema(typeProp) && typeof typeProp.const === 'string') {\n out.set(typeProp.const, name.slice(0, -'Resource'.length))\n }\n }\n return out\n }\n\n emit(): string {\n // Resolve enums first so the alias block (which depends on `usedEnums`) is populated.\n const interfaces = Object.keys(this.descriptor).map((type) => this.attributeInterface(type))\n const writeInterfaces = Object.keys(this.descriptor).flatMap((type) =>\n this.writeAttributeInterfaces(type),\n )\n const linkInterfaces = [...this.declaredLinks].map(([type, links]) =>\n this.linksInterface(type, links),\n )\n // Action input/output aliases reference component schemas; resolve them (this also\n // records any enums they reach) before the enum block is emitted.\n const actionAliases = this.actionTypeAliases()\n const enums = this.enumAliases()\n\n const parts = [\n this.header(),\n this.imports(),\n ...(enums ? [enums] : []),\n ...interfaces,\n ...writeInterfaces,\n ...linkInterfaces,\n ...actionAliases,\n this.attributesMap(),\n this.writeAttributesMap(),\n this.linksMap(),\n this.actionTypesMap(),\n this.resourceMap(),\n 'export type ResourceMap = typeof resourceMap',\n this.atomicConst(),\n this.pageLimitsConst(),\n emitErrorCodes(readErrorCatalogue(this.doc)),\n this.boundFactory(),\n ]\n return `${parts.join('\\n\\n')}\\n`\n }\n\n private header(): string {\n return [\n '/**',\n ' * AUTO-GENERATED by @haddowg/json-api-codegen — do not edit by hand.',\n ' * Regenerate from the source OpenAPI document instead.',\n ' *',\n ...provenanceLines(this.provenance),\n ' */',\n ].join('\\n')\n }\n\n private imports(): string {\n return [\n 'import {',\n ' type ApiDescriptor,',\n ' type ClientOptions,',\n ' createClient as createClientRuntime,',\n ' type ErrorCodeGuard,',\n ' hasErrorCode as hasErrorCodeRuntime,',\n ...(this.declaredLinks.size > 0 ? [' type ResourceLinks,'] : []),\n \"} from '@haddowg/json-api-client'\",\n ].join('\\n')\n }\n\n /**\n * The links interface of a type that declares links, e.g. `ImagesLinks`: each declared link an\n * optional member, since the server leaves a link out when its href resolves to `null`. It\n * extends the loose `ResourceLinks`, so `self` and any link the type doesn't declare stay\n * reachable as before.\n */\n private linksInterface(type: string, links: readonly DeclaredLink[]): string {\n const lines: string[] = []\n for (const link of links) {\n const doc = jsDoc(memberDoc(link.schema), ' ')\n if (doc !== undefined) {\n lines.push(doc)\n }\n const value = link.kind === 'bare' ? 'string' : this.linkObjectType(link.schema, ' ')\n lines.push(` ${propertyKey(link.name)}?: ${value}`)\n }\n return `export interface ${typeStem(type)}Links extends ResourceLinks {\\n${lines.join('\\n')}\\n}`\n }\n\n /**\n * A declared link object as a multi-line type: `href`, each static member as its `const`, and a\n * `meta` object whose members are typed as attributes are, each with its own TSDoc.\n */\n private linkObjectType(schema: SchemaObject, indent: string): string {\n return this.documentedObject(schema, indent, (name, member) =>\n name === 'meta'\n ? this.documentedObject(member, `${indent} `, (_, field) => this.tsType(field))\n : this.constOrType(member),\n )\n }\n\n /** An object type with one line, and its TSDoc, per property. */\n private documentedObject(\n schema: SchemaObject,\n indent: string,\n type: (name: string, member: SchemaObject) => string,\n ): string {\n const required = new Set(schema.required ?? [])\n const inner = `${indent} `\n const lines: string[] = []\n for (const [name, member] of Object.entries(schema.properties ?? {})) {\n if (!isSchema(member)) {\n continue\n }\n const doc = jsDoc(memberDoc(member), inner)\n if (doc !== undefined) {\n lines.push(doc)\n }\n lines.push(\n `${inner}${propertyKey(name)}${required.has(name) ? '' : '?'}: ${type(name, member)}`,\n )\n }\n return lines.length === 0 ? 'Record<string, unknown>' : `{\\n${lines.join('\\n')}\\n${indent}}`\n }\n\n /** A static link member's `const` as a literal type, else its schema's type. */\n private constOrType(schema: SchemaObject): string {\n const value = schema['const']\n return typeof value === 'string' ? stringLiteral(value) : this.tsType(schema)\n }\n\n /** Per-type attribute interface, e.g. `export interface AlbumsAttributes { ... }`. */\n private attributeInterface(type: string): string {\n const base = this.baseByType.get(type)\n const props = base ? this.schemas[`${base}Attributes`]?.properties : undefined\n // Drive field order off the (sorted) descriptor so output stays deterministic; read\n // attributes are always present (every member required, no optional marker).\n const fields = Object.keys(this.descriptor[type]!.attributes)\n return this.renderInterface(`${typeStem(type)}Attributes`, props, fields, () => true)\n }\n\n /**\n * The per-type WRITE attribute interfaces — `<Pascal>CreateAttributes` and\n * `<Pascal>UpdateAttributes` — from the `<Base>CreateAttributes`/`<Base>UpdateAttributes`\n * components (readOnly fields are already excluded vs the read attributes by the bundle).\n * Create marks a field required iff it sits in the component's `required`; Update makes\n * every field optional. A read-only type (no create/update component) contributes nothing.\n */\n private writeAttributeInterfaces(type: string): string[] {\n const base = this.baseByType.get(type)\n if (base === undefined) {\n return []\n }\n const pascal = typeStem(type)\n const out: string[] = []\n\n const create = this.schemas[`${base}CreateAttributes`]\n if (create !== undefined) {\n const required = new Set(create.required ?? [])\n // Sort the schema's own property keys (no descriptor to order write fields).\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created key array\n const fields = Object.keys(create.properties ?? {}).sort()\n out.push(\n this.renderInterface(`${pascal}CreateAttributes`, create.properties, fields, (field) =>\n required.has(field),\n ),\n )\n }\n\n const update = this.schemas[`${base}UpdateAttributes`]\n if (update !== undefined) {\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created key array\n const fields = Object.keys(update.properties ?? {}).sort()\n out.push(\n this.renderInterface(`${pascal}UpdateAttributes`, update.properties, fields, () => false),\n )\n }\n\n return out\n }\n\n /**\n * Per-action input/output type aliases for every type that declares custom actions. An\n * action whose `input`/`output` resolves to a component schema gets a named alias\n * (`<Pascal><Action>Input` / `<Pascal><Action>Output`) expanding that component via the\n * shared {@link tsType} machinery — a `none` input/output (no body / a `204`) contributes\n * no alias. Deterministic order: types, then action names (the descriptor is sorted).\n */\n private actionTypeAliases(): string[] {\n const out: string[] = []\n for (const type of Object.keys(this.descriptor)) {\n const actions = this.descriptor[type]?.actions\n if (actions === undefined) {\n continue\n }\n const pascal = typeStem(type)\n for (const [actionName, action] of Object.entries(actions)) {\n const member = `${pascal}${pascalCase(actionName)}`\n const names: ActionAliasNames = {}\n const inputType = this.actionBodyType(action, 'input')\n if (inputType !== undefined) {\n out.push(`export type ${member}Input = ${inputType}`)\n names.input = `${member}Input`\n }\n const outputType = this.actionBodyType(action, 'output')\n if (outputType !== undefined) {\n out.push(`export type ${member}Output = ${outputType}`)\n names.output = `${member}Output`\n }\n const op = actionOperation(this.doc, action)\n for (const { mediaType, kind } of action.rawOutput ?? []) {\n if (kind === 'json') {\n const schema = firstSuccessSchema(op, mediaType)\n names.responses ??= new Map()\n names.responses.set(\n mediaType,\n this.rawBodyAlias(schema, `${member}${pascalCase(mediaType)}Output`, out),\n )\n }\n }\n const single = action.input === 'raw' && action.inputMedia === undefined\n const singleKind = !single\n ? undefined\n : action.contentType?.startsWith('multipart/') === true\n ? 'multipart'\n : action.contentType === 'application/x-www-form-urlencoded'\n ? 'form'\n : undefined\n const listed =\n action.inputMedia ??\n (singleKind === undefined || action.contentType === undefined\n ? []\n : [{ mediaType: action.contentType, kind: singleKind }])\n for (const { mediaType, kind } of listed) {\n const schema = op?.requestBody?.content?.[mediaType]?.schema\n if (kind === 'json') {\n names.requests ??= new Map()\n names.requests.set(\n mediaType,\n this.rawBodyAlias(schema, `${member}${pascalCase(mediaType)}Input`, out),\n )\n } else if (kind === 'multipart' || kind === 'form') {\n const fields = this.formFieldsType(schema, kind)\n if (fields !== undefined) {\n const alias = `${member}${pascalCase(mediaType)}Input`\n const doc = schema === undefined ? undefined : jsDoc(schema.description, '')\n const declaration = `export type ${alias} = ${fields}`\n out.push(doc === undefined ? declaration : `${doc}\\n${declaration}`)\n names.requests ??= new Map()\n names.requests.set(mediaType, alias)\n }\n }\n }\n if (\n names.input !== undefined ||\n names.output !== undefined ||\n names.responses !== undefined ||\n names.requests !== undefined\n ) {\n let byAction = this.actionAliasNames.get(type)\n if (byAction === undefined) {\n byAction = new Map()\n this.actionAliasNames.set(type, byAction)\n }\n byAction.set(actionName, names)\n }\n }\n }\n return out\n }\n\n /**\n * The alias a JSON-like raw body is typed by. A `$ref` to a component is emitted once under the\n * component's own name when that name is free; anything else gets `fallback`. The alias source\n * is pushed onto `out` the first time.\n */\n private rawBodyAlias(schema: SchemaObject | undefined, fallback: string, out: string[]): string {\n const target = typeof schema?.$ref === 'string' ? refName(schema.$ref) : undefined\n const resolved = target === undefined ? undefined : this.schemas[target]\n if (target !== undefined && resolved !== undefined) {\n const known = this.rawBodyAliases.get(target)\n if (known !== undefined) {\n return known\n }\n if (isTypeName(target) && !this.takenNames.has(target) && !Array.isArray(resolved.enum)) {\n this.takenNames.add(target)\n this.rawBodyAliases.set(target, target)\n out.push(this.rawBodyDeclaration(target, resolved))\n this.emittedInterfaces.add(target)\n return target\n }\n }\n out.push(this.rawBodyDeclaration(fallback, schema))\n return fallback\n }\n\n /**\n * The typed fields of a multipart or URL-encoded request body whose object schema lists\n * `properties`, which the client encodes into a `FormData` or `URLSearchParams`. `undefined`\n * when the schema lists none, so the body stays a raw `FormData` or `URLSearchParams`.\n */\n private formFieldsType(\n schema: SchemaObject | undefined,\n kind: 'multipart' | 'form',\n ): string | undefined {\n let target = schema\n if (typeof target?.$ref === 'string') {\n target = this.schemas[refName(target.$ref) ?? '']\n }\n const props = target?.properties\n if (target === undefined || props === undefined) {\n return undefined\n }\n const required = new Set(target.required ?? [])\n const members: string[] = []\n const valueTypes: string[] = []\n for (const [name, prop] of Object.entries(props)) {\n if (!isSchema(prop)) {\n continue\n }\n const type = this.formFieldType(prop, kind)\n valueTypes.push(type)\n members.push(`${propertyKey(name)}${required.has(name) ? '' : '?'}: ${type}`)\n }\n if (members.length === 0) {\n return undefined\n }\n const extra = target['additionalProperties']\n if (extra === true || isSchema(extra as SchemaOrBool | undefined)) {\n // An index signature must admit every declared member's type too.\n const additional = isSchema(extra as SchemaOrBool | undefined)\n ? this.formFieldType(extra as SchemaObject, kind)\n : this.formFieldType({}, kind)\n const all = [...new Set([...valueTypes, additional].flatMap((type) => type.split(' | ')))]\n members.push(`[field: string]: ${all.join(' | ')} | undefined`)\n }\n return `{ ${members.join('; ')} }`\n }\n\n /**\n * One form field's type: `Blob | File` for a binary part of a multipart body, an array of\n * its item type for an array, else the scalar's own type. A field with no usable type takes\n * any scalar a form can carry.\n */\n private formFieldType(schema: SchemaObject, kind: 'multipart' | 'form'): string {\n const any =\n kind === 'multipart' ? 'string | number | boolean | Blob' : 'string | number | boolean'\n let target = schema\n if (typeof target.$ref === 'string') {\n const resolved = this.schemas[refName(target.$ref) ?? '']\n if (resolved !== undefined && !Array.isArray(resolved.enum)) {\n target = resolved\n }\n }\n if (kind === 'multipart' && target.format === 'binary') {\n return 'Blob | File'\n }\n if (target.type === 'array') {\n const item = target.items === undefined ? any : this.formFieldType(target.items, kind)\n return item.includes(' ') ? `(${item})[]` : `${item}[]`\n }\n const type = this.tsType(target)\n return type === 'unknown' || type.includes('{') || type.startsWith('Record<') ? any : type\n }\n\n /** `export type Name = …` for a raw body schema, with its description as JSDoc. */\n private rawBodyDeclaration(name: string, schema: SchemaObject | undefined): string {\n const type = schema === undefined ? 'unknown' : this.tsType(schema)\n const doc = schema === undefined ? undefined : jsDoc(schema.description, '')\n const declaration = `export type ${name} = ${type}`\n return doc === undefined ? declaration : `${doc}\\n${declaration}`\n }\n\n /**\n * Emit the `ActionTypes` interface wiring the emitted per-action aliases onto the typed\n * action surface — `type -> actionName -> { input?; output? }`, the client's fourth type\n * argument. So `client.albums.id(id).actions.reissue(body)` takes `AlbumsReissueInput` and\n * resolves `AlbumsReissueOutput` rather than a loose `Record<string,unknown>` / `unknown`.\n * Only actions whose alias was emitted appear (a `none`-input/output action contributes the\n * absent side, which the runtime types fall back to loosely). Emits `{}` when none exist.\n */\n private actionTypesMap(): string {\n const typeLines: string[] = []\n for (const type of Object.keys(this.descriptor)) {\n const byAction = this.actionAliasNames.get(type)\n if (byAction === undefined || byAction.size === 0) {\n continue\n }\n const actionLines: string[] = []\n for (const [actionName, names] of byAction) {\n const members: string[] = []\n if (names.input !== undefined) {\n members.push(`input: ${names.input}`)\n }\n if (names.output !== undefined) {\n members.push(`output: ${names.output}`)\n }\n if (names.responses !== undefined) {\n members.push(`responses: ${mediaMap(names.responses)}`)\n }\n if (names.requests !== undefined) {\n members.push(`requests: ${mediaMap(names.requests)}`)\n }\n actionLines.push(` ${propertyKey(actionName)}: { ${members.join('; ')} }`)\n }\n typeLines.push(` ${propertyKey(type)}: {\\n${actionLines.join('\\n')}\\n }`)\n }\n if (typeLines.length === 0) {\n return 'export interface ActionTypes {}'\n }\n return `export interface ActionTypes {\\n${typeLines.join('\\n')}\\n}`\n }\n\n /**\n * The TS type alias (if any) for an action's request body.\n *\n * An action's RESULT and its FLAT input are derived at the type level from the descriptor\n * (`outputType`/`outputCardinality` → the materialised resource view; `inputType` → the\n * `CreateInput` of that type), so no `output` alias is emitted and a `document` input whose\n * resource type resolves emits no `input` alias either. Only a bespoke command document (a\n * `document` input with no resolvable `inputType`) keeps a raw-envelope alias as its typed body,\n * expanded via {@link tsType} (falling back to a loose JSON:API document shape).\n */\n private actionBodyType(action: ActionDescriptor, side: 'input' | 'output'): string | undefined {\n if (side === 'output' || action.input !== 'document' || action.inputType !== undefined) {\n return undefined\n }\n const op = this.doc.paths?.[action.path]?.post\n const ref = op?.requestBody?.content?.[JSON_API_MEDIA_TYPE]?.schema?.$ref\n if (typeof ref !== 'string') {\n return LOOSE_DOCUMENT\n }\n const target = refName(ref)\n const resolved = target ? this.schemas[target] : undefined\n return resolved ? this.tsType(resolved) : LOOSE_DOCUMENT\n }\n\n /** Emit the server-level atomic capability constant (`{ path }` or `null`). */\n private atomicConst(): string {\n const atomicScopes = scopeDoc(this.atomic?.scopes)\n const doc = [\n '/**',\n ' * The server-level Atomic Operations endpoint (the atomic ext media type), or `null`',\n ' * when this server exposes none. The runtime `client.atomic` builder posts the batch here.',\n ...(atomicScopes === undefined ? [] : [' *', ` * ${atomicScopes}`]),\n ' */',\n ].join('\\n')\n const value = this.atomic === null ? 'null' : `${this.literal(this.atomic, 0)} as const`\n return `${doc}\\nexport const atomic = ${value}`\n }\n\n /**\n * The `pageLimits` const: per collection, the `default`, `minimum` and `maximum` each `page`\n * member declares (generator contract 5 adds the paginator's default and page-size cap). A\n * menu nests them under each arm's `kind`. Members declaring none, and collections with no\n * such member, are left out. The client never clamps a `page` argument to these.\n */\n private pageLimitsConst(): string {\n const typeLines: string[] = []\n for (const type of Object.keys(this.descriptor)) {\n const path = this.descriptor[type]!.paths['fetchMany']\n const page = path === undefined ? undefined : this.doc.paths?.[path]?.get?.parameters\n const schema = page?.find((param) => param.name === 'page')?.schema\n if (schema === undefined) {\n continue\n }\n let body: string[] = []\n if (schema.oneOf !== undefined) {\n for (const arm of schema.oneOf) {\n const kind = isSchema(arm.properties?.['kind']) ? arm.properties['kind'].const : undefined\n const members = this.pageMemberLimits(arm, ' ')\n if (typeof kind === 'string' && members.length > 0) {\n body.push(` ${propertyKey(kind)}: {\\n${members.join('\\n')}\\n },`)\n }\n }\n } else {\n body = this.pageMemberLimits(schema, ' ')\n }\n if (body.length > 0) {\n typeLines.push(` ${propertyKey(type)}: {\\n${body.join('\\n')}\\n },`)\n }\n }\n const doc = [\n '/**',\n \" * The bounds each collection's `page` parameter declares, keyed by type, then by strategy for a\",\n ' * collection offering several, then by wire key. `default` is what the server uses when the key',\n ' * is absent and `maximum` is the largest value it serves. The client sends the `page` you pass',\n ' * unchanged, so read these to bound a page-size picker.',\n ' */',\n ].join('\\n')\n const body = typeLines.length === 0 ? '{}' : `{\\n${typeLines.join('\\n')}\\n}`\n return `${doc}\\nexport const pageLimits = ${body} as const`\n }\n\n /** One page schema's members that declare a `default`, `minimum` or `maximum`, as literal lines. */\n private pageMemberLimits(schema: SchemaObject, indent: string): string[] {\n const lines: string[] = []\n for (const [name, prop] of Object.entries(schema.properties ?? {})) {\n if (!isSchema(prop) || name === 'kind') {\n continue\n }\n const limits: string[] = []\n for (const keyword of ['default', 'minimum', 'maximum'] as const) {\n if (typeof prop[keyword] === 'number') {\n limits.push(`${keyword}: ${String(prop[keyword])}`)\n }\n }\n if (limits.length === 0) {\n continue\n }\n const doc = jsDoc(memberDoc(prop), indent)\n if (doc !== undefined) {\n lines.push(doc)\n }\n lines.push(`${indent}${propertyKey(name)}: { ${limits.join(', ')} },`)\n }\n return lines\n }\n\n /**\n * Render an attribute interface from a property map, a field order, and a `required`\n * predicate (true => no `?`). Shared by the read and write attribute interfaces so the\n * tsType/JSDoc logic stays in one place.\n */\n private renderInterface(\n name: string,\n props: Record<string, SchemaOrBool> | undefined,\n fields: readonly string[],\n required: (field: string) => boolean,\n ): string {\n const lines: string[] = []\n for (const field of fields) {\n const schema = props?.[field]\n const tsType = isSchema(schema) ? this.tsType(schema) : 'unknown'\n const doc = isSchema(schema) ? jsDoc(memberDoc(schema), ' ') : undefined\n if (doc) {\n lines.push(doc)\n }\n const optional = required(field) ? '' : '?'\n lines.push(` ${propertyKey(field)}${optional}: ${tsType}`)\n }\n\n this.emittedInterfaces.add(name)\n if (lines.length === 0) {\n return `export interface ${name} {}`\n }\n return `export interface ${name} {\\n${lines.join('\\n')}\\n}`\n }\n\n /** Map a JSON Schema attribute node to a precise TypeScript type. */\n private tsType(schema: SchemaObject): string {\n // A reference: an enum -> its emitted union alias; an emitted attribute interface ->\n // its interface name (so an action envelope nests precise attribute types); else\n // structural expansion of the referenced component, falling back to unknown. A\n // `expanding` guard breaks any cyclic/self-referential component chain.\n if (typeof schema.$ref === 'string') {\n const target = refName(schema.$ref)\n const resolved = target ? this.schemas[target] : undefined\n if (target && resolved && Array.isArray(resolved.enum)) {\n this.usedEnums.set(target, resolved)\n return this.enumName(target)\n }\n if (target && this.emittedInterfaces.has(target)) {\n return target\n }\n if (resolved === undefined || target === undefined || this.expanding.has(target)) {\n return 'unknown'\n }\n this.expanding.add(target)\n const expanded = this.tsType(resolved)\n this.expanding.delete(target)\n return expanded\n }\n\n // A union of branches, as `anyOf: [{ $ref: Enum }, { type: 'null' }]` for a nullable enum.\n const branches = schema.anyOf ?? schema.oneOf\n if (schema.type === undefined && branches !== undefined && branches.length > 0) {\n const members = branches.map((branch) => this.tsType(branch))\n const nullable = members.includes('null')\n const rest = [...new Set(members.filter((member) => member !== 'null'))]\n if (rest.length === 0) {\n return 'null'\n }\n return nullable ? `${rest.join(' | ')} | null` : rest.join(' | ')\n }\n\n const types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : []\n if (types.length === 1 && types[0] === 'null') {\n return 'null'\n }\n const nullable = types.includes('null')\n const base = this.baseTsType(\n schema,\n types.filter((t) => t !== 'null'),\n )\n return nullable ? `${base} | null` : base\n }\n\n /** The non-nullable TS type for the declared JSON type(s). */\n private baseTsType(schema: SchemaObject, types: readonly string[]): string {\n // An inline enum (string literals without a $ref).\n if (Array.isArray(schema.enum) && schema.enum.length > 0) {\n return schema.enum.map((value) => stringLiteral(String(value))).join(' | ')\n }\n if (types.length === 0) {\n return 'unknown'\n }\n const mapped = types.map((t) => this.scalarOrComposite(schema, t))\n // De-dupe while preserving order.\n return [...new Set(mapped)].join(' | ')\n }\n\n private scalarOrComposite(schema: SchemaObject, type: string): string {\n switch (type) {\n case 'string': {\n return 'string'\n }\n case 'number':\n case 'integer': {\n return 'number'\n }\n case 'boolean': {\n return 'boolean'\n }\n case 'object': {\n return this.objectType(schema)\n }\n case 'array': {\n return this.arrayType(schema)\n }\n default: {\n return 'unknown'\n }\n }\n }\n\n /** A nested object type from its `properties` (falls back to an index signature). */\n private objectType(schema: SchemaObject): string {\n const props = schema.properties\n if (props === undefined) {\n return 'Record<string, unknown>'\n }\n const required = new Set(schema.required ?? [])\n const members: string[] = []\n for (const [name, prop] of Object.entries(props)) {\n if (!isSchema(prop)) {\n continue\n }\n const optional = required.has(name) ? '' : '?'\n members.push(`${propertyKey(name)}${optional}: ${this.tsType(prop)}`)\n }\n if (members.length === 0) {\n return 'Record<string, unknown>'\n }\n return `{ ${members.join('; ')} }`\n }\n\n private arrayType(schema: SchemaObject): string {\n const items = schema.items\n const element = isSchema(items) ? this.tsType(items) : 'unknown'\n // Wrap unions so `(A | B)[]` reads correctly.\n const list = /[|&]/.test(element) ? `(${element})[]` : `${element}[]`\n // `minItems` of 1 or more: the server never sends, or accepts, an empty list.\n const minItems = schema['minItems']\n return typeof minItems === 'number' && minItems >= 1 ? `[${element}, ...${list}]` : list\n }\n\n /** Union aliases for every enum component an attribute referenced, sorted by name. */\n private enumAliases(): string | undefined {\n if (this.usedEnums.size === 0) {\n return undefined\n }\n // oxlint-disable-next-line no-array-sort -- sorting a freshly-created key array\n const names = [...this.usedEnums.keys()].sort()\n return names\n .map((name) => {\n const schema = this.usedEnums.get(name)!\n const values = schema.enum ?? []\n const union = values.map((value) => stringLiteral(String(value))).join(' | ')\n const alias = `export type ${this.enumName(name)} = ${union}`\n const doc = jsDoc(this.enumDoc(schema), '')\n return doc ? `${doc}\\n${alias}` : alias\n })\n .join('\\n\\n')\n }\n\n /**\n * Documentation for an enum alias: a per-value list built from `x-enum-descriptions`\n * (the richest hover DX, since a union alias can't carry per-member JSDoc), falling\n * back to the component's own `description`.\n */\n private enumDoc(schema: SchemaObject): string | undefined {\n const values = schema.enum ?? []\n const descriptions = schema['x-enum-descriptions']\n if (Array.isArray(descriptions) && descriptions.length === values.length && values.length > 0) {\n return values\n .map((value, i) => `- \\`${String(value)}\\` — ${String(descriptions[i])}`)\n .join('\\n')\n }\n return schema.description\n }\n\n /**\n * Emit the `Attributes` interface mapping each wire type to its per-type attribute\n * interface. The runtime descriptor only carries coarse format hints; this is how the\n * precise per-type attribute types reach the bound client (passed as the second type\n * argument to the runtime factory).\n */\n private attributesMap(): string {\n const lines = Object.keys(this.descriptor).map(\n (type) => ` ${propertyKey(type)}: ${typeStem(type)}Attributes`,\n )\n return `export interface Attributes {\\n${lines.join('\\n')}\\n}`\n }\n\n /**\n * Emit the `Links` interface mapping each type that declares links to its links interface. The\n * runtime threads it beside the `Attributes` map, so a read result's `$links` carries the\n * declared links. A type absent from it keeps the loose `ResourceLinks`. Passed as the sixth\n * type argument to the runtime factory.\n */\n private linksMap(): string {\n const lines = [...this.declaredLinks.keys()].map(\n (type) => ` ${propertyKey(type)}: ${typeStem(type)}Links`,\n )\n if (lines.length === 0) {\n return 'export interface Links {}'\n }\n return `export interface Links {\\n${lines.join('\\n')}\\n}`\n }\n\n /**\n * Emit the `WriteAttributes` interface mapping each writable wire type to its\n * `{ create; update }` attribute pair. A read-only type (no create/update component)\n * contributes no entry, so the bound client only exposes writes where the API allows\n * them. Passed as the third type argument to the runtime factory.\n */\n private writeAttributesMap(): string {\n const lines: string[] = []\n for (const type of Object.keys(this.descriptor)) {\n const base = this.baseByType.get(type)\n const hasCreate = base !== undefined && this.schemas[`${base}CreateAttributes`] !== undefined\n const hasUpdate = base !== undefined && this.schemas[`${base}UpdateAttributes`] !== undefined\n if (!hasCreate && !hasUpdate) {\n continue\n }\n const pascal = typeStem(type)\n const members: string[] = []\n if (hasCreate) {\n members.push(`create: ${pascal}CreateAttributes`)\n }\n if (hasUpdate) {\n members.push(`update: ${pascal}UpdateAttributes`)\n }\n lines.push(` ${propertyKey(type)}: { ${members.join('; ')} }`)\n }\n if (lines.length === 0) {\n return 'export interface WriteAttributes {}'\n }\n return `export interface WriteAttributes {\\n${lines.join('\\n')}\\n}`\n }\n\n /** Emit the descriptor as a literal `as const satisfies ApiDescriptor`. */\n private resourceMap(): string {\n const body = this.literal(this.descriptor as Record<string, unknown>, 0, '')\n return `export const resourceMap = ${body} as const satisfies ApiDescriptor`\n }\n\n /** Render a JSON-serialisable descriptor value as deterministic TS object-literal source. */\n private literal(value: unknown, depth: number, path?: string): string {\n const indent = ' '.repeat(depth)\n const inner = ' '.repeat(depth + 1)\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return '[]'\n }\n const items = value.map((item) => `${inner}${this.literal(item, depth + 1)}`)\n return `[\\n${items.join(',\\n')}\\n${indent}]`\n }\n\n if (value !== null && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n if (entries.length === 0) {\n return '{}'\n }\n const lines = entries.map(([key, v]) => {\n const childPath = path === undefined ? undefined : path === '' ? key : `${path}/${key}`\n const line = `${inner}${propertyKey(key)}: ${this.literal(v, depth + 1, childPath)}`\n const doc = childPath === undefined ? undefined : this.literalDocs.get(childPath)\n return doc === undefined ? line : `${jsDoc(doc, inner)}\\n${line}`\n })\n return `{\\n${lines.join(',\\n')}\\n${indent}}`\n }\n\n return typeof value === 'string' ? stringLiteral(value) : JSON.stringify(value)\n }\n\n private boundFactory(): string {\n return [\n '/**',\n ' * Descriptor-bound client factory; wraps the generic runtime with this API’s `resourceMap`.',\n ' * The server-level `atomic` capability is threaded in by default so `client.atomic` is wired',\n ' * (a caller may still override it via `options.atomic`). The client type carries `ErrorCode`,',\n ' * so bindings that only see the client (the Angular refs) type its errors.',\n ' */',\n 'export const createClient = (options: ClientOptions) =>',\n ' createClientRuntime<typeof resourceMap, Attributes, WriteAttributes, ActionTypes, ErrorCode, Links>(',\n ' resourceMap,',\n ' {',\n ' atomic,',\n ' ...options,',\n ' },',\n ' )',\n ].join('\\n')\n }\n}\n\n/**\n * Generate the full source of the client module for a document + its built descriptor.\n * The server-level atomic capability is derived from the document (override via `atomic`).\n */\nexport function emit(\n doc: OpenApiDocument,\n descriptor: ApiDescriptor,\n atomic: AtomicDescriptor | null = buildAtomic(doc),\n): string {\n return new Emitter(doc, descriptor, atomic).emit()\n}\n\n/** Re-export so callers can reference the resource descriptor shape if needed. */\nexport type { ResourceDescriptor }\n","import type { ApiExamples } from '@haddowg/json-api-client'\nimport type { OpenApiDocument } from './openapi'\nimport { deriveProvenance, provenanceLines } from './provenance'\nimport { jsonLiteral } from './source'\n\n/**\n * Emit the operation examples as a standalone generated artifact:\n *\n * ```ts\n * export const examples: ApiExamples = { <type>: { operations: { … }, actions: { … } }, … }\n * ```\n *\n * It sits beside the client rather than in it because the examples outweigh the rest of the\n * client several times over and only a few consumers, such as a tool describing each operation,\n * read them. The const is annotated rather than `as const`, so a large document costs the type\n * checker nothing beyond the assignability check.\n */\nexport function emitExamples(doc: OpenApiDocument, examples: ApiExamples): string {\n const header = [\n '/**',\n ' * AUTO-GENERATED by @haddowg/json-api-codegen — do not edit by hand.',\n ' * Worked examples of each operation, as the source OpenAPI document declares them.',\n ' *',\n ...provenanceLines(deriveProvenance(doc)),\n ' */',\n ].join('\\n')\n return `${[\n header,\n \"import type { ApiExamples } from '@haddowg/json-api-client'\",\n `export const examples: ApiExamples = ${jsonLiteral(examples)}`,\n ].join('\\n\\n')}\\n`\n}\n","import { hashJson } from './provenance'\nimport type { SchemaBundle } from './reader'\nimport { jsonLiteral } from './source'\n\n/**\n * Emit the per-type JSON Schema map as a standalone generated artifact:\n *\n * ```ts\n * export const schemas = { <type>: { …json schema… }, … } as const\n * ```\n *\n * The values are the raw, self-contained resource-object JSON Schema documents the bundle\n * serves at `GET /schemas.json` — suitable to hand straight to a validation engine via the\n * opt-in `validate?` seam (ADR 0004). This is a separate file from the client so the main\n * descriptor/client output is unaffected when `--schemas` is absent.\n *\n * The schemas are emitted as JSON (deterministic, key order preserved) so the artifact is\n * stable to diff; `as const` keeps the literal shapes narrow.\n */\nexport function emitSchemas(bundle: SchemaBundle): string {\n return `${[header(bundle), body(bundle)].join('\\n\\n')}\\n`\n}\n\nfunction header(bundle: SchemaBundle): string {\n return [\n '/**',\n ' * AUTO-GENERATED by @haddowg/json-api-codegen — do not edit by hand.',\n ' * Per-type JSON Schemas for the opt-in validation seam; regenerate from the source bundle.',\n ' *',\n ` * Schema hash: ${hashJson(bundle)}`,\n ' */',\n ].join('\\n')\n}\n\nfunction body(bundle: SchemaBundle): string {\n // The raw schema objects are valid TS object literals; JSON keeps the bundle's key order.\n return `export const schemas = ${jsonLiteral(bundle)} as const`\n}\n","import { readFile } from 'node:fs/promises'\nimport { parse as parseYaml } from 'yaml'\nimport type { OpenApiDocument } from './openapi'\nimport type { SchemaObject } from './openapi'\n\n/** A self-contained JSON Schema document, keyed by JSON:API type, as served at `GET /schemas.json`. */\nexport type SchemaBundle = Record<string, SchemaObject>\n\n/** True when the input looks like an http(s) URL rather than a local path. */\nfunction isHttpUrl(input: string): boolean {\n return /^https?:\\/\\//i.test(input)\n}\n\n/** Decide YAML vs JSON by extension first, then by a cheap content sniff. */\nfunction looksLikeYaml(source: string, text: string): boolean {\n if (/\\.ya?ml$/i.test(source)) {\n return true\n }\n if (/\\.json$/i.test(source)) {\n return false\n }\n // No decisive extension: JSON documents start with `{`/`[` once trimmed.\n return !/^\\s*[{[]/.test(text)\n}\n\nfunction parse<T>(source: string, text: string, label: string): T {\n const doc = looksLikeYaml(source, text) ? parseYaml(text) : JSON.parse(text)\n if (doc === null || typeof doc !== 'object') {\n throw new Error(`${label} at ${source} did not parse to an object`)\n }\n return doc as T\n}\n\n/**\n * Fetch (URL) or read (file) `input`, then parse it as JSON or YAML (decided by extension,\n * falling back to a content sniff). Shared by the OpenAPI and JSON Schema readers.\n */\nasync function readSource<T>(input: string, label: string): Promise<T> {\n if (isHttpUrl(input)) {\n const res = await fetch(input)\n if (!res.ok) {\n throw new Error(`Failed to fetch ${label} from ${input}: ${res.status}`)\n }\n return parse<T>(input, await res.text(), label)\n }\n\n return parse<T>(input, await readFile(input, 'utf8'), label)\n}\n\n/**\n * Read an OpenAPI document from an http(s) URL or a local file path. Supports both JSON\n * and YAML (decided by extension, falling back to a content sniff).\n */\nexport async function readDocument(input: string): Promise<OpenApiDocument> {\n return readSource<OpenApiDocument>(input, 'OpenAPI document')\n}\n\n/**\n * Read the bundle's JSON Schema bundle (`GET /schemas.json`) from an http(s) URL or a\n * local file path — a map keyed by JSON:API type, each value a self-contained JSON Schema\n * 2020-12 resource-object document. Supports both JSON and YAML, like {@link readDocument}.\n */\nexport async function readSchemas(input: string): Promise<SchemaBundle> {\n return readSource<SchemaBundle>(input, 'JSON Schema bundle')\n}\n","/**\n * @haddowg/json-api-codegen — reads the bundle's OpenAPI 3.1 document (from a URL or\n * a local file) and emits the runtime descriptor + derived types + a bound\n * `createClient` (ADR 0001). Optionally reads the bundle's JSON Schemas to wire the\n * opt-in validation seam.\n *\n * The spec is fully self-describing for our needs (see CONTEXT.md): type identity is\n * `properties.type.const`; relationships, cardinality and related types come from the\n * relationship components' `data`; allowed `?include` paths are a bounded, pre-expanded\n * enum per endpoint; the create client-id policy is encoded in the create request\n * schema (`id: false` / required / optional).\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { buildDescriptor } from './build-descriptor'\nimport { buildExamples } from './build-examples'\nimport { checkContract } from './contract'\nimport { detectVerbCollisions, emit } from './emit'\nimport { emitExamples } from './emit-examples'\nimport { emitSchemas } from './emit-schemas'\nimport { readDocument, readSchemas } from './reader'\n\nexport { buildAtomic, buildDescriptor, DescriptorBuilder } from './build-descriptor'\nexport { buildExamples, operationExamples } from './build-examples'\nexport { checkContract, MAXIMUM_CONTRACT, MINIMUM_CONTRACT } from './contract'\nexport { detectVerbCollisions, emit, Emitter } from './emit'\nexport { emitErrorCodes, readErrorCatalogue } from './error-codes'\nexport type { DocumentedErrorCode, ErrorCatalogue } from './error-codes'\nexport type { VerbCollision } from './emit'\nexport { emitExamples } from './emit-examples'\nexport { emitSchemas } from './emit-schemas'\nexport type * from './openapi'\nexport { deriveProvenance, hashJson, provenanceLines } from './provenance'\nexport type { Provenance } from './provenance'\nexport { readDocument, readSchemas } from './reader'\nexport type { SchemaBundle } from './reader'\n\nexport interface CodegenConfig {\n /** OpenAPI document source: an http(s) URL or a local file path. */\n input: string\n /** Output file (or directory) for the generated client. */\n output: string\n /** Server name to target (the spec is per-server). Defaults to the default server. */\n server?: string\n /** JSON Schema source for the validation seam (URL or path). Off when omitted. */\n schemas?: string\n /**\n * Also write the operation examples the document declares (generator contract 12) to a sibling\n * module, `<output>.examples.gen.ts`. Nothing is written when the document has none.\n */\n examples?: boolean\n /**\n * Drift-check mode: regenerate in-memory and compare against the committed `output`\n * (and its schema artifact when `schemas` is set) instead of writing. Nothing is\n * written; {@link check} reports whether the committed artifacts are up to date.\n */\n check?: boolean\n}\n\n/** One artifact's drift status: the file it stands for, and whether it is up to date. */\nexport interface ArtifactDrift {\n /** The committed artifact path (the client output, or its schema sibling). */\n path: string\n /** True when the committed file matches the freshly generated content. */\n upToDate: boolean\n}\n\n/** The outcome of a {@link check} run: `ok` iff every checked artifact is up to date. */\nexport interface CheckResult {\n ok: boolean\n artifacts: ArtifactDrift[]\n}\n\n/**\n * The schema-artifact path beside a client output path: `client.gen.ts` -> `client.schemas.gen.ts`\n * (any `.gen.ts`/`.ts` suffix is preserved; a suffix-less path just gains `.schemas`).\n */\nexport function schemasOutputPath(output: string): string {\n if (output.endsWith('.gen.ts')) {\n return `${output.slice(0, -'.gen.ts'.length)}.schemas.gen.ts`\n }\n if (output.endsWith('.ts')) {\n return `${output.slice(0, -'.ts'.length)}.schemas.ts`\n }\n return `${output}.schemas`\n}\n\n/** The examples-artifact path beside a client output path, named as {@link schemasOutputPath} names its. */\nexport function examplesOutputPath(output: string): string {\n if (output.endsWith('.gen.ts')) {\n return `${output.slice(0, -'.gen.ts'.length)}.examples.gen.ts`\n }\n if (output.endsWith('.ts')) {\n return `${output.slice(0, -'.ts'.length)}.examples.ts`\n }\n return `${output}.examples`\n}\n\n/** One rendered artifact: its target path and the freshly generated content. */\ninterface RenderedArtifact {\n path: string\n content: string\n}\n\n/**\n * Read the source spec(s), build the descriptor and render every generated artifact in\n * memory (the client source first, then the schema artifact when `config.schemas` is set and\n * the examples artifact when `config.examples` is)\n * — the shared core of {@link generate} (which writes them) and {@link check} (which\n * compares them). Verb-collision warnings are emitted here so both paths surface them.\n */\nasync function render(config: CodegenConfig): Promise<RenderedArtifact[]> {\n const doc = await readDocument(config.input)\n const contractWarning = checkContract(doc)\n if (contractWarning !== undefined) {\n console.warn(`[json-api-codegen] ${contractWarning}`)\n }\n const descriptor = buildDescriptor(doc)\n\n for (const { type, relation } of detectVerbCollisions(descriptor)) {\n console.warn(\n `[json-api-codegen] \"${type}\" has a relation named \"${relation}\" which collides with a ` +\n 'reserved verb on the resource handle; it will be reachable via .rel(\"' +\n `${relation}\") in the fluent client.`,\n )\n }\n\n if (Object.keys(descriptor).length === 0) {\n console.warn(\n `[json-api-codegen] found no JSON:API resource types in ${config.input}; the generated client is empty.`,\n )\n }\n\n const artifacts: RenderedArtifact[] = [{ path: config.output, content: emit(doc, descriptor) }]\n\n if (config.schemas !== undefined) {\n const bundle = await readSchemas(config.schemas)\n artifacts.push({ path: schemasOutputPath(config.output), content: emitSchemas(bundle) })\n }\n\n if (config.examples === true) {\n const examples = buildExamples(doc, descriptor)\n if (Object.keys(examples).length > 0) {\n artifacts.push({\n path: examplesOutputPath(config.output),\n content: emitExamples(doc, examples),\n })\n } else {\n console.warn(\n `[json-api-codegen] ${config.input} declares no operation examples; no examples module was written.`,\n )\n }\n }\n\n return artifacts\n}\n\n/**\n * Read the OpenAPI document, build the runtime descriptor, emit the generated client\n * module and write it to `config.output` (creating parent directories as needed).\n *\n * When `config.schemas` is set, also read the bundle's JSON Schema bundle and write a\n * separate per-type schema artifact (`<output>.schemas.gen.ts`) beside the client, wiring\n * the opt-in validation seam (ADR 0004). The main client output is unchanged either way.\n * `config.examples` writes the operation examples the same way (ADR 0011).\n *\n * `config.server` is metadata-only for now: the served document is already per-server,\n * so the caller selects the server by pointing `input` at the right document.\n *\n * Returns the generated client source. When `config.check` is set nothing is written;\n * call {@link check} instead for the drift-gate result.\n */\nexport async function generate(config: CodegenConfig): Promise<string> {\n // The first artifact is always the client source.\n return (await write(config))[0]!.content\n}\n\n/** {@link generate}, returning the path of every artifact written, the client's first. */\nexport async function generateFiles(config: CodegenConfig): Promise<string[]> {\n return (await write(config)).map(({ path }) => path)\n}\n\nasync function write(config: CodegenConfig): Promise<RenderedArtifact[]> {\n const artifacts = await render(config)\n await mkdir(dirname(config.output), { recursive: true })\n for (const { path, content } of artifacts) {\n await writeFile(path, content, 'utf8')\n }\n return artifacts\n}\n\n/**\n * Drift gate: regenerate every artifact in memory and compare it byte-for-byte against the\n * committed file on disk, WITHOUT writing anything. A missing committed file counts as drift\n * (not up to date). Returns per-artifact status plus an aggregate `ok` (true iff all match) —\n * the CI drift check reads `ok` and exits non-zero when it is false.\n */\nexport async function check(config: CodegenConfig): Promise<CheckResult> {\n const artifacts = await render(config)\n const results: ArtifactDrift[] = []\n for (const { path, content } of artifacts) {\n let committed: string | undefined\n try {\n committed = await readFile(path, 'utf8')\n } catch {\n committed = undefined\n }\n results.push({ path, upToDate: committed === content })\n }\n return { ok: results.every((r) => r.upToDate), artifacts: results }\n}\n"],"mappings":"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"}
|