fhir-openapi-translator 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,55 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.1.1] - 2026-09-13
8
+
9
+ Three correctness fixes. Specs generated with 0.1.0 should be regenerated:
10
+ all three produced silently wrong output rather than errors.
11
+
12
+ ### Fixed
13
+
14
+ - **Every schema was missing its `id` property.** The OpenAPI emitter stripped
15
+ the JSON Schema `id`/`$id` keywords everywhere, including inside `properties`
16
+ maps where `id` is an ordinary FHIR element name. 660 of 679 R4 definitions
17
+ declare one, so nearly every generated model lacked its resource id.
18
+ - **Binding enums were absent on R4B and R5.** Enum generation read inline
19
+ enums from the official `fhir.schema.json`, but HL7 stopped inlining them
20
+ after R4 (R4 has 246 occurrences; R4B has 27 and R5 has 26). Required-binding
21
+ codes are now resolved from the vendored definitions on every version, so
22
+ `--no-enums` is once again the only thing that turns them off.
23
+ - **Profiles failed to generate against real IG packages.** A `contentReference`
24
+ written in the absolute canonical form that IG snapshot generators emit
25
+ (`http://hl7.org/fhir/StructureDefinition/Observation#Observation.referenceRange`)
26
+ was parsed as though it were the core `#Observation.referenceRange` short
27
+ form, producing a mangled schema name and aborting generation. US Core Blood
28
+ Pressure, among others, could not be generated at all.
29
+
30
+ ### Documentation
31
+
32
+ - Corrected the `fixed[x]` → `const` claim. Real IGs usually pin values at
33
+ paths _inside_ a datatype or slice (`Observation.category.coding.code`).
34
+ Those datatypes are emitted once as shared schemas and referenced by `$ref`,
35
+ so such constraints cannot be represented and are **not** applied. Only fixed
36
+ values on elements a profile emits as their own property become a `const`.
37
+
38
+ ### Testing
39
+
40
+ - Added `claims.test.ts`: one assertion block per README capability claim,
41
+ across every FHIR version, OpenAPI target and backend it claims to support.
42
+ - Added `fidelity.test.ts`: field-level checks that use the vendored FHIR
43
+ definitions as an oracle instead of hand-written expectations. Covers 45
44
+ resources drawn from the Foundation, Base, Clinical, Financial and
45
+ Specialized modules, in R4/R4B/R5, down to backbone depth — cardinality,
46
+ requiredness, primitive JSON types, choice expansion, `_field` primitive
47
+ extension siblings, and `$ref` resolution.
48
+
49
+ All three bugs above shared a cause: coverage that confirmed expectations at a
50
+ single point of a multi-point matrix. Enums were asserted only on R4, profiles
51
+ only on `us-core-patient`, and `id` never at all.
52
+
53
+ ## [0.1.0] - 2026-09-12
54
+
55
+ Initial release.
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  **Turn any FHIR resource into an OpenAPI spec — and generate typed models in any language.**
4
4
 
5
+ [![npm version](https://img.shields.io/npm/v/fhir-openapi-translator.svg)](https://www.npmjs.com/package/fhir-openapi-translator)
6
+ [![npm downloads](https://img.shields.io/npm/dm/fhir-openapi-translator.svg)](https://www.npmjs.com/package/fhir-openapi-translator)
5
7
  [![CI](https://github.com/krishgok/fhir-openapi-translator/actions/workflows/ci.yml/badge.svg)](https://github.com/krishgok/fhir-openapi-translator/actions/workflows/ci.yml)
6
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
9
  [![Node](https://img.shields.io/badge/node-%E2%89%A520-brightgreen.svg)](https://nodejs.org)
@@ -14,9 +16,12 @@ HAPI FHIR and Firely give Java/.NET teams great FHIR models. Everyone else — G
14
16
  ## Install
15
17
 
16
18
  ```sh
17
- npm install fhir-openapi-translator # library + `fhir-oas` CLI
19
+ npm install -g fhir-openapi-translator # `fhir-oas` on your PATH
20
+ npm install fhir-openapi-translator # or as a library dependency
18
21
  ```
19
22
 
23
+ Or run it without installing: `npx fhir-oas generate Patient --fhir-version r4`
24
+
20
25
  Node.js ≥ 20. FHIR definitions ship with the package — no network, no server.
21
26
 
22
27
  ## Quick start
Binary file
Binary file
Binary file
@@ -326,7 +326,8 @@ function buildElementTree(sd) {
326
326
  return root;
327
327
  }
328
328
  function contentReferenceName(reference, sd, rootName) {
329
- const path3 = reference.replace(/^#/, "");
329
+ const hash = reference.lastIndexOf("#");
330
+ const path3 = hash >= 0 ? reference.slice(hash + 1) : reference;
330
331
  const [root, ...rest] = path3.split(".");
331
332
  if (rest.length === 0) return root ?? path3;
332
333
  const prefix = root === (sd.type ?? sd.name) ? rootName : root ?? "";
@@ -508,8 +509,44 @@ function buildRegistryFromSchemaJson(fhirVersion) {
508
509
  return props?.resourceType !== void 0 && "const" in (props.resourceType ?? {});
509
510
  }).map(([name]) => name);
510
511
  }
512
+ applyBindingEnums(definitions, fhirVersion);
511
513
  return { fhirVersion, definitions, resourceNames };
512
514
  }
515
+ var lowerFirst = (s) => s.charAt(0).toLowerCase() + s.slice(1);
516
+ function elementPathFor(definitionName, property) {
517
+ const [root, ...backbones] = definitionName.split("_");
518
+ return [root, ...backbones.map(lowerFirst), property].join(".");
519
+ }
520
+ function bindingCodeIndex(fhirVersion) {
521
+ const index = /* @__PURE__ */ new Map();
522
+ for (const sd of loadStructureDefinitions(fhirVersion)) {
523
+ for (const el of sd.elements) {
524
+ if (el.binding?.strength === "required" && el.binding.codes?.length) {
525
+ index.set(el.path, el.binding.codes);
526
+ }
527
+ }
528
+ }
529
+ return index;
530
+ }
531
+ function applyBindingEnums(definitions, fhirVersion) {
532
+ const codesByPath = bindingCodeIndex(fhirVersion);
533
+ const isCodeRef = (node) => !!node && node.$ref === "#/definitions/code";
534
+ for (const [name, definition] of definitions) {
535
+ const properties = definition.properties;
536
+ if (!properties) continue;
537
+ for (const [property, schema] of Object.entries(properties)) {
538
+ const codes = codesByPath.get(elementPathFor(name, property));
539
+ if (!codes) continue;
540
+ const description = schema.description;
541
+ const withDescription = (node) => description ? { description, ...node } : node;
542
+ if (isCodeRef(schema)) {
543
+ properties[property] = withDescription({ enum: [...codes] });
544
+ } else if (schema.type === "array" && isCodeRef(schema.items)) {
545
+ properties[property] = withDescription({ type: "array", items: { enum: [...codes] } });
546
+ }
547
+ }
548
+ }
549
+ }
513
550
 
514
551
  // src/backends/structureDefinition.ts
515
552
  function buildRegistryFromStructureDefinitions(fhirVersion) {
@@ -593,9 +630,22 @@ function convertNode(node, target, options) {
593
630
  switch (key) {
594
631
  case "$schema":
595
632
  case "$comment":
633
+ // Draft-04/06 schema keywords. These are only keywords at schema-node
634
+ // level: inside `properties` the same names are FHIR element names, and
635
+ // nearly every FHIR element has an `id`. See the "properties" case.
596
636
  case "id":
597
637
  case "$id":
598
638
  break;
639
+ case "properties": {
640
+ const converted = {};
641
+ for (const [propertyName, propertySchema] of Object.entries(
642
+ value ?? {}
643
+ )) {
644
+ converted[propertyName] = convertNode(propertySchema, target, options);
645
+ }
646
+ out.properties = converted;
647
+ break;
648
+ }
599
649
  case "$ref":
600
650
  out.$ref = typeof value === "string" && value.startsWith(DEFINITIONS_REF) ? COMPONENTS_REF + value.slice(DEFINITIONS_REF.length) : value;
601
651
  break;
@@ -1426,4 +1476,4 @@ export {
1426
1476
  diffAgainstYaml,
1427
1477
  stringifyDocument
1428
1478
  };
1429
- //# sourceMappingURL=chunk-G3DCRADV.js.map
1479
+ //# sourceMappingURL=chunk-RR46JDST.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/ig/package.ts","../src/ig/minimize.ts","../src/definitions.ts","../src/ir/structureWalker.ts","../src/ig/profile.ts","../src/backends/schemaJson.ts","../src/backends/structureDefinition.ts","../src/emit/schema.ts","../src/ir/registry.ts","../src/operations.ts","../src/paths.ts","../src/generate.ts","../src/capability.ts","../src/merge.ts"],"sourcesContent":["export type FhirVersion = \"r4\" | \"r4b\" | \"r5\";\r\n\r\nexport const FHIR_VERSIONS: readonly FhirVersion[] = [\"r4\", \"r4b\", \"r5\"];\r\n\r\nexport const FHIR_VERSION_NUMBERS: Record<FhirVersion, string> = {\r\n r4: \"4.0.1\",\r\n r4b: \"4.3.0\",\r\n r5: \"5.0.0\",\r\n};\r\n\r\nexport type OpenApiVersion = \"3.0.3\" | \"3.1.0\";\r\n\r\nexport type SourceBackend = \"schema-json\" | \"structure-def\";\r\n\r\nexport interface TrimOptions {\r\n /**\r\n * Replace the Narrative type (human-readable HTML in `Resource.text`) with a\r\n * generic object. Shrinks generated models that never render narratives.\r\n */\r\n excludeNarrative?: boolean;\r\n /**\r\n * Stub out schema definitions first reached deeper than this many hops from\r\n * a requested resource with a generic object. Bounds the size of the\r\n * dependency closure for codegen targets that struggle with large graphs.\r\n */\r\n maxDepth?: number;\r\n /**\r\n * Replace required-binding enums on code fields with plain strings (the\r\n * allowed codes are appended to the description). Codegen'd models then\r\n * tolerate servers that return codes outside the strict ValueSet — a common\r\n * reality with legacy data. `resourceType` discriminators keep their enum.\r\n */\r\n noEnums?: boolean;\r\n}\r\n\r\n/** An IG package resolved to profiles + terminology (see ig/package.ts). */\r\nexport interface IgContextLike {\r\n name: string;\r\n version: string;\r\n fhirVersion: FhirVersion;\r\n profiles: unknown[];\r\n profilesMissingSnapshot: string[];\r\n resolveValueSet: (valueSetUrl: string) => string[] | undefined;\r\n}\r\n\r\n/** A parsed CapabilityStatement (see capability.ts). */\r\nexport interface CapabilityLike {\r\n fhirVersion?: string;\r\n resources: {\r\n type: string;\r\n interactions: Set<string>;\r\n searchParamCodes: Set<string>;\r\n operations: Set<string>;\r\n }[];\r\n}\r\n\r\nexport interface GenerateOptions {\r\n /**\r\n * FHIR resource names, e.g. [\"Patient\", \"Observation\"]. Optional when a\r\n * `capability` statement is given (its declared resources are used); when\r\n * both are set, generation is narrowed to the requested resources.\r\n */\r\n resources?: string[];\r\n fhirVersion: FhirVersion;\r\n /**\r\n * A parsed CapabilityStatement restricting generation to one server's\r\n * declared support (resources, interactions, search params, operations).\r\n * Use `loadCapabilityStatement` / `parseCapabilityStatement` to build it.\r\n */\r\n capability?: CapabilityLike;\r\n /**\r\n * IG package to apply profiles from: a local path (`.tgz` or unpacked\r\n * directory) loaded synchronously, or a pre-resolved IgContext (use the\r\n * async `loadIg` for registry coordinates). Required when `profiles` is set.\r\n */\r\n ig?: string | IgContextLike;\r\n /**\r\n * Profile ids, names, or canonical URLs to apply to their base resources.\r\n * Each profiled resource's schemas/paths reference the named profile schema.\r\n */\r\n profiles?: string[];\r\n /** Target OpenAPI version. Default: \"3.0.3\" (widest codegen support). */\r\n openApiVersion?: OpenApiVersion;\r\n /** Definition source backend. Default: \"schema-json\". */\r\n source?: SourceBackend;\r\n /**\r\n * Also emit the standard FHIR operations applicable to the requested\r\n * resources ($everything, $validate, ...) from the official\r\n * OperationDefinitions. Default: false.\r\n */\r\n operations?: boolean;\r\n /** Server base URL for the `servers` entry. Omitted when not given. */\r\n baseUrl?: string;\r\n /** Override the generated `info.title`. */\r\n title?: string;\r\n trim?: TrimOptions;\r\n}\r\n\r\n/** A JSON-Schema-like node. Kept loose: definitions come from vendored files. */\r\nexport type JsonSchemaNode = { [key: string]: unknown };\r\n\r\n/** A generated OpenAPI document (3.0.3 or 3.1.0) as a plain object. */\r\nexport type OpenApiDocument = { [key: string]: unknown };\r\n","import { execFileSync } from \"node:child_process\";\r\nimport fs from \"node:fs\";\r\nimport os from \"node:os\";\r\nimport path from \"node:path\";\r\nimport {\r\n buildValueSetResolver,\r\n minimizeStructureDefinition,\r\n type RawStructureDefinition,\r\n type ValueSetResolver,\r\n} from \"./minimize.js\";\r\nimport type { MinStructureDefinition } from \"../definitions.js\";\r\nimport { FHIR_VERSIONS, type FhirVersion } from \"../types.js\";\r\n\r\n/** Maps an IG package's FHIR version string to our supported version keys. */\r\nconst FHIR_VERSION_BY_NUMBER: Record<string, FhirVersion> = {\r\n \"4.0.1\": \"r4\",\r\n \"4.0.0\": \"r4\",\r\n \"4.3.0\": \"r4b\",\r\n \"5.0.0\": \"r5\",\r\n};\r\n\r\nexport interface IgProfile {\r\n /** Versionless canonical URL. */\r\n url: string;\r\n id?: string;\r\n name: string;\r\n type: string;\r\n definition: MinStructureDefinition;\r\n}\r\n\r\nexport interface IgContext {\r\n name: string;\r\n version: string;\r\n fhirVersion: FhirVersion;\r\n profiles: IgProfile[];\r\n /** Names/URLs of constraint profiles that lack a snapshot (cannot be applied). */\r\n profilesMissingSnapshot: string[];\r\n resolveValueSet: ValueSetResolver;\r\n}\r\n\r\nexport interface LoadIgOptions {\r\n /** Resolve core bindings (e.g. administrative-gender) not defined in the IG. */\r\n coreValueSetFallback?: ValueSetResolver;\r\n /** Base directory for the registry download cache. Defaults to ~/.fhir-oas. */\r\n cacheDir?: string;\r\n fetchImpl?: typeof fetch;\r\n}\r\n\r\ninterface RawResource {\r\n resourceType?: string;\r\n url?: string;\r\n name?: string;\r\n id?: string;\r\n type?: string;\r\n kind?: string;\r\n derivation?: string;\r\n snapshot?: unknown;\r\n [key: string]: unknown;\r\n}\r\n\r\nconst REGISTRY_BASE = \"https://packages.fhir.org\";\r\n\r\n/**\r\n * Resolves the `--ig` input to an IgContext. Accepts a path to a package\r\n * tarball (`.tgz`), a path to an unpacked package directory, or a registry\r\n * coordinate (`name` or `name@version`) fetched from packages.fhir.org and\r\n * cached locally. Async because registry coordinates hit the network.\r\n */\r\nexport async function loadIg(input: string, options: LoadIgOptions = {}): Promise<IgContext> {\r\n if (isRegistryCoordinate(input)) {\r\n const tarball = await fetchFromRegistry(input, options);\r\n return buildContext(readFromTarball(tarball), options.coreValueSetFallback);\r\n }\r\n return loadIgSync(input, options);\r\n}\r\n\r\n/**\r\n * Synchronous IG loader for local inputs (a `.tgz` or an unpacked directory).\r\n * Registry coordinates require the async {@link loadIg} because they fetch\r\n * over the network.\r\n */\r\nexport function loadIgSync(input: string, options: LoadIgOptions = {}): IgContext {\r\n if (isRegistryCoordinate(input)) {\r\n throw new Error(\r\n `\"${input}\" looks like a registry package coordinate, which requires a network ` +\r\n `fetch. Use loadIg() (async) or the CLI, or download the package and pass a local path.`,\r\n );\r\n }\r\n const stat = fs.existsSync(input) ? fs.statSync(input) : undefined;\r\n if (!stat) {\r\n throw new Error(\r\n `--ig \"${input}\" is not a file or directory. Pass a package .tgz, an unpacked ` +\r\n `package directory, or a registry coordinate like hl7.fhir.us.core@5.0.1.`,\r\n );\r\n }\r\n const files = stat.isDirectory() ? readFromDirectory(input) : readFromTarball(input);\r\n return buildContext(files, options.coreValueSetFallback);\r\n}\r\n\r\n/** package.json plus every FHIR JSON resource, keyed by base filename. */\r\ninterface PackageFiles {\r\n packageJson: { name?: string; version?: string; \"fhir-version-list\"?: string[]; fhirVersions?: string[] };\r\n resources: RawResource[];\r\n}\r\n\r\nfunction isRegistryCoordinate(input: string): boolean {\r\n // A registry coordinate is a package id (optionally @version); it never\r\n // looks like a path and does not exist on disk.\r\n if (fs.existsSync(input)) return false;\r\n if (input.includes(\"/\") || input.includes(\"\\\\\") || input.endsWith(\".tgz\")) return false;\r\n return /^[a-z0-9][a-z0-9.\\-]*(@[\\w.\\-]+)?$/i.test(input);\r\n}\r\n\r\nfunction packageDir(root: string): string {\r\n const nested = path.join(root, \"package\");\r\n if (fs.existsSync(path.join(nested, \"package.json\"))) return nested;\r\n if (fs.existsSync(path.join(root, \"package.json\"))) return root;\r\n throw new Error(`No package.json found under \"${root}\" (looked in ./ and ./package)`);\r\n}\r\n\r\nfunction readFromDirectory(dir: string): PackageFiles {\r\n const base = packageDir(dir);\r\n const packageJson = JSON.parse(fs.readFileSync(path.join(base, \"package.json\"), \"utf8\"));\r\n const resources: RawResource[] = [];\r\n for (const file of fs.readdirSync(base).sort()) {\r\n if (!file.endsWith(\".json\") || file === \"package.json\" || file === \".index.json\") continue;\r\n try {\r\n resources.push(JSON.parse(fs.readFileSync(path.join(base, file), \"utf8\")));\r\n } catch {\r\n // Skip non-resource JSON (e.g. index files that aren't FHIR resources).\r\n }\r\n }\r\n return { packageJson, resources };\r\n}\r\n\r\n/**\r\n * Extracts a package tarball to an isolated temp directory (tar refuses\r\n * absolute/`..` members, and the destination is a private mkdtemp), reads the\r\n * JSON resources, then removes the directory.\r\n */\r\nfunction readFromTarball(tarballPath: string): PackageFiles {\r\n if (!fs.existsSync(tarballPath)) {\r\n throw new Error(`Package tarball not found: ${tarballPath}`);\r\n }\r\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"fhir-oas-ig-\"));\r\n try {\r\n execFileSync(\"tar\", [\"-xzf\", tarballPath, \"-C\", tmp], { stdio: \"pipe\" });\r\n return readFromDirectory(tmp);\r\n } finally {\r\n fs.rmSync(tmp, { recursive: true, force: true });\r\n }\r\n}\r\n\r\nasync function fetchFromRegistry(coordinate: string, options: LoadIgOptions): Promise<string> {\r\n const [name, version] = coordinate.split(\"@\");\r\n const cacheDir = path.join(options.cacheDir ?? path.join(os.homedir(), \".fhir-oas\"), \"packages\");\r\n const resolvedVersion = version ?? \"latest\";\r\n const cachePath = path.join(cacheDir, `${name}#${resolvedVersion}.tgz`);\r\n if (fs.existsSync(cachePath)) return cachePath;\r\n\r\n const url = `${REGISTRY_BASE}/${name}/${resolvedVersion}`;\r\n const doFetch = options.fetchImpl ?? fetch;\r\n let response: Response;\r\n try {\r\n response = await doFetch(url);\r\n } catch (cause) {\r\n throw new Error(\r\n `Failed to reach the FHIR package registry at ${url}: ${(cause as Error).message}. ` +\r\n `If you are offline or behind a restrictive proxy, download the package and pass ` +\r\n `--ig ./${name}.tgz instead.`,\r\n );\r\n }\r\n if (!response.ok) {\r\n throw new Error(\r\n `FHIR package registry returned ${response.status} for ${url}. ` +\r\n `Check the package name and version, or download it and pass --ig ./${name}.tgz.`,\r\n );\r\n }\r\n const buffer = Buffer.from(await response.arrayBuffer());\r\n fs.mkdirSync(cacheDir, { recursive: true });\r\n fs.writeFileSync(cachePath, buffer);\r\n return cachePath;\r\n}\r\n\r\nfunction detectFhirVersion(packageJson: PackageFiles[\"packageJson\"]): FhirVersion {\r\n const versions = packageJson[\"fhir-version-list\"] ?? packageJson.fhirVersions ?? [];\r\n for (const v of versions) {\r\n const mapped = FHIR_VERSION_BY_NUMBER[v];\r\n if (mapped) return mapped;\r\n }\r\n throw new Error(\r\n `Could not determine a supported FHIR version for IG package \"${packageJson.name}\" ` +\r\n `(found: ${versions.join(\", \") || \"none\"}). Supported: ${FHIR_VERSIONS.join(\", \")}.`,\r\n );\r\n}\r\n\r\nfunction buildContext(files: PackageFiles, coreFallback?: ValueSetResolver): IgContext {\r\n const fhirVersion = detectFhirVersion(files.packageJson);\r\n const terminology = files.resources.filter(\r\n (r) => r.resourceType === \"ValueSet\" || r.resourceType === \"CodeSystem\",\r\n );\r\n const resolveValueSet = buildValueSetResolver(terminology as never[], coreFallback);\r\n\r\n const profiles: IgProfile[] = [];\r\n const profilesMissingSnapshot: string[] = [];\r\n for (const r of files.resources) {\r\n if (\r\n r.resourceType === \"StructureDefinition\" &&\r\n r.derivation === \"constraint\" &&\r\n r.kind === \"resource\"\r\n ) {\r\n if (!r.snapshot) {\r\n profilesMissingSnapshot.push(r.name ?? r.url ?? \"unknown\");\r\n continue;\r\n }\r\n const sd = r as unknown as RawStructureDefinition;\r\n profiles.push({\r\n url: sd.url.split(\"|\")[0]!,\r\n id: sd.id,\r\n name: sd.name,\r\n type: sd.type,\r\n definition: minimizeStructureDefinition(sd, resolveValueSet),\r\n });\r\n }\r\n }\r\n profiles.sort((a, b) => a.url.localeCompare(b.url));\r\n\r\n return {\r\n name: files.packageJson.name ?? \"unknown\",\r\n version: files.packageJson.version ?? \"unknown\",\r\n fhirVersion,\r\n profiles,\r\n profilesMissingSnapshot,\r\n resolveValueSet,\r\n };\r\n}\r\n","import type { MinElement, MinElementType, MinStructureDefinition } from \"../definitions.js\";\r\n\r\n/**\r\n * Minimizes raw FHIR StructureDefinition / terminology resources loaded from\r\n * an IG package into the same `MinStructureDefinition` shape the vendored core\r\n * definitions use, so profile snapshots feed the shared structure walker.\r\n *\r\n * This mirrors the element-minimizing shape in scripts/update-definitions.mjs\r\n * (which vendors the core packages at build time). The two are kept separate\r\n * on purpose: this one runs at generation time on arbitrary IG packages and\r\n * additionally captures profile constraints (`fixed[x]`, `mustSupport`,\r\n * unenforced `pattern`/slicing), which the base definitions never need.\r\n */\r\n\r\n/** Above this size an enum stops helping codegen and starts hurting it. */\r\nconst MAX_ENUM_CODES = 150;\r\n\r\ninterface RawElement {\r\n path: string;\r\n min?: number;\r\n max?: string;\r\n short?: string;\r\n definition?: string;\r\n contentReference?: string;\r\n mustSupport?: boolean;\r\n slicing?: unknown;\r\n sliceName?: string;\r\n type?: { code: string; targetProfile?: string[]; extension?: RawExtension[] }[];\r\n binding?: { strength?: string; valueSet?: string };\r\n [key: string]: unknown;\r\n}\r\n\r\ninterface RawExtension {\r\n url: string;\r\n valueUrl?: string;\r\n}\r\n\r\nexport interface RawStructureDefinition {\r\n resourceType: string;\r\n name: string;\r\n id?: string;\r\n url: string;\r\n kind: string;\r\n type: string;\r\n abstract?: boolean;\r\n derivation?: string;\r\n baseDefinition?: string;\r\n fhirVersion?: string;\r\n snapshot?: { element: RawElement[] };\r\n}\r\n\r\nexport type ValueSetResolver = (valueSetUrl: string) => string[] | undefined;\r\n\r\nconst FHIR_TYPE_EXTENSION =\r\n \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\";\r\n\r\n/** Extracts the normalized `fixed[x]` value from a snapshot element, if any. */\r\nfunction fixedValue(el: RawElement): unknown {\r\n for (const key of Object.keys(el)) {\r\n if (key.startsWith(\"fixed\") && key.length > 5) return el[key];\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction omittedConstraints(el: RawElement): string[] | undefined {\r\n const notes: string[] = [];\r\n if (el.slicing || el.sliceName) notes.push(\"slicing\");\r\n if (Object.keys(el).some((k) => k.startsWith(\"pattern\") && k.length > 7)) {\r\n notes.push(\"pattern\");\r\n }\r\n return notes.length > 0 ? notes : undefined;\r\n}\r\n\r\nfunction minimizeElement(el: RawElement, resolveValueSet?: ValueSetResolver): MinElement {\r\n const out: MinElement = { path: el.path, min: el.min ?? 0, max: el.max ?? \"*\" };\r\n if (el.short) out.short = el.short;\r\n if (el.definition) out.definition = el.definition;\r\n if (el.contentReference) out.contentReference = el.contentReference;\r\n if (el.type) {\r\n out.types = el.type.map((t) => {\r\n const type: MinElementType = { code: t.code };\r\n if (t.targetProfile) type.targetProfile = t.targetProfile;\r\n const fhirType = (t.extension ?? []).find((e) => e.url === FHIR_TYPE_EXTENSION);\r\n if (fhirType?.valueUrl) type.fhirType = fhirType.valueUrl;\r\n return type;\r\n });\r\n }\r\n if (el.binding?.strength === \"required\" && el.binding.valueSet) {\r\n out.binding = { strength: el.binding.strength, valueSet: el.binding.valueSet };\r\n const codes = resolveValueSet?.(el.binding.valueSet);\r\n if (codes) out.binding.codes = [...codes].sort();\r\n }\r\n const fixed = fixedValue(el);\r\n if (fixed !== undefined) out.fixed = fixed;\r\n if (el.mustSupport) out.mustSupport = true;\r\n const omitted = omittedConstraints(el);\r\n if (omitted) out.omittedConstraints = omitted;\r\n return out;\r\n}\r\n\r\nexport function minimizeStructureDefinition(\r\n sd: RawStructureDefinition,\r\n resolveValueSet?: ValueSetResolver,\r\n): MinStructureDefinition {\r\n return {\r\n name: sd.name,\r\n url: sd.url,\r\n kind: sd.kind as MinStructureDefinition[\"kind\"],\r\n type: sd.type,\r\n abstract: !!sd.abstract,\r\n baseDefinition: sd.baseDefinition,\r\n elements: (sd.snapshot?.element ?? []).map((el) => minimizeElement(el, resolveValueSet)),\r\n };\r\n}\r\n\r\ninterface RawValueSet {\r\n resourceType: string;\r\n url?: string;\r\n compose?: {\r\n include?: RawValueSetGroup[];\r\n exclude?: RawValueSetGroup[];\r\n };\r\n}\r\n\r\ninterface RawValueSetGroup {\r\n system?: string;\r\n concept?: { code: string }[];\r\n filter?: unknown[];\r\n valueSet?: string[];\r\n}\r\n\r\ninterface RawCodeSystem {\r\n resourceType: string;\r\n url?: string;\r\n content?: string;\r\n concept?: RawConcept[];\r\n}\r\n\r\ninterface RawConcept {\r\n code: string;\r\n concept?: RawConcept[];\r\n}\r\n\r\n/**\r\n * Builds a ValueSet URL -> flat code list resolver from the ValueSet and\r\n * CodeSystem resources available (IG-local plus, optionally, a fallback for\r\n * the vendored core terminology). Only simple composes are resolved; anything\r\n * with filters or valueSet imports is left unresolved, so the binding stays a\r\n * plain code — exactly the core behavior.\r\n */\r\nexport function buildValueSetResolver(\r\n resources: (RawValueSet | RawCodeSystem)[],\r\n fallback?: ValueSetResolver,\r\n): ValueSetResolver {\r\n const codeSystems = new Map<string, RawCodeSystem>();\r\n const valueSets = new Map<string, RawValueSet>();\r\n for (const r of resources) {\r\n if (r.resourceType === \"CodeSystem\" && r.url) codeSystems.set(r.url, r as RawCodeSystem);\r\n if (r.resourceType === \"ValueSet\" && r.url) valueSets.set(r.url, r as RawValueSet);\r\n }\r\n\r\n function conceptCodes(concepts: RawConcept[] | undefined, out: string[]): string[] {\r\n for (const c of concepts ?? []) {\r\n out.push(c.code);\r\n if (c.concept) conceptCodes(c.concept, out);\r\n }\r\n return out;\r\n }\r\n\r\n function resolveGroup(group: RawValueSetGroup): string[] | undefined {\r\n if (group.filter?.length || group.valueSet?.length) return undefined;\r\n if (group.concept?.length) return group.concept.map((c) => c.code);\r\n if (!group.system) return undefined;\r\n const cs = codeSystems.get(group.system);\r\n if (!cs || cs.content === \"not-present\" || !cs.concept) return undefined;\r\n return conceptCodes(cs.concept, []);\r\n }\r\n\r\n return function resolve(valueSetUrl: string): string[] | undefined {\r\n const versionless = valueSetUrl.split(\"|\")[0]!;\r\n const vs = valueSets.get(versionless);\r\n if (!vs?.compose?.include?.length) return fallback?.(valueSetUrl);\r\n const codes = new Set<string>();\r\n for (const group of vs.compose.include) {\r\n const groupCodes = resolveGroup(group);\r\n if (!groupCodes) return fallback?.(valueSetUrl);\r\n for (const code of groupCodes) codes.add(code);\r\n }\r\n for (const group of vs.compose.exclude ?? []) {\r\n const groupCodes = resolveGroup(group);\r\n if (!groupCodes) return fallback?.(valueSetUrl);\r\n for (const code of groupCodes) codes.delete(code);\r\n }\r\n if (codes.size === 0 || codes.size > MAX_ENUM_CODES) return fallback?.(valueSetUrl);\r\n return [...codes];\r\n };\r\n}\r\n","import { gunzipSync } from \"node:zlib\";\r\nimport fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"./types.js\";\r\n\r\n/**\r\n * The vendored `definitions/` directory sits at the package root, next to\r\n * `src/` (dev) or `dist/` (published build), so walking up from this module\r\n * finds it in both layouts.\r\n */\r\nfunction definitionsRoot(): string {\r\n let dir = path.dirname(fileURLToPath(import.meta.url));\r\n for (let i = 0; i < 5; i++) {\r\n const candidate = path.join(dir, \"definitions\");\r\n if (fs.existsSync(candidate)) return candidate;\r\n dir = path.dirname(dir);\r\n }\r\n throw new Error(\"Could not locate the vendored FHIR definitions directory\");\r\n}\r\n\r\nconst cache = new Map<string, unknown>();\r\n\r\nfunction loadGzJson(fhirVersion: FhirVersion, file: string): unknown {\r\n const key = `${fhirVersion}/${file}`;\r\n let value = cache.get(key);\r\n if (value === undefined) {\r\n const fullPath = path.join(definitionsRoot(), fhirVersion, `${file}.gz`);\r\n value = JSON.parse(gunzipSync(fs.readFileSync(fullPath)).toString(\"utf8\"));\r\n cache.set(key, value);\r\n }\r\n return value;\r\n}\r\n\r\nexport interface FhirJsonSchema {\r\n discriminator?: { propertyName: string; mapping: Record<string, string> };\r\n definitions: Record<string, JsonSchemaNode>;\r\n}\r\n\r\nexport function loadFhirSchema(fhirVersion: FhirVersion): FhirJsonSchema {\r\n return loadGzJson(fhirVersion, \"fhir.schema.json\") as FhirJsonSchema;\r\n}\r\n\r\nexport interface SearchParameter {\r\n name: string;\r\n code: string;\r\n base: string[];\r\n type: string;\r\n description?: string;\r\n}\r\n\r\nexport function loadSearchParameters(fhirVersion: FhirVersion): SearchParameter[] {\r\n const bundle = loadGzJson(fhirVersion, \"search-parameters.json\") as {\r\n entry?: { resource?: SearchParameter & { resourceType: string } }[];\r\n };\r\n return (bundle.entry ?? [])\r\n .map((e) => e.resource)\r\n .filter(\r\n // R4B ships a few draft codesystem-extensions-* SearchParameters with no\r\n // `base`; they can't be attached to any resource, so drop them here.\r\n (r): r is SearchParameter & { resourceType: string } =>\r\n r?.resourceType === \"SearchParameter\" && Array.isArray(r.base),\r\n );\r\n}\r\n\r\nexport interface MinOperationParameter {\r\n name: string;\r\n use: \"in\" | \"out\";\r\n min: number;\r\n max: string;\r\n /** Absent for multi-part parameters (they force POST + Parameters). */\r\n type?: string;\r\n documentation?: string;\r\n}\r\n\r\nexport interface MinOperationDefinition {\r\n name: string;\r\n code: string;\r\n url: string;\r\n description?: string;\r\n /** Applicable resource types; [\"Resource\"] means every resource. */\r\n resource: string[];\r\n system: boolean;\r\n type: boolean;\r\n instance: boolean;\r\n parameters: MinOperationParameter[];\r\n}\r\n\r\nexport function loadOperationDefinitions(fhirVersion: FhirVersion): MinOperationDefinition[] {\r\n return loadGzJson(fhirVersion, \"operation-definitions.json\") as MinOperationDefinition[];\r\n}\r\n\r\nexport interface MinElementType {\r\n code: string;\r\n targetProfile?: string[];\r\n fhirType?: string;\r\n}\r\n\r\nexport interface MinElement {\r\n path: string;\r\n min: number;\r\n max: string;\r\n short?: string;\r\n definition?: string;\r\n contentReference?: string;\r\n types?: MinElementType[];\r\n binding?: { strength: string; valueSet: string; codes?: string[] };\r\n /**\r\n * Value the element is fixed to by a profile (`fixed[x]`), normalized to a\r\n * JSON value. Only populated for profiles loaded from an IG package; the\r\n * vendored base definitions do not carry it.\r\n */\r\n fixed?: unknown;\r\n /** Profile `mustSupport` flag (surfaced in descriptions, not enforced). */\r\n mustSupport?: boolean;\r\n /**\r\n * Human labels for profile constraints this tool does not enforce in\r\n * OpenAPI (e.g. \"pattern\", \"slicing\"), surfaced in the property description\r\n * and `x-fhir-constraints-omitted`. IG profiles only.\r\n */\r\n omittedConstraints?: string[];\r\n}\r\n\r\nexport interface MinStructureDefinition {\r\n name: string;\r\n url: string;\r\n kind: \"resource\" | \"complex-type\" | \"primitive-type\";\r\n type: string;\r\n abstract: boolean;\r\n baseDefinition?: string;\r\n elements: MinElement[];\r\n}\r\n\r\nexport function loadStructureDefinitions(fhirVersion: FhirVersion): MinStructureDefinition[] {\r\n return loadGzJson(fhirVersion, \"structure-definitions.json\") as MinStructureDefinition[];\r\n}\r\n","import type { MinElement, MinStructureDefinition } from \"../definitions.js\";\r\nimport type { JsonSchemaNode } from \"../types.js\";\r\n\r\n/**\r\n * Walks a StructureDefinition snapshot into named IR schema definitions\r\n * (`#/definitions/<Name>` refs). Shared by the core structure-def backend\r\n * (base resources/types) and the profile applier (IG profiles), so the two\r\n * produce identical schema shapes and only differ in the constraints applied.\r\n */\r\nexport interface EmitOptions {\r\n /** Schema name for the root definition (e.g. \"Patient\" or \"USCorePatient\"). */\r\n rootName: string;\r\n /** Emit a `resourceType` discriminator property. */\r\n isResourceRoot: boolean;\r\n /**\r\n * Wire resourceType/description name. Defaults to the SD `type`. For a\r\n * profile this stays the base resource (\"Patient\") even though rootName is\r\n * the profile name, because resourceType on the wire is the base type.\r\n */\r\n resourceDisplayName?: string;\r\n /**\r\n * Apply profile constraints while walking: drop `max: \"0\"` elements and\r\n * turn `fixed[x]` into a `const`. Off for base definitions so their output\r\n * is unchanged.\r\n */\r\n profile?: boolean;\r\n}\r\n\r\ninterface ElementNode {\r\n element: MinElement;\r\n children: Map<string, ElementNode>;\r\n}\r\n\r\nfunction segmentToPascal(segment: string): string {\r\n return segment.charAt(0).toUpperCase() + segment.slice(1);\r\n}\r\n\r\nfunction isBackbone(el: MinElement): boolean {\r\n return (el.types ?? []).some((t) => t.code === \"BackboneElement\" || t.code === \"Element\");\r\n}\r\n\r\n/** Type codes from the FHIRPath system (used on `id`, `Extension.url`, ...). */\r\nfunction systemTypeSchema(code: string): JsonSchemaNode | undefined {\r\n if (!code.startsWith(\"http://hl7.org/fhirpath/System.\")) return undefined;\r\n const kind = code.slice(\"http://hl7.org/fhirpath/System.\".length);\r\n switch (kind) {\r\n case \"Boolean\":\r\n return { type: \"boolean\" };\r\n case \"Integer\":\r\n case \"Decimal\":\r\n return { type: \"number\" };\r\n default:\r\n return { type: \"string\" };\r\n }\r\n}\r\n\r\nfunction buildElementTree(sd: MinStructureDefinition): ElementNode | undefined {\r\n const rootPath = sd.type ?? sd.name;\r\n let root: ElementNode | undefined;\r\n const nodes = new Map<string, ElementNode>();\r\n for (const el of sd.elements) {\r\n const node: ElementNode = { element: el, children: new Map() };\r\n nodes.set(el.path, node);\r\n if (el.path === rootPath) {\r\n root = node;\r\n continue;\r\n }\r\n const parentPath = el.path.slice(0, el.path.lastIndexOf(\".\"));\r\n const segment = el.path.slice(el.path.lastIndexOf(\".\") + 1);\r\n nodes.get(parentPath)?.children.set(segment, node);\r\n }\r\n return root;\r\n}\r\n\r\n/**\r\n * Names a backbone reached by a `contentReference` (e.g. \"#Questionnaire.item\"\r\n * -> \"Questionnaire_Item\"). When walking a profile, a self-reference to the\r\n * base type root is remapped onto the profile's own name so the ref resolves\r\n * within the emitted profile schemas.\r\n */\r\nfunction contentReferenceName(reference: string, sd: MinStructureDefinition, rootName: string): string {\r\n // Two forms occur: the core definitions use \"#Observation.referenceRange\",\r\n // while IG snapshot generators emit the absolute canonical\r\n // \"http://hl7.org/fhir/StructureDefinition/Observation#Observation.referenceRange\".\r\n // Only the fragment names the element path.\r\n const hash = reference.lastIndexOf(\"#\");\r\n const path = hash >= 0 ? reference.slice(hash + 1) : reference;\r\n const [root, ...rest] = path.split(\".\");\r\n if (rest.length === 0) return root ?? path;\r\n const prefix = root === (sd.type ?? sd.name) ? rootName : (root ?? \"\");\r\n return [prefix, ...rest.map(segmentToPascal)].join(\"_\");\r\n}\r\n\r\nexport function emitStructureDefinitionSchemas(\r\n sd: MinStructureDefinition,\r\n definitions: Map<string, JsonSchemaNode>,\r\n opts: EmitOptions,\r\n): void {\r\n const root = buildElementTree(sd);\r\n if (!root) return;\r\n emitObjectDefinition(sd, opts.rootName, root, definitions, opts.isResourceRoot, opts);\r\n}\r\n\r\nfunction emitObjectDefinition(\r\n sd: MinStructureDefinition,\r\n name: string,\r\n node: ElementNode,\r\n definitions: Map<string, JsonSchemaNode>,\r\n isResourceRoot: boolean,\r\n opts: EmitOptions,\r\n): void {\r\n if (definitions.has(name)) return;\r\n const properties: Record<string, JsonSchemaNode> = {};\r\n const required: string[] = [];\r\n const displayName = opts.resourceDisplayName ?? sd.type ?? sd.name;\r\n\r\n if (isResourceRoot) {\r\n properties.resourceType = {\r\n description: `This is a ${displayName} resource`,\r\n const: displayName,\r\n };\r\n required.push(\"resourceType\");\r\n }\r\n\r\n // Reserve the name before recursing so cycles terminate.\r\n const definition: JsonSchemaNode = {\r\n ...(node.element.definition ? { description: node.element.definition } : {}),\r\n properties,\r\n additionalProperties: false,\r\n };\r\n definitions.set(name, definition);\r\n\r\n for (const [segment, child] of node.children) {\r\n emitProperty(sd, name, segment, child, properties, required, definitions, opts);\r\n }\r\n if (required.length > 0) definition.required = required.sort();\r\n}\r\n\r\nfunction emitProperty(\r\n sd: MinStructureDefinition,\r\n parentName: string,\r\n segment: string,\r\n node: ElementNode,\r\n properties: Record<string, JsonSchemaNode>,\r\n required: string[],\r\n definitions: Map<string, JsonSchemaNode>,\r\n opts: EmitOptions,\r\n): void {\r\n const el = node.element;\r\n // Profile constraint: an element constrained out (max 0) is removed.\r\n if (opts.profile && el.max === \"0\") return;\r\n\r\n const isArray = el.max === \"*\" || Number(el.max) > 1;\r\n const isChoice = segment.endsWith(\"[x]\");\r\n\r\n // In profile mode, annotate must-support and constraints not enforced in\r\n // OpenAPI (pattern, slicing) so they survive into generated docs.\r\n let description = el.definition ?? el.short;\r\n const omitted: string[] = [];\r\n if (opts.profile) {\r\n if (el.mustSupport) omitted.push(\"must-support\");\r\n if (el.omittedConstraints) omitted.push(...el.omittedConstraints);\r\n if (omitted.length > 0) {\r\n const note = `Profile constraints not enforced here: ${omitted.join(\", \")}.`;\r\n description = description ? `${description} ${note}` : note;\r\n }\r\n }\r\n\r\n const addProperty = (fieldName: string, schema: JsonSchemaNode, primitive: boolean) => {\r\n const annotated =\r\n omitted.length > 0 && !(\"$ref\" in schema)\r\n ? { ...schema, \"x-fhir-constraints-omitted\": omitted }\r\n : schema;\r\n properties[fieldName] = wrapCardinality(annotated, isArray, description);\r\n if (primitive) {\r\n properties[`_${fieldName}`] = wrapCardinality(\r\n { $ref: \"#/definitions/Element\" },\r\n isArray,\r\n `Extensions for ${fieldName}`,\r\n );\r\n }\r\n };\r\n\r\n if (isChoice) {\r\n const base = segment.slice(0, -3);\r\n for (const type of el.types ?? []) {\r\n const fieldName = base + segmentToPascal(type.code);\r\n const { schema, primitive } = schemaForTypeCode(type.code, el, opts);\r\n addProperty(fieldName, schema, primitive);\r\n }\r\n // Choice fields are never individually required: the constraint \"exactly\r\n // one of the expansions\" is not expressible in required[].\r\n return;\r\n }\r\n\r\n if (el.contentReference) {\r\n const target = contentReferenceName(el.contentReference, sd, opts.rootName);\r\n addProperty(segment, { $ref: `#/definitions/${target}` }, false);\r\n } else if (isBackbone(el) && node.children.size > 0) {\r\n const childName = `${parentName}_${segmentToPascal(segment)}`;\r\n emitObjectDefinition(sd, childName, node, definitions, false, opts);\r\n addProperty(segment, { $ref: `#/definitions/${childName}` }, false);\r\n } else {\r\n const type = (el.types ?? [])[0];\r\n if (!type) return; // extension-only or profiled-out element\r\n const { schema, primitive } = schemaForTypeCode(type.code, el, opts);\r\n addProperty(segment, schema, primitive);\r\n }\r\n\r\n if (el.min >= 1) required.push(segment);\r\n}\r\n\r\nfunction schemaForTypeCode(\r\n code: string,\r\n el: MinElement,\r\n opts: EmitOptions,\r\n): { schema: JsonSchemaNode; primitive: boolean } {\r\n const primitive = code.charAt(0) === code.charAt(0).toLowerCase();\r\n\r\n const system = systemTypeSchema(code);\r\n if (system) return { schema: system, primitive: false };\r\n if (code === \"Resource\" || code === \"DomainResource\") {\r\n return { schema: { $ref: \"#/definitions/ResourceList\" }, primitive: false };\r\n }\r\n // Profile constraint: a fixed value pins the element to a single constant.\r\n if (opts.profile && el.fixed !== undefined) {\r\n return { schema: { const: el.fixed }, primitive };\r\n }\r\n // Required bindings whose ValueSet was resolved become inline enums on\r\n // `code` elements, mirroring the official fhir.schema.json.\r\n if (code === \"code\" && el.binding?.codes?.length) {\r\n return { schema: { enum: el.binding.codes }, primitive: true };\r\n }\r\n return { schema: { $ref: `#/definitions/${code}` }, primitive };\r\n}\r\n\r\nfunction wrapCardinality(\r\n schema: JsonSchemaNode,\r\n isArray: boolean,\r\n description?: string,\r\n): JsonSchemaNode {\r\n const withDescription = (s: JsonSchemaNode) =>\r\n description && !(\"$ref\" in s) ? { description, ...s } : s;\r\n if (isArray) {\r\n return {\r\n ...(description ? { description } : {}),\r\n type: \"array\",\r\n items: schema,\r\n };\r\n }\r\n if (\"$ref\" in schema && description) {\r\n // JSON Schema draft-06/OAS 3.0 ignores siblings of $ref; nest description\r\n // via allOf only in 3.1. Keep plain $ref for compatibility.\r\n return schema;\r\n }\r\n return withDescription(schema);\r\n}\r\n","import { loadStructureDefinitions } from \"../definitions.js\";\r\nimport type { DefinitionRegistry } from \"../ir/registry.js\";\r\nimport { emitStructureDefinitionSchemas } from \"../ir/structureWalker.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"../types.js\";\r\nimport type { IgContext, IgProfile } from \"./package.js\";\r\nimport type { ValueSetResolver } from \"./minimize.js\";\r\n\r\nexport interface AppliedProfile {\r\n /** Component schema name emitted for the profile (e.g. \"USCorePatient\"). */\r\n schemaName: string;\r\n /** Base resource type the profile constrains (e.g. \"Patient\"). */\r\n resourceType: string;\r\n /** Versionless canonical URL of the profile. */\r\n url: string;\r\n}\r\n\r\n/**\r\n * A ValueSet resolver backed by the vendored core definitions: base elements\r\n * already carry the resolved code list for their required binding, so core\r\n * ValueSets (e.g. administrative-gender) referenced by profile elements can be\r\n * resolved without shipping the core ValueSets themselves.\r\n */\r\nexport function buildCoreValueSetFallback(fhirVersion: FhirVersion): ValueSetResolver {\r\n const map = new Map<string, string[]>();\r\n for (const sd of loadStructureDefinitions(fhirVersion)) {\r\n for (const el of sd.elements) {\r\n if (el.binding?.codes?.length && el.binding.valueSet) {\r\n const key = el.binding.valueSet.split(\"|\")[0]!;\r\n if (!map.has(key)) map.set(key, el.binding.codes);\r\n }\r\n }\r\n }\r\n return (valueSetUrl) => map.get(valueSetUrl.split(\"|\")[0]!);\r\n}\r\n\r\nfunction sanitizeSchemaName(name: string): string {\r\n const cleaned = name.replace(/[^A-Za-z0-9_]/g, \"\");\r\n return /^[A-Za-z]/.test(cleaned) ? cleaned : `Profile${cleaned}`;\r\n}\r\n\r\n/** Finds a profile in the IG by canonical URL, id, or name (case-insensitive). */\r\nfunction findProfile(context: IgContext, requested: string): IgProfile {\r\n const needle = requested.toLowerCase();\r\n const matches = context.profiles.filter(\r\n (p) =>\r\n p.url.toLowerCase() === needle ||\r\n p.id?.toLowerCase() === needle ||\r\n p.name.toLowerCase() === needle,\r\n );\r\n if (matches.length === 1) return matches[0]!;\r\n if (matches.length > 1) {\r\n throw new Error(\r\n `Profile \"${requested}\" is ambiguous in ${context.name}; match by canonical URL. ` +\r\n `Candidates: ${matches.map((p) => p.url).join(\", \")}`,\r\n );\r\n }\r\n if (context.profilesMissingSnapshot.some((p) => p.toLowerCase() === needle)) {\r\n throw new Error(\r\n `Profile \"${requested}\" in ${context.name} has no snapshot. Snapshot generation is ` +\r\n `out of scope; use a snapshot-bearing release of the IG.`,\r\n );\r\n }\r\n const available = context.profiles.map((p) => p.id ?? p.name).sort();\r\n throw new Error(\r\n `Profile \"${requested}\" not found in ${context.name}@${context.version}. ` +\r\n `Available profiles: ${available.join(\", \") || \"none\"}`,\r\n );\r\n}\r\n\r\n/**\r\n * Emits the profiled schema (and its backbones) into the registry, applying\r\n * the profile's constraints, and returns how it maps onto the base resource.\r\n * Unconstrained elements resolve to base type refs, so the dependency closure\r\n * still draws from the vendored core registry.\r\n */\r\nexport function applyProfile(\r\n context: IgContext,\r\n requested: string,\r\n registry: DefinitionRegistry,\r\n): AppliedProfile {\r\n const profile = findProfile(context, requested);\r\n let schemaName = sanitizeSchemaName(profile.name);\r\n // Guard against collision with a base definition of a different shape.\r\n if (registry.definitions.has(schemaName) && schemaName !== profile.type) {\r\n schemaName = `${schemaName}Profile`;\r\n }\r\n\r\n emitStructureDefinitionSchemas(profile.definition, registry.definitions, {\r\n rootName: schemaName,\r\n isResourceRoot: true,\r\n resourceDisplayName: profile.type,\r\n profile: true,\r\n });\r\n\r\n const schema = registry.definitions.get(schemaName) as JsonSchemaNode | undefined;\r\n if (schema) schema[\"x-fhir-profile\"] = profile.url;\r\n\r\n return { schemaName, resourceType: profile.type, url: profile.url };\r\n}\r\n","import { loadFhirSchema, loadStructureDefinitions } from \"../definitions.js\";\r\nimport type { DefinitionRegistry } from \"../ir/registry.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"../types.js\";\r\n\r\n/**\r\n * Builds the definition registry from the official `fhir.schema.json`\r\n * published with each FHIR release. This schema already has choice types\r\n * (value[x]) expanded and backbone elements flattened into named definitions\r\n * (e.g. `Patient_Contact`), so it maps directly onto the IR.\r\n *\r\n * One gap it does not cover: HL7 stopped inlining required-binding enums in\r\n * fhir.schema.json after R4, and even R4 only inlines some of them. The codes\r\n * are resolved at vendor time onto the StructureDefinition elements, so they\r\n * are applied here too — see applyBindingEnums.\r\n */\r\nexport function buildRegistryFromSchemaJson(fhirVersion: FhirVersion): DefinitionRegistry {\r\n const schema = loadFhirSchema(fhirVersion);\r\n const definitions = new Map<string, JsonSchemaNode>(Object.entries(schema.definitions));\r\n\r\n // Resource types are exactly the discriminator mapping keys; fall back to\r\n // \"has a resourceType const\" for robustness.\r\n let resourceNames: string[];\r\n if (schema.discriminator?.mapping) {\r\n resourceNames = Object.keys(schema.discriminator.mapping);\r\n } else {\r\n resourceNames = [...definitions.entries()]\r\n .filter(([, def]) => {\r\n const props = def.properties as Record<string, JsonSchemaNode> | undefined;\r\n return props?.resourceType !== undefined && \"const\" in (props.resourceType ?? {});\r\n })\r\n .map(([name]) => name);\r\n }\r\n\r\n applyBindingEnums(definitions, fhirVersion);\r\n\r\n return { fhirVersion, definitions, resourceNames };\r\n}\r\n\r\nconst lowerFirst = (s: string) => s.charAt(0).toLowerCase() + s.slice(1);\r\n\r\n/**\r\n * fhir.schema.json names flattened backbones `<Root>_<Segment>`; the element\r\n * paths they came from are `<Root>.<segment>`. Reverses that so a definition\r\n * and property can be looked up against the StructureDefinition elements.\r\n */\r\nfunction elementPathFor(definitionName: string, property: string): string {\r\n const [root, ...backbones] = definitionName.split(\"_\");\r\n return [root, ...backbones.map(lowerFirst), property].join(\".\");\r\n}\r\n\r\n/** element path -> resolved codes, for required bindings only. */\r\nfunction bindingCodeIndex(fhirVersion: FhirVersion): Map<string, string[]> {\r\n const index = new Map<string, string[]>();\r\n for (const sd of loadStructureDefinitions(fhirVersion)) {\r\n for (const el of sd.elements) {\r\n if (el.binding?.strength === \"required\" && el.binding.codes?.length) {\r\n index.set(el.path, el.binding.codes);\r\n }\r\n }\r\n }\r\n return index;\r\n}\r\n\r\n/**\r\n * Replaces plain `code` references with the inline enum for that element's\r\n * required binding. Only `code` targets are touched: Coding/CodeableConcept\r\n * carry their binding differently and stay as they are. Properties that\r\n * already have an enum (R4 ships many inline) are left alone.\r\n */\r\nfunction applyBindingEnums(\r\n definitions: Map<string, JsonSchemaNode>,\r\n fhirVersion: FhirVersion,\r\n): void {\r\n const codesByPath = bindingCodeIndex(fhirVersion);\r\n const isCodeRef = (node: JsonSchemaNode | undefined) =>\r\n !!node && node.$ref === \"#/definitions/code\";\r\n\r\n for (const [name, definition] of definitions) {\r\n const properties = definition.properties as Record<string, JsonSchemaNode> | undefined;\r\n if (!properties) continue;\r\n\r\n for (const [property, schema] of Object.entries(properties)) {\r\n const codes = codesByPath.get(elementPathFor(name, property));\r\n if (!codes) continue;\r\n\r\n const description = schema.description as string | undefined;\r\n const withDescription = (node: JsonSchemaNode) =>\r\n description ? { description, ...node } : node;\r\n\r\n if (isCodeRef(schema)) {\r\n properties[property] = withDescription({ enum: [...codes] });\r\n } else if (schema.type === \"array\" && isCodeRef(schema.items as JsonSchemaNode)) {\r\n properties[property] = withDescription({ type: \"array\", items: { enum: [...codes] } });\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n loadStructureDefinitions,\r\n type MinStructureDefinition,\r\n} from \"../definitions.js\";\r\nimport type { DefinitionRegistry } from \"../ir/registry.js\";\r\nimport { emitStructureDefinitionSchemas } from \"../ir/structureWalker.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"../types.js\";\r\n\r\n/**\r\n * Builds the definition registry by walking StructureDefinition snapshots —\r\n * the canonical FHIR metadata, and the basis for profile support. Produces the\r\n * same IR shape as the fhir.schema.json backend: named definitions referencing\r\n * each other via `#/definitions/<Name>`.\r\n *\r\n * The per-snapshot walk lives in ../ir/structureWalker.ts so profiles loaded\r\n * from an IG package emit identically-shaped schemas.\r\n */\r\nexport function buildRegistryFromStructureDefinitions(\r\n fhirVersion: FhirVersion,\r\n): DefinitionRegistry {\r\n const sds = loadStructureDefinitions(fhirVersion);\r\n const definitions = new Map<string, JsonSchemaNode>();\r\n const resourceNames: string[] = [];\r\n\r\n const byName = new Map(sds.map((sd) => [sd.name, sd]));\r\n\r\n for (const sd of sds) {\r\n if (sd.kind === \"primitive-type\") {\r\n definitions.set(sd.name, primitiveSchema(sd));\r\n }\r\n }\r\n // `xhtml` (Narrative.div) has no StructureDefinition in the core packages.\r\n if (!definitions.has(\"xhtml\")) {\r\n definitions.set(\"xhtml\", {\r\n type: \"string\",\r\n description: \"XHTML narrative content\",\r\n });\r\n }\r\n\r\n for (const sd of sds) {\r\n if (sd.kind === \"primitive-type\" || sd.abstract) continue;\r\n emitStructureDefinitionSchemas(sd, definitions, {\r\n rootName: sd.name,\r\n isResourceRoot: sd.kind === \"resource\",\r\n });\r\n if (sd.kind === \"resource\") resourceNames.push(sd.name);\r\n }\r\n\r\n // Element/BackboneElement are abstract but referenced by primitive-extension\r\n // (`_field`) properties, so they need concrete definitions.\r\n for (const abstractName of [\"Element\", \"BackboneElement\"]) {\r\n const sd = byName.get(abstractName);\r\n if (sd && !definitions.has(abstractName)) {\r\n emitStructureDefinitionSchemas(sd, definitions, {\r\n rootName: sd.name,\r\n isResourceRoot: false,\r\n });\r\n }\r\n }\r\n\r\n resourceNames.sort();\r\n definitions.set(\"ResourceList\", {\r\n oneOf: resourceNames.map((name) => ({ $ref: `#/definitions/${name}` })),\r\n });\r\n\r\n return { fhirVersion, definitions, resourceNames };\r\n}\r\n\r\n/** Maps FHIR primitive type names to their JSON representation. */\r\nfunction primitiveJsonType(name: string): JsonSchemaNode {\r\n switch (name) {\r\n case \"boolean\":\r\n return { type: \"boolean\" };\r\n case \"decimal\":\r\n return { type: \"number\" };\r\n case \"integer\":\r\n case \"positiveInt\":\r\n case \"unsignedInt\":\r\n return { type: \"number\" };\r\n // integer64 (R5) is represented as a JSON string per the spec.\r\n default:\r\n return { type: \"string\" };\r\n }\r\n}\r\n\r\nfunction primitiveSchema(sd: MinStructureDefinition): JsonSchemaNode {\r\n const root = sd.elements[0];\r\n return {\r\n ...primitiveJsonType(sd.name),\r\n ...(root?.definition ? { description: root.definition } : {}),\r\n };\r\n}\r\n","import type { JsonSchemaNode, OpenApiVersion } from \"../types.js\";\r\n\r\nconst DEFINITIONS_REF = \"#/definitions/\";\r\nconst COMPONENTS_REF = \"#/components/schemas/\";\r\nconst NO_ENUMS_NOTE_MAX_CODES = 25;\r\n\r\nexport interface ConvertOptions {\r\n /** Strip source enums (required-binding codes), noting them in description. */\r\n noEnums?: boolean;\r\n}\r\n\r\n/**\r\n * Converts one JSON-Schema-shaped definition (draft-06 subset as used by\r\n * fhir.schema.json) into an OpenAPI schema object:\r\n * - rewrites `#/definitions/X` refs to `#/components/schemas/X`\r\n * - strips `pattern` from non-string types (fhir.schema.json puts regex\r\n * patterns on booleans/numbers, where the keyword is meaningless)\r\n * - drops JSON Schema bookkeeping keywords ($schema, id/$id, $comment)\r\n * - for 3.0.x, downconverts `const` to a single-value `enum`\r\n * - with `noEnums`, replaces source enums with plain strings, keeping the\r\n * allowed codes in the description; `const`-derived enums (resourceType\r\n * discriminators) are exempt\r\n */\r\nexport function convertSchema(\r\n node: JsonSchemaNode,\r\n target: OpenApiVersion,\r\n options: ConvertOptions = {},\r\n): JsonSchemaNode {\r\n return convertNode(node, target, options) as JsonSchemaNode;\r\n}\r\n\r\nfunction convertNode(node: unknown, target: OpenApiVersion, options: ConvertOptions): unknown {\r\n if (Array.isArray(node)) {\r\n return node.map((item) => convertNode(item, target, options));\r\n }\r\n if (!node || typeof node !== \"object\") return node;\r\n\r\n const out: JsonSchemaNode = {};\r\n const source = node as JsonSchemaNode;\r\n let strippedEnum: unknown[] | undefined;\r\n for (const [key, value] of Object.entries(source)) {\r\n switch (key) {\r\n case \"$schema\":\r\n case \"$comment\":\r\n // Draft-04/06 schema keywords. These are only keywords at schema-node\r\n // level: inside `properties` the same names are FHIR element names, and\r\n // nearly every FHIR element has an `id`. See the \"properties\" case.\r\n case \"id\":\r\n case \"$id\":\r\n break;\r\n case \"properties\": {\r\n // Keys here are property names, not schema keywords, so they are\r\n // preserved verbatim and only their values converted.\r\n const converted: JsonSchemaNode = {};\r\n for (const [propertyName, propertySchema] of Object.entries(\r\n (value ?? {}) as Record<string, unknown>,\r\n )) {\r\n converted[propertyName] = convertNode(propertySchema, target, options);\r\n }\r\n out.properties = converted;\r\n break;\r\n }\r\n case \"$ref\":\r\n out.$ref =\r\n typeof value === \"string\" && value.startsWith(DEFINITIONS_REF)\r\n ? COMPONENTS_REF + value.slice(DEFINITIONS_REF.length)\r\n : value;\r\n break;\r\n case \"const\":\r\n if (target === \"3.1.0\") out.const = value;\r\n else out.enum = [value];\r\n break;\r\n case \"enum\":\r\n if (options.noEnums && Array.isArray(value)) strippedEnum = value;\r\n else out.enum = value;\r\n break;\r\n case \"pattern\":\r\n if (source.type === undefined || source.type === \"string\") out.pattern = value;\r\n break;\r\n default:\r\n out[key] = convertNode(value, target, options);\r\n }\r\n }\r\n\r\n if (strippedEnum) {\r\n if (out.type === undefined && out.$ref === undefined) out.type = \"string\";\r\n const listed = strippedEnum.slice(0, NO_ENUMS_NOTE_MAX_CODES).join(\" | \");\r\n const ellipsis = strippedEnum.length > NO_ENUMS_NOTE_MAX_CODES ? \" | ...\" : \"\";\r\n const note = `Codes (FHIR required binding, not enforced here): ${listed}${ellipsis}`;\r\n out.description = out.description ? `${out.description} ${note}` : note;\r\n }\r\n return out;\r\n}\r\n","import type { FhirVersion, JsonSchemaNode, TrimOptions } from \"../types.js\";\r\n\r\n/**\r\n * Backend-neutral intermediate representation: a set of named,\r\n * JSON-Schema-shaped type definitions whose internal references use the\r\n * `#/definitions/<Name>` form (the convention of the official fhir.schema.json).\r\n * Both backends produce this shape; emitters consume it.\r\n */\r\nexport interface DefinitionRegistry {\r\n fhirVersion: FhirVersion;\r\n definitions: Map<string, JsonSchemaNode>;\r\n /** Concrete (non-abstract) resource type names, e.g. \"Patient\". */\r\n resourceNames: string[];\r\n}\r\n\r\nconst REF_PREFIX = \"#/definitions/\";\r\n\r\nexport function refName(ref: string): string | undefined {\r\n return ref.startsWith(REF_PREFIX) ? ref.slice(REF_PREFIX.length) : undefined;\r\n}\r\n\r\n/** Collects the names of all `#/definitions/...` references inside a schema node. */\r\nexport function collectRefs(node: unknown, out = new Set<string>()): Set<string> {\r\n if (Array.isArray(node)) {\r\n for (const item of node) collectRefs(item, out);\r\n } else if (node && typeof node === \"object\") {\r\n for (const [key, value] of Object.entries(node)) {\r\n if (key === \"$ref\" && typeof value === \"string\") {\r\n const name = refName(value);\r\n if (name) out.add(name);\r\n } else {\r\n collectRefs(value, out);\r\n }\r\n }\r\n }\r\n return out;\r\n}\r\n\r\nexport interface ClosureResult {\r\n /** Definition name -> schema, for the full dependency closure of the roots. */\r\n schemas: Map<string, JsonSchemaNode>;\r\n /** Names whose bodies were replaced by generic-object stubs via trimming. */\r\n stubbed: Set<string>;\r\n}\r\n\r\nfunction stubSchema(reason: string): JsonSchemaNode {\r\n return {\r\n type: \"object\",\r\n additionalProperties: true,\r\n description: reason,\r\n };\r\n}\r\n\r\n/**\r\n * `ResourceList` in fhir.schema.json is a oneOf over every resource type\r\n * (150-200 entries), referenced by e.g. `Bundle.entry.resource` and\r\n * `DomainResource.contained`. Following it verbatim would drag the entire\r\n * specification into every output, so it is narrowed to the resource types\r\n * actually requested (plus Bundle/OperationOutcome, which the generated REST\r\n * paths always use).\r\n */\r\nfunction narrowedResourceList(included: string[]): JsonSchemaNode {\r\n return {\r\n oneOf: included.map((name) => ({ $ref: `${REF_PREFIX}${name}` })),\r\n description:\r\n \"A contained/bundled FHIR resource. Narrowed by fhir-openapi-translator to the \" +\r\n \"resource types requested at generation time; servers may return other types.\",\r\n };\r\n}\r\n\r\n/**\r\n * Extracts the transitive dependency closure of `roots` from the registry via\r\n * breadth-first search. Cycles are fine: every definition is visited once and\r\n * mutual references remain as $refs. Trim options replace selected\r\n * definitions with stubs whose dependencies are not followed.\r\n */\r\nexport function extractClosure(\r\n registry: DefinitionRegistry,\r\n roots: string[],\r\n trim: TrimOptions = {},\r\n resourceListNarrowing: string[] = roots,\r\n): ClosureResult {\r\n const schemas = new Map<string, JsonSchemaNode>();\r\n const stubbed = new Set<string>();\r\n const maxDepth = trim.maxDepth;\r\n\r\n let frontier = [...new Set(roots)];\r\n let depth = 0;\r\n while (frontier.length > 0) {\r\n const next: string[] = [];\r\n for (const name of frontier) {\r\n if (schemas.has(name)) continue;\r\n const original = registry.definitions.get(name);\r\n if (!original) {\r\n throw new Error(`Unknown FHIR definition: ${name}`);\r\n }\r\n\r\n let schema: JsonSchemaNode = original;\r\n let followDeps = true;\r\n if (trim.excludeNarrative && name === \"Narrative\") {\r\n schema = stubSchema(\r\n \"Human-readable narrative. Excluded from this specification (--exclude-narrative).\",\r\n );\r\n followDeps = false;\r\n stubbed.add(name);\r\n } else if (maxDepth !== undefined && depth > maxDepth) {\r\n schema = stubSchema(\r\n `FHIR ${name}. Pruned from this specification by --max-depth ${maxDepth}.`,\r\n );\r\n followDeps = false;\r\n stubbed.add(name);\r\n } else if (name === \"ResourceList\") {\r\n schema = narrowedResourceList(\r\n [...new Set(resourceListNarrowing)].filter((n) => registry.definitions.has(n)),\r\n );\r\n }\r\n\r\n schemas.set(name, schema);\r\n if (followDeps) {\r\n for (const dep of collectRefs(schema)) {\r\n if (!schemas.has(dep)) next.push(dep);\r\n }\r\n }\r\n }\r\n frontier = next;\r\n depth++;\r\n }\r\n\r\n return { schemas, stubbed };\r\n}\r\n","import {\r\n loadOperationDefinitions,\r\n type MinOperationDefinition,\r\n type MinOperationParameter,\r\n} from \"./definitions.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"./types.js\";\r\n\r\nconst FHIR_JSON = \"application/fhir+json\";\r\nconst SCHEMAS = \"#/components/schemas/\";\r\n\r\n/** FHIR primitive type names are lowercase-first; complex types are not. */\r\nfunction isPrimitive(type: string | undefined): boolean {\r\n return !!type && type.charAt(0) === type.charAt(0).toLowerCase();\r\n}\r\n\r\nfunction camelCode(code: string): string {\r\n return code.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());\r\n}\r\n\r\nfunction ref(schema: string) {\r\n return { $ref: `${SCHEMAS}${schema}` };\r\n}\r\n\r\nfunction fhirContent(schema: string) {\r\n return { [FHIR_JSON]: { schema: ref(schema) } };\r\n}\r\n\r\nfunction errorResponses() {\r\n return {\r\n default: {\r\n description: \"Error, with an OperationOutcome describing the problem\",\r\n content: fhirContent(\"OperationOutcome\"),\r\n },\r\n };\r\n}\r\n\r\nexport interface OperationPathsResult {\r\n paths: Record<string, JsonSchemaNode>;\r\n /** Schema names the operations reference, to add to the closure roots. */\r\n extraSchemaRoots: string[];\r\n}\r\n\r\n/**\r\n * Emits paths for the standard FHIR operations applicable to one resource\r\n * type, from the vendored OperationDefinitions.\r\n *\r\n * Method selection is deterministic per operation: GET with query parameters\r\n * when every `in` parameter is a primitive type (the spec-legal simple\r\n * invocation, and how e.g. $everything is used in practice); otherwise POST\r\n * with a Parameters request body. System-level-only operations are not\r\n * resource-scoped and are out of scope here.\r\n */\r\nexport interface OperationPathOptions {\r\n /** Maps a resource type to the schema name to reference (profile-aware). */\r\n schemaFor?: (resourceType: string) => string;\r\n /**\r\n * Restrict to operations whose code or canonical URL is in this set (e.g.\r\n * from a CapabilityStatement). Default: all operations applicable to the\r\n * resource.\r\n */\r\n only?: ReadonlySet<string>;\r\n}\r\n\r\nexport function buildOperationPaths(\r\n fhirVersion: FhirVersion,\r\n resource: string,\r\n knownResources: ReadonlySet<string>,\r\n options: OperationPathOptions = {},\r\n): OperationPathsResult {\r\n const schemaFor = options.schemaFor ?? ((r) => r);\r\n const paths: Record<string, JsonSchemaNode> = {};\r\n const extraSchemaRoots = new Set<string>();\r\n\r\n const applicable = loadOperationDefinitions(fhirVersion).filter(\r\n (op) =>\r\n (op.type || op.instance) &&\r\n (op.resource.includes(resource) || op.resource.includes(\"Resource\")) &&\r\n (!options.only || options.only.has(op.code) || options.only.has(op.url)),\r\n );\r\n\r\n for (const op of applicable) {\r\n const inParams = op.parameters.filter((p) => p.use === \"in\");\r\n const useGet = inParams.every((p) => isPrimitive(p.type));\r\n const responseSchema = schemaFor(responseSchemaName(op, knownResources));\r\n extraSchemaRoots.add(responseSchema);\r\n if (!useGet) extraSchemaRoots.add(\"Parameters\");\r\n\r\n const buildOperation = (level: \"Type\" | \"Instance\") => {\r\n const operation: JsonSchemaNode = {\r\n tags: [resource],\r\n summary: `$${op.code} (${level.toLowerCase()} level)`,\r\n ...(op.description ? { description: op.description } : {}),\r\n operationId: `${camelCode(op.code)}${resource}${level}`,\r\n externalDocs: { url: op.url },\r\n responses: {\r\n \"200\": {\r\n description: `Result of the $${op.code} operation`,\r\n content: fhirContent(responseSchema),\r\n },\r\n ...errorResponses(),\r\n },\r\n };\r\n if (useGet) {\r\n if (inParams.length > 0) operation.parameters = inParams.map(queryParameter);\r\n } else {\r\n operation.requestBody = {\r\n required: inParams.some((p) => p.min >= 1),\r\n content: fhirContent(\"Parameters\"),\r\n };\r\n }\r\n return operation;\r\n };\r\n\r\n const method = useGet ? \"get\" : \"post\";\r\n if (op.type) {\r\n paths[`/${resource}/$${op.code}`] = { [method]: buildOperation(\"Type\") };\r\n }\r\n if (op.instance) {\r\n paths[`/${resource}/{id}/$${op.code}`] = {\r\n parameters: [\r\n {\r\n name: \"id\",\r\n in: \"path\",\r\n required: true,\r\n description: `Logical id of the ${resource}`,\r\n schema: { type: \"string\", pattern: \"^[A-Za-z0-9\\\\-\\\\.]{1,64}$\" },\r\n },\r\n ],\r\n [method]: buildOperation(\"Instance\"),\r\n };\r\n }\r\n }\r\n\r\n return { paths, extraSchemaRoots: [...extraSchemaRoots].sort() };\r\n}\r\n\r\n/**\r\n * Exactly one `out` parameter named `return` typed as a resource maps to that\r\n * resource; every other output shape is a Parameters resource.\r\n */\r\nfunction responseSchemaName(\r\n op: MinOperationDefinition,\r\n knownResources: ReadonlySet<string>,\r\n): string {\r\n const outParams = op.parameters.filter((p) => p.use === \"out\");\r\n if (outParams.length === 1) {\r\n const only = outParams[0]!;\r\n if (only.name === \"return\" && only.type && knownResources.has(only.type)) {\r\n return only.type;\r\n }\r\n }\r\n return \"Parameters\";\r\n}\r\n\r\nfunction queryParameter(param: MinOperationParameter): JsonSchemaNode {\r\n const isArray = param.max === \"*\" || Number(param.max) > 1;\r\n const base: JsonSchemaNode = { type: \"string\" };\r\n return {\r\n name: param.name,\r\n in: \"query\",\r\n required: param.min >= 1,\r\n ...(param.documentation ? { description: param.documentation } : {}),\r\n // FHIR primitives serialize as strings in URLs; the FHIR type is kept\r\n // as an extension, consistent with search parameters.\r\n schema: isArray ? { type: \"array\", items: base } : base,\r\n ...(isArray ? { explode: true } : {}),\r\n \"x-fhir-type\": param.type,\r\n };\r\n}\r\n","import { loadSearchParameters } from \"./definitions.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"./types.js\";\r\n\r\nconst FHIR_JSON = \"application/fhir+json\";\r\nconst SCHEMAS = \"#/components/schemas/\";\r\nconst PARAMETERS = \"#/components/parameters/\";\r\n\r\nfunction ref(schema: string) {\r\n return { $ref: `${SCHEMAS}${schema}` };\r\n}\r\n\r\nfunction fhirContent(schema: string) {\r\n return { [FHIR_JSON]: { schema: ref(schema) } };\r\n}\r\n\r\nfunction errorResponses() {\r\n return {\r\n default: {\r\n description: \"Error, with an OperationOutcome describing the problem\",\r\n content: fhirContent(\"OperationOutcome\"),\r\n },\r\n };\r\n}\r\n\r\nfunction idParameter(name: string, description: string) {\r\n return {\r\n name,\r\n in: \"path\",\r\n required: true,\r\n description,\r\n schema: { type: \"string\", pattern: \"^[A-Za-z0-9\\\\-\\\\.]{1,64}$\" },\r\n };\r\n}\r\n\r\n/**\r\n * Search parameters common to all resources plus the standard search result\r\n * parameters, emitted once under components/parameters and $ref'd from every\r\n * search operation. All are strings except _count: FHIR search values carry\r\n * prefixes/modifiers (e.g. `ge2020-01-01`, `:exact`), so stricter types would\r\n * reject valid requests.\r\n */\r\nconst COMMON_SEARCH_PARAMETERS: Record<string, { description: string; schema: JsonSchemaNode }> = {\r\n _id: { description: \"Logical id of this artifact\", schema: { type: \"string\" } },\r\n _lastUpdated: {\r\n description: \"When the resource version last changed (supports date prefixes, e.g. ge2021-01-01)\",\r\n schema: { type: \"string\" },\r\n },\r\n _tag: { description: \"Tags applied to this resource\", schema: { type: \"string\" } },\r\n _profile: { description: \"Profiles this resource claims to conform to\", schema: { type: \"string\" } },\r\n _security: { description: \"Security labels applied to this resource\", schema: { type: \"string\" } },\r\n _text: { description: \"Search on the narrative of the resource\", schema: { type: \"string\" } },\r\n _content: { description: \"Search on the entire content of the resource\", schema: { type: \"string\" } },\r\n _sort: { description: \"Sort order of the results (comma-separated parameter names, '-' prefix for descending)\", schema: { type: \"string\" } },\r\n _count: { description: \"Maximum number of results per page\", schema: { type: \"integer\", minimum: 0 } },\r\n _include: { description: \"Include referenced resources in the results\", schema: { type: \"string\" } },\r\n _revinclude: { description: \"Include resources that reference the matches in the results\", schema: { type: \"string\" } },\r\n _summary: {\r\n description: \"Return only a portion of each resource\",\r\n schema: { type: \"string\", enum: [\"true\", \"text\", \"data\", \"count\", \"false\"] },\r\n },\r\n _total: {\r\n description: \"Requested precision of the Bundle.total\",\r\n schema: { type: \"string\", enum: [\"none\", \"estimate\", \"accurate\"] },\r\n },\r\n _elements: { description: \"Restrict returned elements (comma-separated element names)\", schema: { type: \"string\" } },\r\n};\r\n\r\nexport function commonSearchParameterComponents(): Record<string, JsonSchemaNode> {\r\n const out: Record<string, JsonSchemaNode> = {};\r\n for (const [name, { description, schema }] of Object.entries(COMMON_SEARCH_PARAMETERS)) {\r\n out[name] = { name, in: \"query\", required: false, description, schema };\r\n }\r\n return out;\r\n}\r\n\r\n/** FHIR RESTful interaction codes (CapabilityStatement.rest.resource.interaction). */\r\nexport type FhirInteraction =\r\n | \"read\"\r\n | \"vread\"\r\n | \"update\"\r\n | \"patch\"\r\n | \"delete\"\r\n | \"history-instance\"\r\n | \"history-type\"\r\n | \"create\"\r\n | \"search-type\";\r\n\r\nexport const ALL_INTERACTIONS: readonly FhirInteraction[] = [\r\n \"read\",\r\n \"vread\",\r\n \"update\",\r\n \"patch\",\r\n \"delete\",\r\n \"history-instance\",\r\n \"history-type\",\r\n \"create\",\r\n \"search-type\",\r\n];\r\n\r\nexport interface ResourcePathOptions {\r\n /** Emit only these interactions. Default: all of them. */\r\n interactions?: ReadonlySet<FhirInteraction>;\r\n /**\r\n * Restrict resource-specific search parameters to these codes (the common\r\n * result parameters like `_id`/`_count` are always kept). Default: all\r\n * search parameters the FHIR version defines for the resource.\r\n */\r\n searchParamCodes?: ReadonlySet<string>;\r\n}\r\n\r\nfunction resourceSearchParameters(\r\n fhirVersion: FhirVersion,\r\n resource: string,\r\n only?: ReadonlySet<string>,\r\n): JsonSchemaNode[] {\r\n return loadSearchParameters(fhirVersion)\r\n .filter((sp) => sp.base.includes(resource) && (!only || only.has(sp.code)))\r\n .sort((a, b) => a.code.localeCompare(b.code))\r\n .map((sp) => ({\r\n name: sp.code,\r\n in: \"query\",\r\n required: false,\r\n description: sp.description,\r\n // FHIR search values carry prefixes and modifiers, so all are strings.\r\n schema: { type: \"string\" },\r\n \"x-fhir-search-type\": sp.type,\r\n }));\r\n}\r\n\r\nconst historyParameters = () => [\r\n { $ref: `${PARAMETERS}_count` },\r\n {\r\n name: \"_since\",\r\n in: \"query\",\r\n required: false,\r\n description: \"Only include versions created at or after this instant\",\r\n schema: { type: \"string\", format: \"date-time\" },\r\n },\r\n];\r\n\r\n/**\r\n * FHIR RESTful API interactions for one resource type. By default every\r\n * standard interaction (search, create, read, vread, update, patch, delete,\r\n * and instance/type history) is emitted; `options.interactions` restricts the\r\n * set (e.g. from a CapabilityStatement), and empty path items are dropped.\r\n */\r\nexport function buildResourcePaths(\r\n fhirVersion: FhirVersion,\r\n resource: string,\r\n /** Schema referenced by request/response bodies; a profile name or the resource. */\r\n schemaName: string = resource,\r\n options: ResourcePathOptions = {},\r\n): Record<string, JsonSchemaNode> {\r\n const want = (interaction: FhirInteraction) =>\r\n !options.interactions || options.interactions.has(interaction);\r\n const body = () => fhirContent(schemaName);\r\n const idParam = () => idParameter(\"id\", `Logical id of the ${resource}`);\r\n const paths: Record<string, JsonSchemaNode> = {};\r\n\r\n const typeItem: Record<string, JsonSchemaNode> = {};\r\n if (want(\"search-type\")) {\r\n typeItem.get = {\r\n tags: [resource],\r\n summary: `Search for ${resource} resources`,\r\n operationId: `search${resource}`,\r\n parameters: [\r\n ...Object.keys(COMMON_SEARCH_PARAMETERS).map((name) => ({ $ref: `${PARAMETERS}${name}` })),\r\n ...resourceSearchParameters(fhirVersion, resource, options.searchParamCodes),\r\n ],\r\n responses: {\r\n \"200\": {\r\n description: `Bundle of matching ${resource} resources`,\r\n content: fhirContent(\"Bundle\"),\r\n },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"create\")) {\r\n typeItem.post = {\r\n tags: [resource],\r\n summary: `Create a ${resource} resource`,\r\n operationId: `create${resource}`,\r\n requestBody: { required: true, content: body() },\r\n responses: {\r\n \"201\": { description: `${resource} created`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (Object.keys(typeItem).length > 0) paths[`/${resource}`] = typeItem;\r\n\r\n const instanceItem: Record<string, JsonSchemaNode> = {};\r\n if (want(\"read\")) {\r\n instanceItem.get = {\r\n tags: [resource],\r\n summary: `Read a ${resource} resource by id`,\r\n operationId: `read${resource}`,\r\n responses: {\r\n \"200\": { description: `The ${resource} resource`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"update\")) {\r\n instanceItem.put = {\r\n tags: [resource],\r\n summary: `Update (or create) a ${resource} resource by id`,\r\n operationId: `update${resource}`,\r\n parameters: [\r\n {\r\n name: \"If-Match\",\r\n in: \"header\",\r\n required: false,\r\n description: \"Version-aware update: weak ETag of the version being updated\",\r\n schema: { type: \"string\" },\r\n },\r\n ],\r\n requestBody: { required: true, content: body() },\r\n responses: {\r\n \"200\": { description: `${resource} updated`, content: body() },\r\n \"201\": { description: `${resource} created`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"patch\")) {\r\n instanceItem.patch = {\r\n tags: [resource],\r\n summary: `Patch a ${resource} resource by id`,\r\n operationId: `patch${resource}`,\r\n requestBody: {\r\n required: true,\r\n content: {\r\n \"application/json-patch+json\": {\r\n schema: {\r\n type: \"array\",\r\n items: { type: \"object\", additionalProperties: true },\r\n description: \"JSON Patch operations (RFC 6902)\",\r\n },\r\n },\r\n },\r\n },\r\n responses: {\r\n \"200\": { description: `${resource} patched`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"delete\")) {\r\n instanceItem.delete = {\r\n tags: [resource],\r\n summary: `Delete a ${resource} resource by id`,\r\n operationId: `delete${resource}`,\r\n responses: { \"204\": { description: `${resource} deleted` }, ...errorResponses() },\r\n };\r\n }\r\n if (Object.keys(instanceItem).length > 0) {\r\n paths[`/${resource}/{id}`] = { parameters: [idParam()], ...instanceItem };\r\n }\r\n\r\n if (want(\"history-instance\")) {\r\n paths[`/${resource}/{id}/_history`] = {\r\n parameters: [idParam()],\r\n get: {\r\n tags: [resource],\r\n summary: `History of a ${resource} instance`,\r\n operationId: `history${resource}Instance`,\r\n parameters: historyParameters(),\r\n responses: {\r\n \"200\": { description: \"History bundle\", content: fhirContent(\"Bundle\") },\r\n ...errorResponses(),\r\n },\r\n },\r\n };\r\n }\r\n if (want(\"vread\")) {\r\n paths[`/${resource}/{id}/_history/{vid}`] = {\r\n parameters: [idParam(), idParameter(\"vid\", \"Version id of the resource\")],\r\n get: {\r\n tags: [resource],\r\n summary: `Read a specific version of a ${resource} resource`,\r\n operationId: `vread${resource}`,\r\n responses: {\r\n \"200\": { description: `The ${resource} resource version`, content: body() },\r\n ...errorResponses(),\r\n },\r\n },\r\n };\r\n }\r\n if (want(\"history-type\")) {\r\n paths[`/${resource}/_history`] = {\r\n get: {\r\n tags: [resource],\r\n summary: `History across all ${resource} resources`,\r\n operationId: `history${resource}Type`,\r\n parameters: historyParameters(),\r\n responses: {\r\n \"200\": { description: \"History bundle\", content: fhirContent(\"Bundle\") },\r\n ...errorResponses(),\r\n },\r\n },\r\n };\r\n }\r\n\r\n return paths;\r\n}\r\n","import { buildRegistryFromSchemaJson } from \"./backends/schemaJson.js\";\r\nimport { buildRegistryFromStructureDefinitions } from \"./backends/structureDefinition.js\";\r\nimport type { Capability, ResourceCapability } from \"./capability.js\";\r\nimport { convertSchema } from \"./emit/schema.js\";\r\nimport { loadIgSync, type IgContext } from \"./ig/package.js\";\r\nimport { applyProfile, buildCoreValueSetFallback } from \"./ig/profile.js\";\r\nimport { extractClosure, type DefinitionRegistry } from \"./ir/registry.js\";\r\nimport { buildOperationPaths } from \"./operations.js\";\r\nimport { buildResourcePaths, commonSearchParameterComponents } from \"./paths.js\";\r\nimport {\r\n FHIR_VERSION_NUMBERS,\r\n FHIR_VERSIONS,\r\n type FhirVersion,\r\n type GenerateOptions,\r\n type JsonSchemaNode,\r\n type OpenApiDocument,\r\n type SourceBackend,\r\n} from \"./types.js\";\r\n\r\nfunction buildRegistry(fhirVersion: FhirVersion, source: SourceBackend): DefinitionRegistry {\r\n return source === \"structure-def\"\r\n ? buildRegistryFromStructureDefinitions(fhirVersion)\r\n : buildRegistryFromSchemaJson(fhirVersion);\r\n}\r\n\r\nfunction resolveResourceName(registry: DefinitionRegistry, requested: string): string {\r\n const match = registry.resourceNames.find(\r\n (name) => name.toLowerCase() === requested.toLowerCase(),\r\n );\r\n if (!match) {\r\n throw new Error(\r\n `Unknown FHIR ${registry.fhirVersion.toUpperCase()} resource: \"${requested}\". ` +\r\n `Run \"fhir-oas list --fhir-version ${registry.fhirVersion}\" to see available resources.`,\r\n );\r\n }\r\n return match;\r\n}\r\n\r\n/** Lists the resource type names available for a FHIR version. */\r\nexport function listResources(\r\n fhirVersion: FhirVersion,\r\n source: SourceBackend = \"schema-json\",\r\n): string[] {\r\n assertFhirVersion(fhirVersion);\r\n return [...buildRegistry(fhirVersion, source).resourceNames].sort();\r\n}\r\n\r\nfunction assertFhirVersion(fhirVersion: string): asserts fhirVersion is FhirVersion {\r\n if (!FHIR_VERSIONS.includes(fhirVersion as FhirVersion)) {\r\n throw new Error(\r\n `Unsupported FHIR version \"${fhirVersion}\". Supported: ${FHIR_VERSIONS.join(\", \")}`,\r\n );\r\n }\r\n}\r\n\r\n/** The FHIR version a CapabilityStatement fhirVersion string belongs to. */\r\nfunction assertCapabilityFhirVersion(capability: Capability, fhirVersion: FhirVersion): void {\r\n const declared = capability.fhirVersion;\r\n if (!declared) return; // statement omitted it; trust the caller's --fhir-version\r\n const expectedMajor = FHIR_VERSION_NUMBERS[fhirVersion].split(\".\").slice(0, 2).join(\".\");\r\n // R4 (4.0.x) and R4B (4.3.x) share major 4 but differ in minor; compare the\r\n // major.minor prefix, tolerating the statement carrying only \"4.0\" etc.\r\n const declaredPrefix = declared.split(\".\").slice(0, 2).join(\".\");\r\n if (declaredPrefix && expectedMajor && declaredPrefix !== expectedMajor) {\r\n throw new Error(\r\n `CapabilityStatement targets FHIR ${declared}, but generation is for ` +\r\n `${fhirVersion.toUpperCase()} (${FHIR_VERSION_NUMBERS[fhirVersion]}). ` +\r\n `Set --fhir-version to match the server.`,\r\n );\r\n }\r\n}\r\n\r\n/** Resolves options.ig to an IgContext: a local path is loaded synchronously. */\r\nfunction resolveIg(options: GenerateOptions): IgContext {\r\n const ig = options.ig;\r\n if (!ig) throw new Error(\"--profile requires --ig: point at the IG package.\");\r\n if (typeof ig === \"string\") {\r\n return loadIgSync(ig, { coreValueSetFallback: buildCoreValueSetFallback(options.fhirVersion) });\r\n }\r\n return ig as IgContext;\r\n}\r\n\r\n/**\r\n * Generates an OpenAPI document covering the requested FHIR resources: their\r\n * full schema dependency closure plus the standard FHIR RESTful interactions.\r\n */\r\nexport function generateOpenApi(options: GenerateOptions): OpenApiDocument {\r\n assertFhirVersion(options.fhirVersion);\r\n const openApiVersion = options.openApiVersion ?? \"3.0.3\";\r\n if (openApiVersion !== \"3.0.3\" && openApiVersion !== \"3.1.0\") {\r\n throw new Error(`Unsupported OpenAPI version \"${openApiVersion}\". Supported: 3.0.3, 3.1.0`);\r\n }\r\n\r\n const registry = buildRegistry(options.fhirVersion, options.source ?? \"schema-json\");\r\n\r\n // A CapabilityStatement restricts generation to one server's declared\r\n // surface: which resources, interactions, search params, and operations.\r\n const capability = options.capability as Capability | undefined;\r\n const capabilityByResource = new Map<string, ResourceCapability>();\r\n if (capability) {\r\n assertCapabilityFhirVersion(capability, options.fhirVersion);\r\n for (const cap of capability.resources) {\r\n const match = registry.resourceNames.find(\r\n (name) => name.toLowerCase() === cap.type.toLowerCase(),\r\n );\r\n // Skip resource types the FHIR version doesn't define (custom/unknown).\r\n if (match) capabilityByResource.set(match, cap);\r\n }\r\n }\r\n\r\n const requested = (options.resources ?? []).map((r) => resolveResourceName(registry, r));\r\n if (requested.length === 0 && capabilityByResource.size === 0) {\r\n throw new Error(\r\n capability\r\n ? \"The CapabilityStatement declares no resources this FHIR version supports.\"\r\n : \"At least one FHIR resource name (or a --capability statement) is required\",\r\n );\r\n }\r\n\r\n // Apply IG profiles (if any) into the registry, mapping each profiled base\r\n // resource to its emitted schema name. The base resource is auto-included.\r\n const schemaByResource = new Map<string, string>();\r\n // In capability mode, the resource set is the statement's (optionally\r\n // narrowed to the explicitly requested ones); otherwise it's the requested.\r\n const resourceSet = new Set<string>(\r\n capability\r\n ? requested.length > 0\r\n ? requested.filter((r) => capabilityByResource.has(r))\r\n : [...capabilityByResource.keys()]\r\n : requested,\r\n );\r\n if (options.profiles?.length) {\r\n const ig = resolveIg(options);\r\n if (ig.fhirVersion !== options.fhirVersion) {\r\n throw new Error(\r\n `IG package \"${ig.name}\" targets FHIR ${ig.fhirVersion.toUpperCase()}, but generation ` +\r\n `is for ${options.fhirVersion.toUpperCase()}. Use --fhir-version ${ig.fhirVersion}.`,\r\n );\r\n }\r\n for (const profileId of options.profiles) {\r\n const applied = applyProfile(ig, profileId, registry);\r\n const base = resolveResourceName(registry, applied.resourceType);\r\n if (schemaByResource.has(base)) {\r\n throw new Error(\r\n `Multiple profiles target ${base}; generate one profiled resource per run.`,\r\n );\r\n }\r\n schemaByResource.set(base, applied.schemaName);\r\n resourceSet.add(base);\r\n }\r\n } else if (options.ig) {\r\n throw new Error(\"--ig requires --profile: name the profile(s) to apply.\");\r\n }\r\n\r\n const resources = [...resourceSet];\r\n const schemaFor = (resource: string) => schemaByResource.get(resource) ?? resource;\r\n\r\n // Operations: in capability mode, emit exactly the operations each resource\r\n // declares (mapped to known OperationDefinitions); otherwise --operations\r\n // emits every applicable operation.\r\n const operationPaths: Record<string, JsonSchemaNode> = {};\r\n const operationRoots: string[] = [];\r\n if (capability || options.operations) {\r\n const knownResources = new Set(registry.resourceNames);\r\n for (const resource of resources) {\r\n const cap = capabilityByResource.get(resource);\r\n if (capability && (!cap || cap.operations.size === 0)) continue;\r\n const result = buildOperationPaths(options.fhirVersion, resource, knownResources, {\r\n schemaFor,\r\n only: cap?.operations,\r\n });\r\n Object.assign(operationPaths, result.paths);\r\n operationRoots.push(...result.extraSchemaRoots);\r\n }\r\n }\r\n\r\n // Closure roots use the profiled schema name where a resource is profiled,\r\n // so the base schema is only emitted if something else references it.\r\n // Bundle and OperationOutcome are always present: search/history responses\r\n // are Bundles and every error response is an OperationOutcome.\r\n const roots = [\r\n ...new Set([...resources.map(schemaFor), \"Bundle\", \"OperationOutcome\", ...operationRoots]),\r\n ];\r\n const { schemas } = extractClosure(registry, roots, options.trim ?? {}, roots);\r\n\r\n const componentSchemas: Record<string, JsonSchemaNode> = {};\r\n const convertOptions = { noEnums: options.trim?.noEnums };\r\n for (const name of [...schemas.keys()].sort()) {\r\n componentSchemas[name] = convertSchema(schemas.get(name)!, openApiVersion, convertOptions);\r\n }\r\n\r\n const paths: Record<string, JsonSchemaNode> = {};\r\n for (const resource of resources) {\r\n const cap = capabilityByResource.get(resource);\r\n Object.assign(\r\n paths,\r\n buildResourcePaths(options.fhirVersion, resource, schemaFor(resource), {\r\n interactions: cap?.interactions,\r\n searchParamCodes: cap?.searchParamCodes,\r\n }),\r\n );\r\n }\r\n Object.assign(paths, operationPaths);\r\n\r\n const fhirNumber = FHIR_VERSION_NUMBERS[options.fhirVersion];\r\n const document: OpenApiDocument = {\r\n openapi: openApiVersion,\r\n info: {\r\n title:\r\n options.title ??\r\n `FHIR ${options.fhirVersion.toUpperCase()} REST API: ${resources.join(\", \")}`,\r\n description:\r\n `OpenAPI definition of the FHIR ${options.fhirVersion.toUpperCase()} (${fhirNumber}) ` +\r\n `RESTful interactions and JSON schemas for: ${resources.join(\", \")}. ` +\r\n \"Generated by fhir-openapi-translator from the official HL7 FHIR definitions. \" +\r\n \"Schema validity does not imply full FHIR conformance: profiles, terminology \" +\r\n \"bindings, and FHIRPath invariants are not represented.\",\r\n version: fhirNumber,\r\n },\r\n ...(options.baseUrl ? { servers: [{ url: options.baseUrl }] } : {}),\r\n tags: resources.map((resource) => ({\r\n name: resource,\r\n description: `Operations on the ${resource} resource`,\r\n })),\r\n paths,\r\n components: {\r\n parameters: commonSearchParameterComponents(),\r\n schemas: componentSchemas,\r\n },\r\n };\r\n return document;\r\n}\r\n","import fs from \"node:fs\";\r\nimport type { FhirInteraction } from \"./paths.js\";\r\n\r\n/**\r\n * Loads and parses a FHIR CapabilityStatement (a server's `/metadata`) into a\r\n * per-resource description of what the server actually supports, so a spec can\r\n * be generated to match exactly one server's surface rather than the full\r\n * standard interaction set.\r\n */\r\n\r\nexport interface ResourceCapability {\r\n type: string;\r\n interactions: Set<FhirInteraction>;\r\n /** Search parameter codes the server declares for this resource. */\r\n searchParamCodes: Set<string>;\r\n /** Operation codes and canonical URLs the server declares for this resource. */\r\n operations: Set<string>;\r\n}\r\n\r\nexport interface Capability {\r\n /** FHIR version string from the statement, e.g. \"4.0.1\" (may be undefined). */\r\n fhirVersion?: string;\r\n resources: ResourceCapability[];\r\n}\r\n\r\ninterface RawInteraction {\r\n code?: string;\r\n}\r\ninterface RawSearchParam {\r\n name?: string;\r\n}\r\ninterface RawOperation {\r\n name?: string;\r\n definition?: string;\r\n}\r\ninterface RawResource {\r\n type?: string;\r\n interaction?: RawInteraction[];\r\n searchParam?: RawSearchParam[];\r\n operation?: RawOperation[];\r\n}\r\ninterface RawCapabilityStatement {\r\n resourceType?: string;\r\n fhirVersion?: string;\r\n rest?: { mode?: string; resource?: RawResource[] }[];\r\n}\r\n\r\nconst KNOWN_INTERACTIONS = new Set<string>([\r\n \"read\",\r\n \"vread\",\r\n \"update\",\r\n \"patch\",\r\n \"delete\",\r\n \"history-instance\",\r\n \"history-type\",\r\n \"create\",\r\n \"search-type\",\r\n]);\r\n\r\nexport interface LoadCapabilityOptions {\r\n fetchImpl?: typeof fetch;\r\n}\r\n\r\n/**\r\n * Loads a CapabilityStatement from a local JSON file or an http(s) URL. A URL\r\n * that does not already end in `/metadata` has it appended, so a base server\r\n * URL works directly.\r\n */\r\nexport async function loadCapabilityStatement(\r\n input: string,\r\n options: LoadCapabilityOptions = {},\r\n): Promise<Capability> {\r\n let json: unknown;\r\n if (/^https?:\\/\\//i.test(input)) {\r\n const url = /\\/metadata\\/?$/.test(input) ? input : `${input.replace(/\\/$/, \"\")}/metadata`;\r\n const doFetch = options.fetchImpl ?? fetch;\r\n let response: Response;\r\n try {\r\n response = await doFetch(url, { headers: { Accept: \"application/fhir+json\" } });\r\n } catch (cause) {\r\n throw new Error(\r\n `Failed to fetch CapabilityStatement from ${url}: ${(cause as Error).message}. ` +\r\n `Save it locally (curl -H 'Accept: application/fhir+json' ${url} > metadata.json) ` +\r\n `and pass the file instead.`,\r\n );\r\n }\r\n if (!response.ok) {\r\n throw new Error(`CapabilityStatement request to ${url} returned ${response.status}.`);\r\n }\r\n json = await response.json();\r\n } else {\r\n if (!fs.existsSync(input)) throw new Error(`No such CapabilityStatement file: ${input}`);\r\n json = JSON.parse(fs.readFileSync(input, \"utf8\"));\r\n }\r\n return parseCapabilityStatement(json);\r\n}\r\n\r\nexport function parseCapabilityStatement(json: unknown): Capability {\r\n const statement = json as RawCapabilityStatement;\r\n if (statement?.resourceType !== \"CapabilityStatement\") {\r\n throw new Error(\r\n `Expected a CapabilityStatement resource, got \"${statement?.resourceType ?? \"unknown\"}\".`,\r\n );\r\n }\r\n\r\n // Merge resource entries across all `rest` blocks with mode \"server\".\r\n const byType = new Map<string, ResourceCapability>();\r\n for (const rest of statement.rest ?? []) {\r\n if (rest.mode && rest.mode !== \"server\") continue;\r\n for (const raw of rest.resource ?? []) {\r\n if (!raw.type) continue;\r\n let cap = byType.get(raw.type);\r\n if (!cap) {\r\n cap = {\r\n type: raw.type,\r\n interactions: new Set(),\r\n searchParamCodes: new Set(),\r\n operations: new Set(),\r\n };\r\n byType.set(raw.type, cap);\r\n }\r\n for (const i of raw.interaction ?? []) {\r\n if (i.code && KNOWN_INTERACTIONS.has(i.code)) cap.interactions.add(i.code as FhirInteraction);\r\n }\r\n for (const sp of raw.searchParam ?? []) {\r\n if (sp.name) cap.searchParamCodes.add(sp.name);\r\n }\r\n for (const op of raw.operation ?? []) {\r\n if (op.name) cap.operations.add(op.name);\r\n if (op.definition) cap.operations.add(op.definition);\r\n }\r\n }\r\n }\r\n\r\n if (byType.size === 0) {\r\n throw new Error(\r\n \"CapabilityStatement declares no server resources (rest[].resource). Nothing to generate.\",\r\n );\r\n }\r\n\r\n return {\r\n fhirVersion: statement.fhirVersion,\r\n resources: [...byType.values()].sort((a, b) => a.type.localeCompare(b.type)),\r\n };\r\n}\r\n","import { Document, parseDocument, isMap, type YAMLMap } from \"yaml\";\r\nimport type { OpenApiDocument } from \"./types.js\";\r\n\r\nexport interface MergeOptions {\r\n /** Overwrite conflicting entries instead of failing. */\r\n force?: boolean;\r\n}\r\n\r\nexport interface MergeConflict {\r\n /** e.g. \"components.schemas.Patient\" or \"paths./Patient/{id}\" */\r\n location: string;\r\n}\r\n\r\nexport class MergeConflictError extends Error {\r\n constructor(public readonly conflicts: MergeConflict[]) {\r\n super(\r\n \"Refusing to overwrite existing, differing entries (use --force to overwrite):\\n\" +\r\n conflicts.map((c) => ` - ${c.location}`).join(\"\\n\"),\r\n );\r\n this.name = \"MergeConflictError\";\r\n }\r\n}\r\n\r\n/** Top-level maps whose entries are merged key-by-key. */\r\nconst MERGED_SECTIONS: [string, string][] = [\r\n [\"paths\", \"\"],\r\n [\"components\", \"schemas\"],\r\n [\"components\", \"parameters\"],\r\n];\r\n\r\nfunction deepEqual(a: unknown, b: unknown): boolean {\r\n return JSON.stringify(a) === JSON.stringify(b);\r\n}\r\n\r\n/**\r\n * `ResourceList` is narrowed to the resource types requested at generation\r\n * time (see ir/registry.ts), so two generated specs legitimately differ in\r\n * it. Merging unions the two narrowings instead of conflicting. Returns\r\n * undefined when either side is not the expected oneOf-of-$refs shape.\r\n */\r\nfunction unionResourceList(existing: unknown, generated: unknown): unknown | undefined {\r\n const refsOf = (node: unknown): string[] | undefined => {\r\n if (!node || typeof node !== \"object\" || Array.isArray(node)) return undefined;\r\n const oneOf = (node as { oneOf?: unknown }).oneOf;\r\n if (!Array.isArray(oneOf)) return undefined;\r\n const refs: string[] = [];\r\n for (const item of oneOf) {\r\n if (!item || typeof item !== \"object\" || Object.keys(item).length !== 1) return undefined;\r\n const ref = (item as { $ref?: unknown }).$ref;\r\n if (typeof ref !== \"string\") return undefined;\r\n refs.push(ref);\r\n }\r\n return refs;\r\n };\r\n const existingRefs = refsOf(existing);\r\n const generatedRefs = refsOf(generated);\r\n if (!existingRefs || !generatedRefs) return undefined;\r\n return {\r\n ...(generated as Record<string, unknown>),\r\n oneOf: [...new Set([...existingRefs, ...generatedRefs])].map(($ref) => ({ $ref })),\r\n };\r\n}\r\n\r\ninterface MergePlan {\r\n doc: ReturnType<typeof parseDocument>;\r\n conflicts: MergeConflict[];\r\n additions: { path: (string | number)[]; value: unknown }[];\r\n}\r\n\r\n/**\r\n * Parses the existing YAML and computes what a merge would do: entries to add\r\n * (absent from the file, or ResourceList unions) and conflicting entries\r\n * (present with different content). Shared by merge and check.\r\n */\r\nfunction computeMergePlan(\r\n generated: OpenApiDocument,\r\n existingText: string,\r\n options: MergeOptions,\r\n): MergePlan {\r\n const doc = parseDocument(existingText);\r\n if (doc.errors.length > 0) {\r\n throw new Error(`Cannot parse existing YAML: ${doc.errors[0]?.message}`);\r\n }\r\n if (doc.contents !== null && !isMap(doc.contents)) {\r\n throw new Error(\"Existing file is not a YAML mapping; refusing to merge\");\r\n }\r\n\r\n const existingVersion = doc.getIn([\"openapi\"]);\r\n const generatedVersion = generated.openapi;\r\n if (existingVersion !== undefined && String(existingVersion) !== String(generatedVersion)) {\r\n throw new Error(\r\n `OpenAPI version mismatch: existing file declares ${String(existingVersion)}, ` +\r\n `generating ${String(generatedVersion)}. Regenerate with a matching --openapi-version.`,\r\n );\r\n }\r\n\r\n const conflicts: MergeConflict[] = [];\r\n const additions: { path: (string | number)[]; value: unknown }[] = [];\r\n\r\n // Top-level scalars/objects that only apply when absent.\r\n for (const key of [\"openapi\", \"info\", \"servers\"]) {\r\n if (generated[key] !== undefined && doc.getIn([key]) === undefined) {\r\n additions.push({ path: [key], value: generated[key] });\r\n }\r\n }\r\n\r\n // Tags: append missing tag names.\r\n const generatedTags = (generated.tags ?? []) as { name: string }[];\r\n if (generatedTags.length > 0) {\r\n const existingTags = doc.toJS()?.tags as { name: string }[] | undefined;\r\n if (existingTags === undefined) {\r\n additions.push({ path: [\"tags\"], value: generatedTags });\r\n } else {\r\n const existingNames = new Set(existingTags.map((t) => t?.name));\r\n let index = existingTags.length;\r\n for (const tag of generatedTags) {\r\n if (!existingNames.has(tag.name)) {\r\n additions.push({ path: [\"tags\", index++], value: tag });\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (const [section, subsection] of MERGED_SECTIONS) {\r\n const generatedSection = subsection\r\n ? ((generated[section] as Record<string, unknown> | undefined)?.[subsection] as\r\n | Record<string, unknown>\r\n | undefined)\r\n : (generated[section] as Record<string, unknown> | undefined);\r\n if (!generatedSection) continue;\r\n const basePath = subsection ? [section, subsection] : [section];\r\n\r\n for (const [key, value] of Object.entries(generatedSection)) {\r\n const existing = doc.getIn([...basePath, key], true);\r\n if (existing === undefined) {\r\n additions.push({ path: [...basePath, key], value });\r\n } else {\r\n const existingJs =\r\n typeof (existing as YAMLMap)?.toJS === \"function\"\r\n ? (existing as YAMLMap).toJS(doc)\r\n : existing;\r\n if (!deepEqual(existingJs, value)) {\r\n if (section === \"components\" && subsection === \"schemas\" && key === \"ResourceList\") {\r\n const union = unionResourceList(existingJs, value);\r\n if (union !== undefined) {\r\n if (!deepEqual(existingJs, union)) {\r\n additions.push({ path: [...basePath, key], value: union });\r\n }\r\n continue;\r\n }\r\n }\r\n conflicts.push({ location: [...basePath, key].join(\".\") });\r\n if (options.force) additions.push({ path: [...basePath, key], value });\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { doc, conflicts, additions };\r\n}\r\n\r\n/**\r\n * Merges a generated OpenAPI document into existing YAML text, preserving the\r\n * existing file's comments, anchors, and key order. Generated entries are\r\n * added alongside existing content; an existing entry with different content\r\n * is a conflict (all conflicts are reported; nothing is written unless every\r\n * conflict is resolved by `force`). Identical entries are left untouched, so\r\n * re-running the generator is idempotent.\r\n */\r\nexport function mergeIntoYaml(\r\n generated: OpenApiDocument,\r\n existingText: string,\r\n options: MergeOptions = {},\r\n): string {\r\n const { doc, conflicts, additions } = computeMergePlan(generated, existingText, options);\r\n if (doc.contents === null) {\r\n // Empty file: treat as a fresh write.\r\n return stringifyDocument(generated);\r\n }\r\n if (conflicts.length > 0 && !options.force) {\r\n throw new MergeConflictError(conflicts);\r\n }\r\n for (const { path, value } of additions) {\r\n doc.setIn(path, doc.createNode(value));\r\n }\r\n return doc.toString({ lineWidth: 0 });\r\n}\r\n\r\nexport interface SpecDiff {\r\n /** Entries the file lacks (dot paths), e.g. \"components.schemas.Patient\". */\r\n missing: string[];\r\n /** Entries present in the file but differing from generation. */\r\n changed: string[];\r\n /** True when the file already contains exactly what generation produces. */\r\n inSync: boolean;\r\n}\r\n\r\n/**\r\n * Compares existing spec text against a generated document without writing\r\n * anything — the CI drift guard behind `fhir-oas check`. The file is in sync\r\n * when a merge would be a no-op: nothing to add, nothing conflicting.\r\n */\r\nexport function diffAgainstYaml(generated: OpenApiDocument, existingText: string): SpecDiff {\r\n const { doc, conflicts, additions } = computeMergePlan(generated, existingText, {});\r\n if (doc.contents === null) {\r\n return { missing: [\"(entire document: file is empty)\"], changed: [], inSync: false };\r\n }\r\n const missing = additions.map((a) => a.path.join(\".\"));\r\n const changed = conflicts.map((c) => c.location);\r\n return { missing, changed, inSync: missing.length === 0 && changed.length === 0 };\r\n}\r\n\r\n/** Serializes a generated document to YAML text. */\r\nexport function stringifyDocument(generated: OpenApiDocument): string {\r\n const doc = new Document(generated);\r\n return doc.toString({ lineWidth: 0 });\r\n}\r\n"],"mappings":"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","names":["fs","path","path","ref","FHIR_JSON","SCHEMAS","ref","fhirContent","errorResponses","fhirContent","errorResponses","fs","ref","path"]}
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  loadIg,
10
10
  mergeIntoYaml,
11
11
  stringifyDocument
12
- } from "./chunk-G3DCRADV.js";
12
+ } from "./chunk-RR46JDST.js";
13
13
 
14
14
  // src/cli.ts
15
15
  import { Command, Option } from "commander";
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  mergeIntoYaml,
12
12
  parseCapabilityStatement,
13
13
  stringifyDocument
14
- } from "./chunk-G3DCRADV.js";
14
+ } from "./chunk-RR46JDST.js";
15
15
  export {
16
16
  FHIR_VERSIONS,
17
17
  FHIR_VERSION_NUMBERS,
package/docs/REFERENCE.md CHANGED
@@ -159,10 +159,20 @@ Given `--ig <package> --profile <id>`, the profile snapshot is turned into a sch
159
159
  | `max: "0"` | property omitted |
160
160
  | `max: "1"` on a base array | scalar instead of array |
161
161
  | required binding, resolvable ValueSet (IG-local, then vendored core; ≤150 codes) | inline `enum` |
162
- | `fixed[x]` | `const` (3.1) / single-value `enum` (3.0.3) |
162
+ | `fixed[x]` on an element emitted as its own property | `const` (3.1) / single-value `enum` (3.0.3) |
163
+ | `fixed[x]` **inside** a datatype or slice (e.g. `Observation.category.coding.code`) | *not applied* — see below |
163
164
  | choice-type narrowing | only the permitted `value[x]` expansions emitted |
164
165
  | `pattern[x]`, slicing, invariants, must-support | *not enforced* — noted in `description` + `x-fhir-constraints-omitted` |
165
166
 
167
+ Note on `fixed[x]`: real IGs usually pin values at paths *inside* a datatype
168
+ (`Observation.category.coding.code`) or inside a slice, rather than on a
169
+ resource element directly. Those datatypes are emitted once as shared schemas
170
+ and referenced with `$ref`, so a constraint that applies to one profile's use
171
+ of `CodeableConcept` cannot be written into the shared `CodeableConcept`
172
+ schema. Such fixed values are therefore **not** represented — US Core Blood
173
+ Pressure, for example, declares six and none appear as `const`. Only fixed
174
+ values on elements the profile emits as their own property are applied.
175
+
166
176
  The IG package is a local `.tgz` / unpacked directory, or a `name@version` coordinate fetched from `packages.fhir.org` and cached under `~/.fhir-oas/packages`. Profiles must ship a snapshot (differential-only packages error); the package FHIR version must match `--fhir-version`; only the public registry is supported (no auth).
167
177
 
168
178
  ## Assumptions and known limitations
@@ -174,6 +184,7 @@ The IG package is a local `.tgz` / unpacked directory, or a `name@version` coord
174
184
  - Operations are resource-scoped only: system-level operations (`GET /$export`-style, `$convert`, ...), `POST /_search`, batch/transaction semantics, and conditional headers beyond `If-Match` are not modeled. Multi-part operation parameters collapse to a generic `Parameters` body.
175
185
  - `--capability` reflects a server's *declared* surface: resource types the FHIR version doesn't define are skipped, and declared operations are emitted only when they map to a known OperationDefinition (system-level interactions like transaction/batch are not modeled). It restricts what's generated; it does not verify the server actually behaves as declared.
176
186
  - The two definition backends can differ cosmetically (e.g. naming of deeply nested backbone elements, primitive regex patterns); `schema-json` is the default and the reference.
187
+ - They also differ on one thing that is **not** cosmetic: **mandatory primitive elements**. `structure-def` marks them `required` (the StructureDefinition says `min: 1`), while `schema-json` does not, because the official `fhir.schema.json` omits them — a FHIR primitive may legitimately appear as only its `_element` extension sibling (e.g. carrying a `dataAbsentReason`), so the JSON property itself is not strictly required. `Observation.status` is the canonical example: required under `structure-def`, optional under `schema-json`. Mandatory *complex* elements (`Observation.code`) are required under both. Pick `structure-def` if you want stricter generated models.
177
188
 
178
189
  ## Development
179
190
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fhir-openapi-translator",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Generate an OpenAPI (Swagger) spec for any FHIR resource (R4/R4B/R5) — for typed model & client codegen in any language. Supports US Core profiles, operations, and CapabilityStatements.",
5
5
  "keywords": [
6
6
  "fhir",
@@ -49,7 +49,8 @@
49
49
  "files": [
50
50
  "dist",
51
51
  "definitions",
52
- "docs"
52
+ "docs",
53
+ "CHANGELOG.md"
53
54
  ],
54
55
  "scripts": {
55
56
  "build": "tsup",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types.ts","../src/ig/package.ts","../src/ig/minimize.ts","../src/definitions.ts","../src/ir/structureWalker.ts","../src/ig/profile.ts","../src/backends/schemaJson.ts","../src/backends/structureDefinition.ts","../src/emit/schema.ts","../src/ir/registry.ts","../src/operations.ts","../src/paths.ts","../src/generate.ts","../src/capability.ts","../src/merge.ts"],"sourcesContent":["export type FhirVersion = \"r4\" | \"r4b\" | \"r5\";\r\n\r\nexport const FHIR_VERSIONS: readonly FhirVersion[] = [\"r4\", \"r4b\", \"r5\"];\r\n\r\nexport const FHIR_VERSION_NUMBERS: Record<FhirVersion, string> = {\r\n r4: \"4.0.1\",\r\n r4b: \"4.3.0\",\r\n r5: \"5.0.0\",\r\n};\r\n\r\nexport type OpenApiVersion = \"3.0.3\" | \"3.1.0\";\r\n\r\nexport type SourceBackend = \"schema-json\" | \"structure-def\";\r\n\r\nexport interface TrimOptions {\r\n /**\r\n * Replace the Narrative type (human-readable HTML in `Resource.text`) with a\r\n * generic object. Shrinks generated models that never render narratives.\r\n */\r\n excludeNarrative?: boolean;\r\n /**\r\n * Stub out schema definitions first reached deeper than this many hops from\r\n * a requested resource with a generic object. Bounds the size of the\r\n * dependency closure for codegen targets that struggle with large graphs.\r\n */\r\n maxDepth?: number;\r\n /**\r\n * Replace required-binding enums on code fields with plain strings (the\r\n * allowed codes are appended to the description). Codegen'd models then\r\n * tolerate servers that return codes outside the strict ValueSet — a common\r\n * reality with legacy data. `resourceType` discriminators keep their enum.\r\n */\r\n noEnums?: boolean;\r\n}\r\n\r\n/** An IG package resolved to profiles + terminology (see ig/package.ts). */\r\nexport interface IgContextLike {\r\n name: string;\r\n version: string;\r\n fhirVersion: FhirVersion;\r\n profiles: unknown[];\r\n profilesMissingSnapshot: string[];\r\n resolveValueSet: (valueSetUrl: string) => string[] | undefined;\r\n}\r\n\r\n/** A parsed CapabilityStatement (see capability.ts). */\r\nexport interface CapabilityLike {\r\n fhirVersion?: string;\r\n resources: {\r\n type: string;\r\n interactions: Set<string>;\r\n searchParamCodes: Set<string>;\r\n operations: Set<string>;\r\n }[];\r\n}\r\n\r\nexport interface GenerateOptions {\r\n /**\r\n * FHIR resource names, e.g. [\"Patient\", \"Observation\"]. Optional when a\r\n * `capability` statement is given (its declared resources are used); when\r\n * both are set, generation is narrowed to the requested resources.\r\n */\r\n resources?: string[];\r\n fhirVersion: FhirVersion;\r\n /**\r\n * A parsed CapabilityStatement restricting generation to one server's\r\n * declared support (resources, interactions, search params, operations).\r\n * Use `loadCapabilityStatement` / `parseCapabilityStatement` to build it.\r\n */\r\n capability?: CapabilityLike;\r\n /**\r\n * IG package to apply profiles from: a local path (`.tgz` or unpacked\r\n * directory) loaded synchronously, or a pre-resolved IgContext (use the\r\n * async `loadIg` for registry coordinates). Required when `profiles` is set.\r\n */\r\n ig?: string | IgContextLike;\r\n /**\r\n * Profile ids, names, or canonical URLs to apply to their base resources.\r\n * Each profiled resource's schemas/paths reference the named profile schema.\r\n */\r\n profiles?: string[];\r\n /** Target OpenAPI version. Default: \"3.0.3\" (widest codegen support). */\r\n openApiVersion?: OpenApiVersion;\r\n /** Definition source backend. Default: \"schema-json\". */\r\n source?: SourceBackend;\r\n /**\r\n * Also emit the standard FHIR operations applicable to the requested\r\n * resources ($everything, $validate, ...) from the official\r\n * OperationDefinitions. Default: false.\r\n */\r\n operations?: boolean;\r\n /** Server base URL for the `servers` entry. Omitted when not given. */\r\n baseUrl?: string;\r\n /** Override the generated `info.title`. */\r\n title?: string;\r\n trim?: TrimOptions;\r\n}\r\n\r\n/** A JSON-Schema-like node. Kept loose: definitions come from vendored files. */\r\nexport type JsonSchemaNode = { [key: string]: unknown };\r\n\r\n/** A generated OpenAPI document (3.0.3 or 3.1.0) as a plain object. */\r\nexport type OpenApiDocument = { [key: string]: unknown };\r\n","import { execFileSync } from \"node:child_process\";\r\nimport fs from \"node:fs\";\r\nimport os from \"node:os\";\r\nimport path from \"node:path\";\r\nimport {\r\n buildValueSetResolver,\r\n minimizeStructureDefinition,\r\n type RawStructureDefinition,\r\n type ValueSetResolver,\r\n} from \"./minimize.js\";\r\nimport type { MinStructureDefinition } from \"../definitions.js\";\r\nimport { FHIR_VERSIONS, type FhirVersion } from \"../types.js\";\r\n\r\n/** Maps an IG package's FHIR version string to our supported version keys. */\r\nconst FHIR_VERSION_BY_NUMBER: Record<string, FhirVersion> = {\r\n \"4.0.1\": \"r4\",\r\n \"4.0.0\": \"r4\",\r\n \"4.3.0\": \"r4b\",\r\n \"5.0.0\": \"r5\",\r\n};\r\n\r\nexport interface IgProfile {\r\n /** Versionless canonical URL. */\r\n url: string;\r\n id?: string;\r\n name: string;\r\n type: string;\r\n definition: MinStructureDefinition;\r\n}\r\n\r\nexport interface IgContext {\r\n name: string;\r\n version: string;\r\n fhirVersion: FhirVersion;\r\n profiles: IgProfile[];\r\n /** Names/URLs of constraint profiles that lack a snapshot (cannot be applied). */\r\n profilesMissingSnapshot: string[];\r\n resolveValueSet: ValueSetResolver;\r\n}\r\n\r\nexport interface LoadIgOptions {\r\n /** Resolve core bindings (e.g. administrative-gender) not defined in the IG. */\r\n coreValueSetFallback?: ValueSetResolver;\r\n /** Base directory for the registry download cache. Defaults to ~/.fhir-oas. */\r\n cacheDir?: string;\r\n fetchImpl?: typeof fetch;\r\n}\r\n\r\ninterface RawResource {\r\n resourceType?: string;\r\n url?: string;\r\n name?: string;\r\n id?: string;\r\n type?: string;\r\n kind?: string;\r\n derivation?: string;\r\n snapshot?: unknown;\r\n [key: string]: unknown;\r\n}\r\n\r\nconst REGISTRY_BASE = \"https://packages.fhir.org\";\r\n\r\n/**\r\n * Resolves the `--ig` input to an IgContext. Accepts a path to a package\r\n * tarball (`.tgz`), a path to an unpacked package directory, or a registry\r\n * coordinate (`name` or `name@version`) fetched from packages.fhir.org and\r\n * cached locally. Async because registry coordinates hit the network.\r\n */\r\nexport async function loadIg(input: string, options: LoadIgOptions = {}): Promise<IgContext> {\r\n if (isRegistryCoordinate(input)) {\r\n const tarball = await fetchFromRegistry(input, options);\r\n return buildContext(readFromTarball(tarball), options.coreValueSetFallback);\r\n }\r\n return loadIgSync(input, options);\r\n}\r\n\r\n/**\r\n * Synchronous IG loader for local inputs (a `.tgz` or an unpacked directory).\r\n * Registry coordinates require the async {@link loadIg} because they fetch\r\n * over the network.\r\n */\r\nexport function loadIgSync(input: string, options: LoadIgOptions = {}): IgContext {\r\n if (isRegistryCoordinate(input)) {\r\n throw new Error(\r\n `\"${input}\" looks like a registry package coordinate, which requires a network ` +\r\n `fetch. Use loadIg() (async) or the CLI, or download the package and pass a local path.`,\r\n );\r\n }\r\n const stat = fs.existsSync(input) ? fs.statSync(input) : undefined;\r\n if (!stat) {\r\n throw new Error(\r\n `--ig \"${input}\" is not a file or directory. Pass a package .tgz, an unpacked ` +\r\n `package directory, or a registry coordinate like hl7.fhir.us.core@5.0.1.`,\r\n );\r\n }\r\n const files = stat.isDirectory() ? readFromDirectory(input) : readFromTarball(input);\r\n return buildContext(files, options.coreValueSetFallback);\r\n}\r\n\r\n/** package.json plus every FHIR JSON resource, keyed by base filename. */\r\ninterface PackageFiles {\r\n packageJson: { name?: string; version?: string; \"fhir-version-list\"?: string[]; fhirVersions?: string[] };\r\n resources: RawResource[];\r\n}\r\n\r\nfunction isRegistryCoordinate(input: string): boolean {\r\n // A registry coordinate is a package id (optionally @version); it never\r\n // looks like a path and does not exist on disk.\r\n if (fs.existsSync(input)) return false;\r\n if (input.includes(\"/\") || input.includes(\"\\\\\") || input.endsWith(\".tgz\")) return false;\r\n return /^[a-z0-9][a-z0-9.\\-]*(@[\\w.\\-]+)?$/i.test(input);\r\n}\r\n\r\nfunction packageDir(root: string): string {\r\n const nested = path.join(root, \"package\");\r\n if (fs.existsSync(path.join(nested, \"package.json\"))) return nested;\r\n if (fs.existsSync(path.join(root, \"package.json\"))) return root;\r\n throw new Error(`No package.json found under \"${root}\" (looked in ./ and ./package)`);\r\n}\r\n\r\nfunction readFromDirectory(dir: string): PackageFiles {\r\n const base = packageDir(dir);\r\n const packageJson = JSON.parse(fs.readFileSync(path.join(base, \"package.json\"), \"utf8\"));\r\n const resources: RawResource[] = [];\r\n for (const file of fs.readdirSync(base).sort()) {\r\n if (!file.endsWith(\".json\") || file === \"package.json\" || file === \".index.json\") continue;\r\n try {\r\n resources.push(JSON.parse(fs.readFileSync(path.join(base, file), \"utf8\")));\r\n } catch {\r\n // Skip non-resource JSON (e.g. index files that aren't FHIR resources).\r\n }\r\n }\r\n return { packageJson, resources };\r\n}\r\n\r\n/**\r\n * Extracts a package tarball to an isolated temp directory (tar refuses\r\n * absolute/`..` members, and the destination is a private mkdtemp), reads the\r\n * JSON resources, then removes the directory.\r\n */\r\nfunction readFromTarball(tarballPath: string): PackageFiles {\r\n if (!fs.existsSync(tarballPath)) {\r\n throw new Error(`Package tarball not found: ${tarballPath}`);\r\n }\r\n const tmp = fs.mkdtempSync(path.join(os.tmpdir(), \"fhir-oas-ig-\"));\r\n try {\r\n execFileSync(\"tar\", [\"-xzf\", tarballPath, \"-C\", tmp], { stdio: \"pipe\" });\r\n return readFromDirectory(tmp);\r\n } finally {\r\n fs.rmSync(tmp, { recursive: true, force: true });\r\n }\r\n}\r\n\r\nasync function fetchFromRegistry(coordinate: string, options: LoadIgOptions): Promise<string> {\r\n const [name, version] = coordinate.split(\"@\");\r\n const cacheDir = path.join(options.cacheDir ?? path.join(os.homedir(), \".fhir-oas\"), \"packages\");\r\n const resolvedVersion = version ?? \"latest\";\r\n const cachePath = path.join(cacheDir, `${name}#${resolvedVersion}.tgz`);\r\n if (fs.existsSync(cachePath)) return cachePath;\r\n\r\n const url = `${REGISTRY_BASE}/${name}/${resolvedVersion}`;\r\n const doFetch = options.fetchImpl ?? fetch;\r\n let response: Response;\r\n try {\r\n response = await doFetch(url);\r\n } catch (cause) {\r\n throw new Error(\r\n `Failed to reach the FHIR package registry at ${url}: ${(cause as Error).message}. ` +\r\n `If you are offline or behind a restrictive proxy, download the package and pass ` +\r\n `--ig ./${name}.tgz instead.`,\r\n );\r\n }\r\n if (!response.ok) {\r\n throw new Error(\r\n `FHIR package registry returned ${response.status} for ${url}. ` +\r\n `Check the package name and version, or download it and pass --ig ./${name}.tgz.`,\r\n );\r\n }\r\n const buffer = Buffer.from(await response.arrayBuffer());\r\n fs.mkdirSync(cacheDir, { recursive: true });\r\n fs.writeFileSync(cachePath, buffer);\r\n return cachePath;\r\n}\r\n\r\nfunction detectFhirVersion(packageJson: PackageFiles[\"packageJson\"]): FhirVersion {\r\n const versions = packageJson[\"fhir-version-list\"] ?? packageJson.fhirVersions ?? [];\r\n for (const v of versions) {\r\n const mapped = FHIR_VERSION_BY_NUMBER[v];\r\n if (mapped) return mapped;\r\n }\r\n throw new Error(\r\n `Could not determine a supported FHIR version for IG package \"${packageJson.name}\" ` +\r\n `(found: ${versions.join(\", \") || \"none\"}). Supported: ${FHIR_VERSIONS.join(\", \")}.`,\r\n );\r\n}\r\n\r\nfunction buildContext(files: PackageFiles, coreFallback?: ValueSetResolver): IgContext {\r\n const fhirVersion = detectFhirVersion(files.packageJson);\r\n const terminology = files.resources.filter(\r\n (r) => r.resourceType === \"ValueSet\" || r.resourceType === \"CodeSystem\",\r\n );\r\n const resolveValueSet = buildValueSetResolver(terminology as never[], coreFallback);\r\n\r\n const profiles: IgProfile[] = [];\r\n const profilesMissingSnapshot: string[] = [];\r\n for (const r of files.resources) {\r\n if (\r\n r.resourceType === \"StructureDefinition\" &&\r\n r.derivation === \"constraint\" &&\r\n r.kind === \"resource\"\r\n ) {\r\n if (!r.snapshot) {\r\n profilesMissingSnapshot.push(r.name ?? r.url ?? \"unknown\");\r\n continue;\r\n }\r\n const sd = r as unknown as RawStructureDefinition;\r\n profiles.push({\r\n url: sd.url.split(\"|\")[0]!,\r\n id: sd.id,\r\n name: sd.name,\r\n type: sd.type,\r\n definition: minimizeStructureDefinition(sd, resolveValueSet),\r\n });\r\n }\r\n }\r\n profiles.sort((a, b) => a.url.localeCompare(b.url));\r\n\r\n return {\r\n name: files.packageJson.name ?? \"unknown\",\r\n version: files.packageJson.version ?? \"unknown\",\r\n fhirVersion,\r\n profiles,\r\n profilesMissingSnapshot,\r\n resolveValueSet,\r\n };\r\n}\r\n","import type { MinElement, MinElementType, MinStructureDefinition } from \"../definitions.js\";\r\n\r\n/**\r\n * Minimizes raw FHIR StructureDefinition / terminology resources loaded from\r\n * an IG package into the same `MinStructureDefinition` shape the vendored core\r\n * definitions use, so profile snapshots feed the shared structure walker.\r\n *\r\n * This mirrors the element-minimizing shape in scripts/update-definitions.mjs\r\n * (which vendors the core packages at build time). The two are kept separate\r\n * on purpose: this one runs at generation time on arbitrary IG packages and\r\n * additionally captures profile constraints (`fixed[x]`, `mustSupport`,\r\n * unenforced `pattern`/slicing), which the base definitions never need.\r\n */\r\n\r\n/** Above this size an enum stops helping codegen and starts hurting it. */\r\nconst MAX_ENUM_CODES = 150;\r\n\r\ninterface RawElement {\r\n path: string;\r\n min?: number;\r\n max?: string;\r\n short?: string;\r\n definition?: string;\r\n contentReference?: string;\r\n mustSupport?: boolean;\r\n slicing?: unknown;\r\n sliceName?: string;\r\n type?: { code: string; targetProfile?: string[]; extension?: RawExtension[] }[];\r\n binding?: { strength?: string; valueSet?: string };\r\n [key: string]: unknown;\r\n}\r\n\r\ninterface RawExtension {\r\n url: string;\r\n valueUrl?: string;\r\n}\r\n\r\nexport interface RawStructureDefinition {\r\n resourceType: string;\r\n name: string;\r\n id?: string;\r\n url: string;\r\n kind: string;\r\n type: string;\r\n abstract?: boolean;\r\n derivation?: string;\r\n baseDefinition?: string;\r\n fhirVersion?: string;\r\n snapshot?: { element: RawElement[] };\r\n}\r\n\r\nexport type ValueSetResolver = (valueSetUrl: string) => string[] | undefined;\r\n\r\nconst FHIR_TYPE_EXTENSION =\r\n \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\";\r\n\r\n/** Extracts the normalized `fixed[x]` value from a snapshot element, if any. */\r\nfunction fixedValue(el: RawElement): unknown {\r\n for (const key of Object.keys(el)) {\r\n if (key.startsWith(\"fixed\") && key.length > 5) return el[key];\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction omittedConstraints(el: RawElement): string[] | undefined {\r\n const notes: string[] = [];\r\n if (el.slicing || el.sliceName) notes.push(\"slicing\");\r\n if (Object.keys(el).some((k) => k.startsWith(\"pattern\") && k.length > 7)) {\r\n notes.push(\"pattern\");\r\n }\r\n return notes.length > 0 ? notes : undefined;\r\n}\r\n\r\nfunction minimizeElement(el: RawElement, resolveValueSet?: ValueSetResolver): MinElement {\r\n const out: MinElement = { path: el.path, min: el.min ?? 0, max: el.max ?? \"*\" };\r\n if (el.short) out.short = el.short;\r\n if (el.definition) out.definition = el.definition;\r\n if (el.contentReference) out.contentReference = el.contentReference;\r\n if (el.type) {\r\n out.types = el.type.map((t) => {\r\n const type: MinElementType = { code: t.code };\r\n if (t.targetProfile) type.targetProfile = t.targetProfile;\r\n const fhirType = (t.extension ?? []).find((e) => e.url === FHIR_TYPE_EXTENSION);\r\n if (fhirType?.valueUrl) type.fhirType = fhirType.valueUrl;\r\n return type;\r\n });\r\n }\r\n if (el.binding?.strength === \"required\" && el.binding.valueSet) {\r\n out.binding = { strength: el.binding.strength, valueSet: el.binding.valueSet };\r\n const codes = resolveValueSet?.(el.binding.valueSet);\r\n if (codes) out.binding.codes = [...codes].sort();\r\n }\r\n const fixed = fixedValue(el);\r\n if (fixed !== undefined) out.fixed = fixed;\r\n if (el.mustSupport) out.mustSupport = true;\r\n const omitted = omittedConstraints(el);\r\n if (omitted) out.omittedConstraints = omitted;\r\n return out;\r\n}\r\n\r\nexport function minimizeStructureDefinition(\r\n sd: RawStructureDefinition,\r\n resolveValueSet?: ValueSetResolver,\r\n): MinStructureDefinition {\r\n return {\r\n name: sd.name,\r\n url: sd.url,\r\n kind: sd.kind as MinStructureDefinition[\"kind\"],\r\n type: sd.type,\r\n abstract: !!sd.abstract,\r\n baseDefinition: sd.baseDefinition,\r\n elements: (sd.snapshot?.element ?? []).map((el) => minimizeElement(el, resolveValueSet)),\r\n };\r\n}\r\n\r\ninterface RawValueSet {\r\n resourceType: string;\r\n url?: string;\r\n compose?: {\r\n include?: RawValueSetGroup[];\r\n exclude?: RawValueSetGroup[];\r\n };\r\n}\r\n\r\ninterface RawValueSetGroup {\r\n system?: string;\r\n concept?: { code: string }[];\r\n filter?: unknown[];\r\n valueSet?: string[];\r\n}\r\n\r\ninterface RawCodeSystem {\r\n resourceType: string;\r\n url?: string;\r\n content?: string;\r\n concept?: RawConcept[];\r\n}\r\n\r\ninterface RawConcept {\r\n code: string;\r\n concept?: RawConcept[];\r\n}\r\n\r\n/**\r\n * Builds a ValueSet URL -> flat code list resolver from the ValueSet and\r\n * CodeSystem resources available (IG-local plus, optionally, a fallback for\r\n * the vendored core terminology). Only simple composes are resolved; anything\r\n * with filters or valueSet imports is left unresolved, so the binding stays a\r\n * plain code — exactly the core behavior.\r\n */\r\nexport function buildValueSetResolver(\r\n resources: (RawValueSet | RawCodeSystem)[],\r\n fallback?: ValueSetResolver,\r\n): ValueSetResolver {\r\n const codeSystems = new Map<string, RawCodeSystem>();\r\n const valueSets = new Map<string, RawValueSet>();\r\n for (const r of resources) {\r\n if (r.resourceType === \"CodeSystem\" && r.url) codeSystems.set(r.url, r as RawCodeSystem);\r\n if (r.resourceType === \"ValueSet\" && r.url) valueSets.set(r.url, r as RawValueSet);\r\n }\r\n\r\n function conceptCodes(concepts: RawConcept[] | undefined, out: string[]): string[] {\r\n for (const c of concepts ?? []) {\r\n out.push(c.code);\r\n if (c.concept) conceptCodes(c.concept, out);\r\n }\r\n return out;\r\n }\r\n\r\n function resolveGroup(group: RawValueSetGroup): string[] | undefined {\r\n if (group.filter?.length || group.valueSet?.length) return undefined;\r\n if (group.concept?.length) return group.concept.map((c) => c.code);\r\n if (!group.system) return undefined;\r\n const cs = codeSystems.get(group.system);\r\n if (!cs || cs.content === \"not-present\" || !cs.concept) return undefined;\r\n return conceptCodes(cs.concept, []);\r\n }\r\n\r\n return function resolve(valueSetUrl: string): string[] | undefined {\r\n const versionless = valueSetUrl.split(\"|\")[0]!;\r\n const vs = valueSets.get(versionless);\r\n if (!vs?.compose?.include?.length) return fallback?.(valueSetUrl);\r\n const codes = new Set<string>();\r\n for (const group of vs.compose.include) {\r\n const groupCodes = resolveGroup(group);\r\n if (!groupCodes) return fallback?.(valueSetUrl);\r\n for (const code of groupCodes) codes.add(code);\r\n }\r\n for (const group of vs.compose.exclude ?? []) {\r\n const groupCodes = resolveGroup(group);\r\n if (!groupCodes) return fallback?.(valueSetUrl);\r\n for (const code of groupCodes) codes.delete(code);\r\n }\r\n if (codes.size === 0 || codes.size > MAX_ENUM_CODES) return fallback?.(valueSetUrl);\r\n return [...codes];\r\n };\r\n}\r\n","import { gunzipSync } from \"node:zlib\";\r\nimport fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"./types.js\";\r\n\r\n/**\r\n * The vendored `definitions/` directory sits at the package root, next to\r\n * `src/` (dev) or `dist/` (published build), so walking up from this module\r\n * finds it in both layouts.\r\n */\r\nfunction definitionsRoot(): string {\r\n let dir = path.dirname(fileURLToPath(import.meta.url));\r\n for (let i = 0; i < 5; i++) {\r\n const candidate = path.join(dir, \"definitions\");\r\n if (fs.existsSync(candidate)) return candidate;\r\n dir = path.dirname(dir);\r\n }\r\n throw new Error(\"Could not locate the vendored FHIR definitions directory\");\r\n}\r\n\r\nconst cache = new Map<string, unknown>();\r\n\r\nfunction loadGzJson(fhirVersion: FhirVersion, file: string): unknown {\r\n const key = `${fhirVersion}/${file}`;\r\n let value = cache.get(key);\r\n if (value === undefined) {\r\n const fullPath = path.join(definitionsRoot(), fhirVersion, `${file}.gz`);\r\n value = JSON.parse(gunzipSync(fs.readFileSync(fullPath)).toString(\"utf8\"));\r\n cache.set(key, value);\r\n }\r\n return value;\r\n}\r\n\r\nexport interface FhirJsonSchema {\r\n discriminator?: { propertyName: string; mapping: Record<string, string> };\r\n definitions: Record<string, JsonSchemaNode>;\r\n}\r\n\r\nexport function loadFhirSchema(fhirVersion: FhirVersion): FhirJsonSchema {\r\n return loadGzJson(fhirVersion, \"fhir.schema.json\") as FhirJsonSchema;\r\n}\r\n\r\nexport interface SearchParameter {\r\n name: string;\r\n code: string;\r\n base: string[];\r\n type: string;\r\n description?: string;\r\n}\r\n\r\nexport function loadSearchParameters(fhirVersion: FhirVersion): SearchParameter[] {\r\n const bundle = loadGzJson(fhirVersion, \"search-parameters.json\") as {\r\n entry?: { resource?: SearchParameter & { resourceType: string } }[];\r\n };\r\n return (bundle.entry ?? [])\r\n .map((e) => e.resource)\r\n .filter(\r\n // R4B ships a few draft codesystem-extensions-* SearchParameters with no\r\n // `base`; they can't be attached to any resource, so drop them here.\r\n (r): r is SearchParameter & { resourceType: string } =>\r\n r?.resourceType === \"SearchParameter\" && Array.isArray(r.base),\r\n );\r\n}\r\n\r\nexport interface MinOperationParameter {\r\n name: string;\r\n use: \"in\" | \"out\";\r\n min: number;\r\n max: string;\r\n /** Absent for multi-part parameters (they force POST + Parameters). */\r\n type?: string;\r\n documentation?: string;\r\n}\r\n\r\nexport interface MinOperationDefinition {\r\n name: string;\r\n code: string;\r\n url: string;\r\n description?: string;\r\n /** Applicable resource types; [\"Resource\"] means every resource. */\r\n resource: string[];\r\n system: boolean;\r\n type: boolean;\r\n instance: boolean;\r\n parameters: MinOperationParameter[];\r\n}\r\n\r\nexport function loadOperationDefinitions(fhirVersion: FhirVersion): MinOperationDefinition[] {\r\n return loadGzJson(fhirVersion, \"operation-definitions.json\") as MinOperationDefinition[];\r\n}\r\n\r\nexport interface MinElementType {\r\n code: string;\r\n targetProfile?: string[];\r\n fhirType?: string;\r\n}\r\n\r\nexport interface MinElement {\r\n path: string;\r\n min: number;\r\n max: string;\r\n short?: string;\r\n definition?: string;\r\n contentReference?: string;\r\n types?: MinElementType[];\r\n binding?: { strength: string; valueSet: string; codes?: string[] };\r\n /**\r\n * Value the element is fixed to by a profile (`fixed[x]`), normalized to a\r\n * JSON value. Only populated for profiles loaded from an IG package; the\r\n * vendored base definitions do not carry it.\r\n */\r\n fixed?: unknown;\r\n /** Profile `mustSupport` flag (surfaced in descriptions, not enforced). */\r\n mustSupport?: boolean;\r\n /**\r\n * Human labels for profile constraints this tool does not enforce in\r\n * OpenAPI (e.g. \"pattern\", \"slicing\"), surfaced in the property description\r\n * and `x-fhir-constraints-omitted`. IG profiles only.\r\n */\r\n omittedConstraints?: string[];\r\n}\r\n\r\nexport interface MinStructureDefinition {\r\n name: string;\r\n url: string;\r\n kind: \"resource\" | \"complex-type\" | \"primitive-type\";\r\n type: string;\r\n abstract: boolean;\r\n baseDefinition?: string;\r\n elements: MinElement[];\r\n}\r\n\r\nexport function loadStructureDefinitions(fhirVersion: FhirVersion): MinStructureDefinition[] {\r\n return loadGzJson(fhirVersion, \"structure-definitions.json\") as MinStructureDefinition[];\r\n}\r\n","import type { MinElement, MinStructureDefinition } from \"../definitions.js\";\r\nimport type { JsonSchemaNode } from \"../types.js\";\r\n\r\n/**\r\n * Walks a StructureDefinition snapshot into named IR schema definitions\r\n * (`#/definitions/<Name>` refs). Shared by the core structure-def backend\r\n * (base resources/types) and the profile applier (IG profiles), so the two\r\n * produce identical schema shapes and only differ in the constraints applied.\r\n */\r\nexport interface EmitOptions {\r\n /** Schema name for the root definition (e.g. \"Patient\" or \"USCorePatient\"). */\r\n rootName: string;\r\n /** Emit a `resourceType` discriminator property. */\r\n isResourceRoot: boolean;\r\n /**\r\n * Wire resourceType/description name. Defaults to the SD `type`. For a\r\n * profile this stays the base resource (\"Patient\") even though rootName is\r\n * the profile name, because resourceType on the wire is the base type.\r\n */\r\n resourceDisplayName?: string;\r\n /**\r\n * Apply profile constraints while walking: drop `max: \"0\"` elements and\r\n * turn `fixed[x]` into a `const`. Off for base definitions so their output\r\n * is unchanged.\r\n */\r\n profile?: boolean;\r\n}\r\n\r\ninterface ElementNode {\r\n element: MinElement;\r\n children: Map<string, ElementNode>;\r\n}\r\n\r\nfunction segmentToPascal(segment: string): string {\r\n return segment.charAt(0).toUpperCase() + segment.slice(1);\r\n}\r\n\r\nfunction isBackbone(el: MinElement): boolean {\r\n return (el.types ?? []).some((t) => t.code === \"BackboneElement\" || t.code === \"Element\");\r\n}\r\n\r\n/** Type codes from the FHIRPath system (used on `id`, `Extension.url`, ...). */\r\nfunction systemTypeSchema(code: string): JsonSchemaNode | undefined {\r\n if (!code.startsWith(\"http://hl7.org/fhirpath/System.\")) return undefined;\r\n const kind = code.slice(\"http://hl7.org/fhirpath/System.\".length);\r\n switch (kind) {\r\n case \"Boolean\":\r\n return { type: \"boolean\" };\r\n case \"Integer\":\r\n case \"Decimal\":\r\n return { type: \"number\" };\r\n default:\r\n return { type: \"string\" };\r\n }\r\n}\r\n\r\nfunction buildElementTree(sd: MinStructureDefinition): ElementNode | undefined {\r\n const rootPath = sd.type ?? sd.name;\r\n let root: ElementNode | undefined;\r\n const nodes = new Map<string, ElementNode>();\r\n for (const el of sd.elements) {\r\n const node: ElementNode = { element: el, children: new Map() };\r\n nodes.set(el.path, node);\r\n if (el.path === rootPath) {\r\n root = node;\r\n continue;\r\n }\r\n const parentPath = el.path.slice(0, el.path.lastIndexOf(\".\"));\r\n const segment = el.path.slice(el.path.lastIndexOf(\".\") + 1);\r\n nodes.get(parentPath)?.children.set(segment, node);\r\n }\r\n return root;\r\n}\r\n\r\n/**\r\n * Names a backbone reached by a `contentReference` (e.g. \"#Questionnaire.item\"\r\n * -> \"Questionnaire_Item\"). When walking a profile, a self-reference to the\r\n * base type root is remapped onto the profile's own name so the ref resolves\r\n * within the emitted profile schemas.\r\n */\r\nfunction contentReferenceName(reference: string, sd: MinStructureDefinition, rootName: string): string {\r\n const path = reference.replace(/^#/, \"\");\r\n const [root, ...rest] = path.split(\".\");\r\n if (rest.length === 0) return root ?? path;\r\n const prefix = root === (sd.type ?? sd.name) ? rootName : (root ?? \"\");\r\n return [prefix, ...rest.map(segmentToPascal)].join(\"_\");\r\n}\r\n\r\nexport function emitStructureDefinitionSchemas(\r\n sd: MinStructureDefinition,\r\n definitions: Map<string, JsonSchemaNode>,\r\n opts: EmitOptions,\r\n): void {\r\n const root = buildElementTree(sd);\r\n if (!root) return;\r\n emitObjectDefinition(sd, opts.rootName, root, definitions, opts.isResourceRoot, opts);\r\n}\r\n\r\nfunction emitObjectDefinition(\r\n sd: MinStructureDefinition,\r\n name: string,\r\n node: ElementNode,\r\n definitions: Map<string, JsonSchemaNode>,\r\n isResourceRoot: boolean,\r\n opts: EmitOptions,\r\n): void {\r\n if (definitions.has(name)) return;\r\n const properties: Record<string, JsonSchemaNode> = {};\r\n const required: string[] = [];\r\n const displayName = opts.resourceDisplayName ?? sd.type ?? sd.name;\r\n\r\n if (isResourceRoot) {\r\n properties.resourceType = {\r\n description: `This is a ${displayName} resource`,\r\n const: displayName,\r\n };\r\n required.push(\"resourceType\");\r\n }\r\n\r\n // Reserve the name before recursing so cycles terminate.\r\n const definition: JsonSchemaNode = {\r\n ...(node.element.definition ? { description: node.element.definition } : {}),\r\n properties,\r\n additionalProperties: false,\r\n };\r\n definitions.set(name, definition);\r\n\r\n for (const [segment, child] of node.children) {\r\n emitProperty(sd, name, segment, child, properties, required, definitions, opts);\r\n }\r\n if (required.length > 0) definition.required = required.sort();\r\n}\r\n\r\nfunction emitProperty(\r\n sd: MinStructureDefinition,\r\n parentName: string,\r\n segment: string,\r\n node: ElementNode,\r\n properties: Record<string, JsonSchemaNode>,\r\n required: string[],\r\n definitions: Map<string, JsonSchemaNode>,\r\n opts: EmitOptions,\r\n): void {\r\n const el = node.element;\r\n // Profile constraint: an element constrained out (max 0) is removed.\r\n if (opts.profile && el.max === \"0\") return;\r\n\r\n const isArray = el.max === \"*\" || Number(el.max) > 1;\r\n const isChoice = segment.endsWith(\"[x]\");\r\n\r\n // In profile mode, annotate must-support and constraints not enforced in\r\n // OpenAPI (pattern, slicing) so they survive into generated docs.\r\n let description = el.definition ?? el.short;\r\n const omitted: string[] = [];\r\n if (opts.profile) {\r\n if (el.mustSupport) omitted.push(\"must-support\");\r\n if (el.omittedConstraints) omitted.push(...el.omittedConstraints);\r\n if (omitted.length > 0) {\r\n const note = `Profile constraints not enforced here: ${omitted.join(\", \")}.`;\r\n description = description ? `${description} ${note}` : note;\r\n }\r\n }\r\n\r\n const addProperty = (fieldName: string, schema: JsonSchemaNode, primitive: boolean) => {\r\n const annotated =\r\n omitted.length > 0 && !(\"$ref\" in schema)\r\n ? { ...schema, \"x-fhir-constraints-omitted\": omitted }\r\n : schema;\r\n properties[fieldName] = wrapCardinality(annotated, isArray, description);\r\n if (primitive) {\r\n properties[`_${fieldName}`] = wrapCardinality(\r\n { $ref: \"#/definitions/Element\" },\r\n isArray,\r\n `Extensions for ${fieldName}`,\r\n );\r\n }\r\n };\r\n\r\n if (isChoice) {\r\n const base = segment.slice(0, -3);\r\n for (const type of el.types ?? []) {\r\n const fieldName = base + segmentToPascal(type.code);\r\n const { schema, primitive } = schemaForTypeCode(type.code, el, opts);\r\n addProperty(fieldName, schema, primitive);\r\n }\r\n // Choice fields are never individually required: the constraint \"exactly\r\n // one of the expansions\" is not expressible in required[].\r\n return;\r\n }\r\n\r\n if (el.contentReference) {\r\n const target = contentReferenceName(el.contentReference, sd, opts.rootName);\r\n addProperty(segment, { $ref: `#/definitions/${target}` }, false);\r\n } else if (isBackbone(el) && node.children.size > 0) {\r\n const childName = `${parentName}_${segmentToPascal(segment)}`;\r\n emitObjectDefinition(sd, childName, node, definitions, false, opts);\r\n addProperty(segment, { $ref: `#/definitions/${childName}` }, false);\r\n } else {\r\n const type = (el.types ?? [])[0];\r\n if (!type) return; // extension-only or profiled-out element\r\n const { schema, primitive } = schemaForTypeCode(type.code, el, opts);\r\n addProperty(segment, schema, primitive);\r\n }\r\n\r\n if (el.min >= 1) required.push(segment);\r\n}\r\n\r\nfunction schemaForTypeCode(\r\n code: string,\r\n el: MinElement,\r\n opts: EmitOptions,\r\n): { schema: JsonSchemaNode; primitive: boolean } {\r\n const primitive = code.charAt(0) === code.charAt(0).toLowerCase();\r\n\r\n const system = systemTypeSchema(code);\r\n if (system) return { schema: system, primitive: false };\r\n if (code === \"Resource\" || code === \"DomainResource\") {\r\n return { schema: { $ref: \"#/definitions/ResourceList\" }, primitive: false };\r\n }\r\n // Profile constraint: a fixed value pins the element to a single constant.\r\n if (opts.profile && el.fixed !== undefined) {\r\n return { schema: { const: el.fixed }, primitive };\r\n }\r\n // Required bindings whose ValueSet was resolved become inline enums on\r\n // `code` elements, mirroring the official fhir.schema.json.\r\n if (code === \"code\" && el.binding?.codes?.length) {\r\n return { schema: { enum: el.binding.codes }, primitive: true };\r\n }\r\n return { schema: { $ref: `#/definitions/${code}` }, primitive };\r\n}\r\n\r\nfunction wrapCardinality(\r\n schema: JsonSchemaNode,\r\n isArray: boolean,\r\n description?: string,\r\n): JsonSchemaNode {\r\n const withDescription = (s: JsonSchemaNode) =>\r\n description && !(\"$ref\" in s) ? { description, ...s } : s;\r\n if (isArray) {\r\n return {\r\n ...(description ? { description } : {}),\r\n type: \"array\",\r\n items: schema,\r\n };\r\n }\r\n if (\"$ref\" in schema && description) {\r\n // JSON Schema draft-06/OAS 3.0 ignores siblings of $ref; nest description\r\n // via allOf only in 3.1. Keep plain $ref for compatibility.\r\n return schema;\r\n }\r\n return withDescription(schema);\r\n}\r\n","import { loadStructureDefinitions } from \"../definitions.js\";\r\nimport type { DefinitionRegistry } from \"../ir/registry.js\";\r\nimport { emitStructureDefinitionSchemas } from \"../ir/structureWalker.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"../types.js\";\r\nimport type { IgContext, IgProfile } from \"./package.js\";\r\nimport type { ValueSetResolver } from \"./minimize.js\";\r\n\r\nexport interface AppliedProfile {\r\n /** Component schema name emitted for the profile (e.g. \"USCorePatient\"). */\r\n schemaName: string;\r\n /** Base resource type the profile constrains (e.g. \"Patient\"). */\r\n resourceType: string;\r\n /** Versionless canonical URL of the profile. */\r\n url: string;\r\n}\r\n\r\n/**\r\n * A ValueSet resolver backed by the vendored core definitions: base elements\r\n * already carry the resolved code list for their required binding, so core\r\n * ValueSets (e.g. administrative-gender) referenced by profile elements can be\r\n * resolved without shipping the core ValueSets themselves.\r\n */\r\nexport function buildCoreValueSetFallback(fhirVersion: FhirVersion): ValueSetResolver {\r\n const map = new Map<string, string[]>();\r\n for (const sd of loadStructureDefinitions(fhirVersion)) {\r\n for (const el of sd.elements) {\r\n if (el.binding?.codes?.length && el.binding.valueSet) {\r\n const key = el.binding.valueSet.split(\"|\")[0]!;\r\n if (!map.has(key)) map.set(key, el.binding.codes);\r\n }\r\n }\r\n }\r\n return (valueSetUrl) => map.get(valueSetUrl.split(\"|\")[0]!);\r\n}\r\n\r\nfunction sanitizeSchemaName(name: string): string {\r\n const cleaned = name.replace(/[^A-Za-z0-9_]/g, \"\");\r\n return /^[A-Za-z]/.test(cleaned) ? cleaned : `Profile${cleaned}`;\r\n}\r\n\r\n/** Finds a profile in the IG by canonical URL, id, or name (case-insensitive). */\r\nfunction findProfile(context: IgContext, requested: string): IgProfile {\r\n const needle = requested.toLowerCase();\r\n const matches = context.profiles.filter(\r\n (p) =>\r\n p.url.toLowerCase() === needle ||\r\n p.id?.toLowerCase() === needle ||\r\n p.name.toLowerCase() === needle,\r\n );\r\n if (matches.length === 1) return matches[0]!;\r\n if (matches.length > 1) {\r\n throw new Error(\r\n `Profile \"${requested}\" is ambiguous in ${context.name}; match by canonical URL. ` +\r\n `Candidates: ${matches.map((p) => p.url).join(\", \")}`,\r\n );\r\n }\r\n if (context.profilesMissingSnapshot.some((p) => p.toLowerCase() === needle)) {\r\n throw new Error(\r\n `Profile \"${requested}\" in ${context.name} has no snapshot. Snapshot generation is ` +\r\n `out of scope; use a snapshot-bearing release of the IG.`,\r\n );\r\n }\r\n const available = context.profiles.map((p) => p.id ?? p.name).sort();\r\n throw new Error(\r\n `Profile \"${requested}\" not found in ${context.name}@${context.version}. ` +\r\n `Available profiles: ${available.join(\", \") || \"none\"}`,\r\n );\r\n}\r\n\r\n/**\r\n * Emits the profiled schema (and its backbones) into the registry, applying\r\n * the profile's constraints, and returns how it maps onto the base resource.\r\n * Unconstrained elements resolve to base type refs, so the dependency closure\r\n * still draws from the vendored core registry.\r\n */\r\nexport function applyProfile(\r\n context: IgContext,\r\n requested: string,\r\n registry: DefinitionRegistry,\r\n): AppliedProfile {\r\n const profile = findProfile(context, requested);\r\n let schemaName = sanitizeSchemaName(profile.name);\r\n // Guard against collision with a base definition of a different shape.\r\n if (registry.definitions.has(schemaName) && schemaName !== profile.type) {\r\n schemaName = `${schemaName}Profile`;\r\n }\r\n\r\n emitStructureDefinitionSchemas(profile.definition, registry.definitions, {\r\n rootName: schemaName,\r\n isResourceRoot: true,\r\n resourceDisplayName: profile.type,\r\n profile: true,\r\n });\r\n\r\n const schema = registry.definitions.get(schemaName) as JsonSchemaNode | undefined;\r\n if (schema) schema[\"x-fhir-profile\"] = profile.url;\r\n\r\n return { schemaName, resourceType: profile.type, url: profile.url };\r\n}\r\n","import { loadFhirSchema } from \"../definitions.js\";\r\nimport type { DefinitionRegistry } from \"../ir/registry.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"../types.js\";\r\n\r\n/**\r\n * Builds the definition registry from the official `fhir.schema.json`\r\n * published with each FHIR release. This schema already has choice types\r\n * (value[x]) expanded and backbone elements flattened into named definitions\r\n * (e.g. `Patient_Contact`), so it maps directly onto the IR.\r\n */\r\nexport function buildRegistryFromSchemaJson(fhirVersion: FhirVersion): DefinitionRegistry {\r\n const schema = loadFhirSchema(fhirVersion);\r\n const definitions = new Map<string, JsonSchemaNode>(Object.entries(schema.definitions));\r\n\r\n // Resource types are exactly the discriminator mapping keys; fall back to\r\n // \"has a resourceType const\" for robustness.\r\n let resourceNames: string[];\r\n if (schema.discriminator?.mapping) {\r\n resourceNames = Object.keys(schema.discriminator.mapping);\r\n } else {\r\n resourceNames = [...definitions.entries()]\r\n .filter(([, def]) => {\r\n const props = def.properties as Record<string, JsonSchemaNode> | undefined;\r\n return props?.resourceType !== undefined && \"const\" in (props.resourceType ?? {});\r\n })\r\n .map(([name]) => name);\r\n }\r\n\r\n return { fhirVersion, definitions, resourceNames };\r\n}\r\n","import {\r\n loadStructureDefinitions,\r\n type MinStructureDefinition,\r\n} from \"../definitions.js\";\r\nimport type { DefinitionRegistry } from \"../ir/registry.js\";\r\nimport { emitStructureDefinitionSchemas } from \"../ir/structureWalker.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"../types.js\";\r\n\r\n/**\r\n * Builds the definition registry by walking StructureDefinition snapshots —\r\n * the canonical FHIR metadata, and the basis for profile support. Produces the\r\n * same IR shape as the fhir.schema.json backend: named definitions referencing\r\n * each other via `#/definitions/<Name>`.\r\n *\r\n * The per-snapshot walk lives in ../ir/structureWalker.ts so profiles loaded\r\n * from an IG package emit identically-shaped schemas.\r\n */\r\nexport function buildRegistryFromStructureDefinitions(\r\n fhirVersion: FhirVersion,\r\n): DefinitionRegistry {\r\n const sds = loadStructureDefinitions(fhirVersion);\r\n const definitions = new Map<string, JsonSchemaNode>();\r\n const resourceNames: string[] = [];\r\n\r\n const byName = new Map(sds.map((sd) => [sd.name, sd]));\r\n\r\n for (const sd of sds) {\r\n if (sd.kind === \"primitive-type\") {\r\n definitions.set(sd.name, primitiveSchema(sd));\r\n }\r\n }\r\n // `xhtml` (Narrative.div) has no StructureDefinition in the core packages.\r\n if (!definitions.has(\"xhtml\")) {\r\n definitions.set(\"xhtml\", {\r\n type: \"string\",\r\n description: \"XHTML narrative content\",\r\n });\r\n }\r\n\r\n for (const sd of sds) {\r\n if (sd.kind === \"primitive-type\" || sd.abstract) continue;\r\n emitStructureDefinitionSchemas(sd, definitions, {\r\n rootName: sd.name,\r\n isResourceRoot: sd.kind === \"resource\",\r\n });\r\n if (sd.kind === \"resource\") resourceNames.push(sd.name);\r\n }\r\n\r\n // Element/BackboneElement are abstract but referenced by primitive-extension\r\n // (`_field`) properties, so they need concrete definitions.\r\n for (const abstractName of [\"Element\", \"BackboneElement\"]) {\r\n const sd = byName.get(abstractName);\r\n if (sd && !definitions.has(abstractName)) {\r\n emitStructureDefinitionSchemas(sd, definitions, {\r\n rootName: sd.name,\r\n isResourceRoot: false,\r\n });\r\n }\r\n }\r\n\r\n resourceNames.sort();\r\n definitions.set(\"ResourceList\", {\r\n oneOf: resourceNames.map((name) => ({ $ref: `#/definitions/${name}` })),\r\n });\r\n\r\n return { fhirVersion, definitions, resourceNames };\r\n}\r\n\r\n/** Maps FHIR primitive type names to their JSON representation. */\r\nfunction primitiveJsonType(name: string): JsonSchemaNode {\r\n switch (name) {\r\n case \"boolean\":\r\n return { type: \"boolean\" };\r\n case \"decimal\":\r\n return { type: \"number\" };\r\n case \"integer\":\r\n case \"positiveInt\":\r\n case \"unsignedInt\":\r\n return { type: \"number\" };\r\n // integer64 (R5) is represented as a JSON string per the spec.\r\n default:\r\n return { type: \"string\" };\r\n }\r\n}\r\n\r\nfunction primitiveSchema(sd: MinStructureDefinition): JsonSchemaNode {\r\n const root = sd.elements[0];\r\n return {\r\n ...primitiveJsonType(sd.name),\r\n ...(root?.definition ? { description: root.definition } : {}),\r\n };\r\n}\r\n","import type { JsonSchemaNode, OpenApiVersion } from \"../types.js\";\r\n\r\nconst DEFINITIONS_REF = \"#/definitions/\";\r\nconst COMPONENTS_REF = \"#/components/schemas/\";\r\nconst NO_ENUMS_NOTE_MAX_CODES = 25;\r\n\r\nexport interface ConvertOptions {\r\n /** Strip source enums (required-binding codes), noting them in description. */\r\n noEnums?: boolean;\r\n}\r\n\r\n/**\r\n * Converts one JSON-Schema-shaped definition (draft-06 subset as used by\r\n * fhir.schema.json) into an OpenAPI schema object:\r\n * - rewrites `#/definitions/X` refs to `#/components/schemas/X`\r\n * - strips `pattern` from non-string types (fhir.schema.json puts regex\r\n * patterns on booleans/numbers, where the keyword is meaningless)\r\n * - drops JSON Schema bookkeeping keywords ($schema, id/$id, $comment)\r\n * - for 3.0.x, downconverts `const` to a single-value `enum`\r\n * - with `noEnums`, replaces source enums with plain strings, keeping the\r\n * allowed codes in the description; `const`-derived enums (resourceType\r\n * discriminators) are exempt\r\n */\r\nexport function convertSchema(\r\n node: JsonSchemaNode,\r\n target: OpenApiVersion,\r\n options: ConvertOptions = {},\r\n): JsonSchemaNode {\r\n return convertNode(node, target, options) as JsonSchemaNode;\r\n}\r\n\r\nfunction convertNode(node: unknown, target: OpenApiVersion, options: ConvertOptions): unknown {\r\n if (Array.isArray(node)) {\r\n return node.map((item) => convertNode(item, target, options));\r\n }\r\n if (!node || typeof node !== \"object\") return node;\r\n\r\n const out: JsonSchemaNode = {};\r\n const source = node as JsonSchemaNode;\r\n let strippedEnum: unknown[] | undefined;\r\n for (const [key, value] of Object.entries(source)) {\r\n switch (key) {\r\n case \"$schema\":\r\n case \"$comment\":\r\n case \"id\":\r\n case \"$id\":\r\n break;\r\n case \"$ref\":\r\n out.$ref =\r\n typeof value === \"string\" && value.startsWith(DEFINITIONS_REF)\r\n ? COMPONENTS_REF + value.slice(DEFINITIONS_REF.length)\r\n : value;\r\n break;\r\n case \"const\":\r\n if (target === \"3.1.0\") out.const = value;\r\n else out.enum = [value];\r\n break;\r\n case \"enum\":\r\n if (options.noEnums && Array.isArray(value)) strippedEnum = value;\r\n else out.enum = value;\r\n break;\r\n case \"pattern\":\r\n if (source.type === undefined || source.type === \"string\") out.pattern = value;\r\n break;\r\n default:\r\n out[key] = convertNode(value, target, options);\r\n }\r\n }\r\n\r\n if (strippedEnum) {\r\n if (out.type === undefined && out.$ref === undefined) out.type = \"string\";\r\n const listed = strippedEnum.slice(0, NO_ENUMS_NOTE_MAX_CODES).join(\" | \");\r\n const ellipsis = strippedEnum.length > NO_ENUMS_NOTE_MAX_CODES ? \" | ...\" : \"\";\r\n const note = `Codes (FHIR required binding, not enforced here): ${listed}${ellipsis}`;\r\n out.description = out.description ? `${out.description} ${note}` : note;\r\n }\r\n return out;\r\n}\r\n","import type { FhirVersion, JsonSchemaNode, TrimOptions } from \"../types.js\";\r\n\r\n/**\r\n * Backend-neutral intermediate representation: a set of named,\r\n * JSON-Schema-shaped type definitions whose internal references use the\r\n * `#/definitions/<Name>` form (the convention of the official fhir.schema.json).\r\n * Both backends produce this shape; emitters consume it.\r\n */\r\nexport interface DefinitionRegistry {\r\n fhirVersion: FhirVersion;\r\n definitions: Map<string, JsonSchemaNode>;\r\n /** Concrete (non-abstract) resource type names, e.g. \"Patient\". */\r\n resourceNames: string[];\r\n}\r\n\r\nconst REF_PREFIX = \"#/definitions/\";\r\n\r\nexport function refName(ref: string): string | undefined {\r\n return ref.startsWith(REF_PREFIX) ? ref.slice(REF_PREFIX.length) : undefined;\r\n}\r\n\r\n/** Collects the names of all `#/definitions/...` references inside a schema node. */\r\nexport function collectRefs(node: unknown, out = new Set<string>()): Set<string> {\r\n if (Array.isArray(node)) {\r\n for (const item of node) collectRefs(item, out);\r\n } else if (node && typeof node === \"object\") {\r\n for (const [key, value] of Object.entries(node)) {\r\n if (key === \"$ref\" && typeof value === \"string\") {\r\n const name = refName(value);\r\n if (name) out.add(name);\r\n } else {\r\n collectRefs(value, out);\r\n }\r\n }\r\n }\r\n return out;\r\n}\r\n\r\nexport interface ClosureResult {\r\n /** Definition name -> schema, for the full dependency closure of the roots. */\r\n schemas: Map<string, JsonSchemaNode>;\r\n /** Names whose bodies were replaced by generic-object stubs via trimming. */\r\n stubbed: Set<string>;\r\n}\r\n\r\nfunction stubSchema(reason: string): JsonSchemaNode {\r\n return {\r\n type: \"object\",\r\n additionalProperties: true,\r\n description: reason,\r\n };\r\n}\r\n\r\n/**\r\n * `ResourceList` in fhir.schema.json is a oneOf over every resource type\r\n * (150-200 entries), referenced by e.g. `Bundle.entry.resource` and\r\n * `DomainResource.contained`. Following it verbatim would drag the entire\r\n * specification into every output, so it is narrowed to the resource types\r\n * actually requested (plus Bundle/OperationOutcome, which the generated REST\r\n * paths always use).\r\n */\r\nfunction narrowedResourceList(included: string[]): JsonSchemaNode {\r\n return {\r\n oneOf: included.map((name) => ({ $ref: `${REF_PREFIX}${name}` })),\r\n description:\r\n \"A contained/bundled FHIR resource. Narrowed by fhir-openapi-translator to the \" +\r\n \"resource types requested at generation time; servers may return other types.\",\r\n };\r\n}\r\n\r\n/**\r\n * Extracts the transitive dependency closure of `roots` from the registry via\r\n * breadth-first search. Cycles are fine: every definition is visited once and\r\n * mutual references remain as $refs. Trim options replace selected\r\n * definitions with stubs whose dependencies are not followed.\r\n */\r\nexport function extractClosure(\r\n registry: DefinitionRegistry,\r\n roots: string[],\r\n trim: TrimOptions = {},\r\n resourceListNarrowing: string[] = roots,\r\n): ClosureResult {\r\n const schemas = new Map<string, JsonSchemaNode>();\r\n const stubbed = new Set<string>();\r\n const maxDepth = trim.maxDepth;\r\n\r\n let frontier = [...new Set(roots)];\r\n let depth = 0;\r\n while (frontier.length > 0) {\r\n const next: string[] = [];\r\n for (const name of frontier) {\r\n if (schemas.has(name)) continue;\r\n const original = registry.definitions.get(name);\r\n if (!original) {\r\n throw new Error(`Unknown FHIR definition: ${name}`);\r\n }\r\n\r\n let schema: JsonSchemaNode = original;\r\n let followDeps = true;\r\n if (trim.excludeNarrative && name === \"Narrative\") {\r\n schema = stubSchema(\r\n \"Human-readable narrative. Excluded from this specification (--exclude-narrative).\",\r\n );\r\n followDeps = false;\r\n stubbed.add(name);\r\n } else if (maxDepth !== undefined && depth > maxDepth) {\r\n schema = stubSchema(\r\n `FHIR ${name}. Pruned from this specification by --max-depth ${maxDepth}.`,\r\n );\r\n followDeps = false;\r\n stubbed.add(name);\r\n } else if (name === \"ResourceList\") {\r\n schema = narrowedResourceList(\r\n [...new Set(resourceListNarrowing)].filter((n) => registry.definitions.has(n)),\r\n );\r\n }\r\n\r\n schemas.set(name, schema);\r\n if (followDeps) {\r\n for (const dep of collectRefs(schema)) {\r\n if (!schemas.has(dep)) next.push(dep);\r\n }\r\n }\r\n }\r\n frontier = next;\r\n depth++;\r\n }\r\n\r\n return { schemas, stubbed };\r\n}\r\n","import {\r\n loadOperationDefinitions,\r\n type MinOperationDefinition,\r\n type MinOperationParameter,\r\n} from \"./definitions.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"./types.js\";\r\n\r\nconst FHIR_JSON = \"application/fhir+json\";\r\nconst SCHEMAS = \"#/components/schemas/\";\r\n\r\n/** FHIR primitive type names are lowercase-first; complex types are not. */\r\nfunction isPrimitive(type: string | undefined): boolean {\r\n return !!type && type.charAt(0) === type.charAt(0).toLowerCase();\r\n}\r\n\r\nfunction camelCode(code: string): string {\r\n return code.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());\r\n}\r\n\r\nfunction ref(schema: string) {\r\n return { $ref: `${SCHEMAS}${schema}` };\r\n}\r\n\r\nfunction fhirContent(schema: string) {\r\n return { [FHIR_JSON]: { schema: ref(schema) } };\r\n}\r\n\r\nfunction errorResponses() {\r\n return {\r\n default: {\r\n description: \"Error, with an OperationOutcome describing the problem\",\r\n content: fhirContent(\"OperationOutcome\"),\r\n },\r\n };\r\n}\r\n\r\nexport interface OperationPathsResult {\r\n paths: Record<string, JsonSchemaNode>;\r\n /** Schema names the operations reference, to add to the closure roots. */\r\n extraSchemaRoots: string[];\r\n}\r\n\r\n/**\r\n * Emits paths for the standard FHIR operations applicable to one resource\r\n * type, from the vendored OperationDefinitions.\r\n *\r\n * Method selection is deterministic per operation: GET with query parameters\r\n * when every `in` parameter is a primitive type (the spec-legal simple\r\n * invocation, and how e.g. $everything is used in practice); otherwise POST\r\n * with a Parameters request body. System-level-only operations are not\r\n * resource-scoped and are out of scope here.\r\n */\r\nexport interface OperationPathOptions {\r\n /** Maps a resource type to the schema name to reference (profile-aware). */\r\n schemaFor?: (resourceType: string) => string;\r\n /**\r\n * Restrict to operations whose code or canonical URL is in this set (e.g.\r\n * from a CapabilityStatement). Default: all operations applicable to the\r\n * resource.\r\n */\r\n only?: ReadonlySet<string>;\r\n}\r\n\r\nexport function buildOperationPaths(\r\n fhirVersion: FhirVersion,\r\n resource: string,\r\n knownResources: ReadonlySet<string>,\r\n options: OperationPathOptions = {},\r\n): OperationPathsResult {\r\n const schemaFor = options.schemaFor ?? ((r) => r);\r\n const paths: Record<string, JsonSchemaNode> = {};\r\n const extraSchemaRoots = new Set<string>();\r\n\r\n const applicable = loadOperationDefinitions(fhirVersion).filter(\r\n (op) =>\r\n (op.type || op.instance) &&\r\n (op.resource.includes(resource) || op.resource.includes(\"Resource\")) &&\r\n (!options.only || options.only.has(op.code) || options.only.has(op.url)),\r\n );\r\n\r\n for (const op of applicable) {\r\n const inParams = op.parameters.filter((p) => p.use === \"in\");\r\n const useGet = inParams.every((p) => isPrimitive(p.type));\r\n const responseSchema = schemaFor(responseSchemaName(op, knownResources));\r\n extraSchemaRoots.add(responseSchema);\r\n if (!useGet) extraSchemaRoots.add(\"Parameters\");\r\n\r\n const buildOperation = (level: \"Type\" | \"Instance\") => {\r\n const operation: JsonSchemaNode = {\r\n tags: [resource],\r\n summary: `$${op.code} (${level.toLowerCase()} level)`,\r\n ...(op.description ? { description: op.description } : {}),\r\n operationId: `${camelCode(op.code)}${resource}${level}`,\r\n externalDocs: { url: op.url },\r\n responses: {\r\n \"200\": {\r\n description: `Result of the $${op.code} operation`,\r\n content: fhirContent(responseSchema),\r\n },\r\n ...errorResponses(),\r\n },\r\n };\r\n if (useGet) {\r\n if (inParams.length > 0) operation.parameters = inParams.map(queryParameter);\r\n } else {\r\n operation.requestBody = {\r\n required: inParams.some((p) => p.min >= 1),\r\n content: fhirContent(\"Parameters\"),\r\n };\r\n }\r\n return operation;\r\n };\r\n\r\n const method = useGet ? \"get\" : \"post\";\r\n if (op.type) {\r\n paths[`/${resource}/$${op.code}`] = { [method]: buildOperation(\"Type\") };\r\n }\r\n if (op.instance) {\r\n paths[`/${resource}/{id}/$${op.code}`] = {\r\n parameters: [\r\n {\r\n name: \"id\",\r\n in: \"path\",\r\n required: true,\r\n description: `Logical id of the ${resource}`,\r\n schema: { type: \"string\", pattern: \"^[A-Za-z0-9\\\\-\\\\.]{1,64}$\" },\r\n },\r\n ],\r\n [method]: buildOperation(\"Instance\"),\r\n };\r\n }\r\n }\r\n\r\n return { paths, extraSchemaRoots: [...extraSchemaRoots].sort() };\r\n}\r\n\r\n/**\r\n * Exactly one `out` parameter named `return` typed as a resource maps to that\r\n * resource; every other output shape is a Parameters resource.\r\n */\r\nfunction responseSchemaName(\r\n op: MinOperationDefinition,\r\n knownResources: ReadonlySet<string>,\r\n): string {\r\n const outParams = op.parameters.filter((p) => p.use === \"out\");\r\n if (outParams.length === 1) {\r\n const only = outParams[0]!;\r\n if (only.name === \"return\" && only.type && knownResources.has(only.type)) {\r\n return only.type;\r\n }\r\n }\r\n return \"Parameters\";\r\n}\r\n\r\nfunction queryParameter(param: MinOperationParameter): JsonSchemaNode {\r\n const isArray = param.max === \"*\" || Number(param.max) > 1;\r\n const base: JsonSchemaNode = { type: \"string\" };\r\n return {\r\n name: param.name,\r\n in: \"query\",\r\n required: param.min >= 1,\r\n ...(param.documentation ? { description: param.documentation } : {}),\r\n // FHIR primitives serialize as strings in URLs; the FHIR type is kept\r\n // as an extension, consistent with search parameters.\r\n schema: isArray ? { type: \"array\", items: base } : base,\r\n ...(isArray ? { explode: true } : {}),\r\n \"x-fhir-type\": param.type,\r\n };\r\n}\r\n","import { loadSearchParameters } from \"./definitions.js\";\r\nimport type { FhirVersion, JsonSchemaNode } from \"./types.js\";\r\n\r\nconst FHIR_JSON = \"application/fhir+json\";\r\nconst SCHEMAS = \"#/components/schemas/\";\r\nconst PARAMETERS = \"#/components/parameters/\";\r\n\r\nfunction ref(schema: string) {\r\n return { $ref: `${SCHEMAS}${schema}` };\r\n}\r\n\r\nfunction fhirContent(schema: string) {\r\n return { [FHIR_JSON]: { schema: ref(schema) } };\r\n}\r\n\r\nfunction errorResponses() {\r\n return {\r\n default: {\r\n description: \"Error, with an OperationOutcome describing the problem\",\r\n content: fhirContent(\"OperationOutcome\"),\r\n },\r\n };\r\n}\r\n\r\nfunction idParameter(name: string, description: string) {\r\n return {\r\n name,\r\n in: \"path\",\r\n required: true,\r\n description,\r\n schema: { type: \"string\", pattern: \"^[A-Za-z0-9\\\\-\\\\.]{1,64}$\" },\r\n };\r\n}\r\n\r\n/**\r\n * Search parameters common to all resources plus the standard search result\r\n * parameters, emitted once under components/parameters and $ref'd from every\r\n * search operation. All are strings except _count: FHIR search values carry\r\n * prefixes/modifiers (e.g. `ge2020-01-01`, `:exact`), so stricter types would\r\n * reject valid requests.\r\n */\r\nconst COMMON_SEARCH_PARAMETERS: Record<string, { description: string; schema: JsonSchemaNode }> = {\r\n _id: { description: \"Logical id of this artifact\", schema: { type: \"string\" } },\r\n _lastUpdated: {\r\n description: \"When the resource version last changed (supports date prefixes, e.g. ge2021-01-01)\",\r\n schema: { type: \"string\" },\r\n },\r\n _tag: { description: \"Tags applied to this resource\", schema: { type: \"string\" } },\r\n _profile: { description: \"Profiles this resource claims to conform to\", schema: { type: \"string\" } },\r\n _security: { description: \"Security labels applied to this resource\", schema: { type: \"string\" } },\r\n _text: { description: \"Search on the narrative of the resource\", schema: { type: \"string\" } },\r\n _content: { description: \"Search on the entire content of the resource\", schema: { type: \"string\" } },\r\n _sort: { description: \"Sort order of the results (comma-separated parameter names, '-' prefix for descending)\", schema: { type: \"string\" } },\r\n _count: { description: \"Maximum number of results per page\", schema: { type: \"integer\", minimum: 0 } },\r\n _include: { description: \"Include referenced resources in the results\", schema: { type: \"string\" } },\r\n _revinclude: { description: \"Include resources that reference the matches in the results\", schema: { type: \"string\" } },\r\n _summary: {\r\n description: \"Return only a portion of each resource\",\r\n schema: { type: \"string\", enum: [\"true\", \"text\", \"data\", \"count\", \"false\"] },\r\n },\r\n _total: {\r\n description: \"Requested precision of the Bundle.total\",\r\n schema: { type: \"string\", enum: [\"none\", \"estimate\", \"accurate\"] },\r\n },\r\n _elements: { description: \"Restrict returned elements (comma-separated element names)\", schema: { type: \"string\" } },\r\n};\r\n\r\nexport function commonSearchParameterComponents(): Record<string, JsonSchemaNode> {\r\n const out: Record<string, JsonSchemaNode> = {};\r\n for (const [name, { description, schema }] of Object.entries(COMMON_SEARCH_PARAMETERS)) {\r\n out[name] = { name, in: \"query\", required: false, description, schema };\r\n }\r\n return out;\r\n}\r\n\r\n/** FHIR RESTful interaction codes (CapabilityStatement.rest.resource.interaction). */\r\nexport type FhirInteraction =\r\n | \"read\"\r\n | \"vread\"\r\n | \"update\"\r\n | \"patch\"\r\n | \"delete\"\r\n | \"history-instance\"\r\n | \"history-type\"\r\n | \"create\"\r\n | \"search-type\";\r\n\r\nexport const ALL_INTERACTIONS: readonly FhirInteraction[] = [\r\n \"read\",\r\n \"vread\",\r\n \"update\",\r\n \"patch\",\r\n \"delete\",\r\n \"history-instance\",\r\n \"history-type\",\r\n \"create\",\r\n \"search-type\",\r\n];\r\n\r\nexport interface ResourcePathOptions {\r\n /** Emit only these interactions. Default: all of them. */\r\n interactions?: ReadonlySet<FhirInteraction>;\r\n /**\r\n * Restrict resource-specific search parameters to these codes (the common\r\n * result parameters like `_id`/`_count` are always kept). Default: all\r\n * search parameters the FHIR version defines for the resource.\r\n */\r\n searchParamCodes?: ReadonlySet<string>;\r\n}\r\n\r\nfunction resourceSearchParameters(\r\n fhirVersion: FhirVersion,\r\n resource: string,\r\n only?: ReadonlySet<string>,\r\n): JsonSchemaNode[] {\r\n return loadSearchParameters(fhirVersion)\r\n .filter((sp) => sp.base.includes(resource) && (!only || only.has(sp.code)))\r\n .sort((a, b) => a.code.localeCompare(b.code))\r\n .map((sp) => ({\r\n name: sp.code,\r\n in: \"query\",\r\n required: false,\r\n description: sp.description,\r\n // FHIR search values carry prefixes and modifiers, so all are strings.\r\n schema: { type: \"string\" },\r\n \"x-fhir-search-type\": sp.type,\r\n }));\r\n}\r\n\r\nconst historyParameters = () => [\r\n { $ref: `${PARAMETERS}_count` },\r\n {\r\n name: \"_since\",\r\n in: \"query\",\r\n required: false,\r\n description: \"Only include versions created at or after this instant\",\r\n schema: { type: \"string\", format: \"date-time\" },\r\n },\r\n];\r\n\r\n/**\r\n * FHIR RESTful API interactions for one resource type. By default every\r\n * standard interaction (search, create, read, vread, update, patch, delete,\r\n * and instance/type history) is emitted; `options.interactions` restricts the\r\n * set (e.g. from a CapabilityStatement), and empty path items are dropped.\r\n */\r\nexport function buildResourcePaths(\r\n fhirVersion: FhirVersion,\r\n resource: string,\r\n /** Schema referenced by request/response bodies; a profile name or the resource. */\r\n schemaName: string = resource,\r\n options: ResourcePathOptions = {},\r\n): Record<string, JsonSchemaNode> {\r\n const want = (interaction: FhirInteraction) =>\r\n !options.interactions || options.interactions.has(interaction);\r\n const body = () => fhirContent(schemaName);\r\n const idParam = () => idParameter(\"id\", `Logical id of the ${resource}`);\r\n const paths: Record<string, JsonSchemaNode> = {};\r\n\r\n const typeItem: Record<string, JsonSchemaNode> = {};\r\n if (want(\"search-type\")) {\r\n typeItem.get = {\r\n tags: [resource],\r\n summary: `Search for ${resource} resources`,\r\n operationId: `search${resource}`,\r\n parameters: [\r\n ...Object.keys(COMMON_SEARCH_PARAMETERS).map((name) => ({ $ref: `${PARAMETERS}${name}` })),\r\n ...resourceSearchParameters(fhirVersion, resource, options.searchParamCodes),\r\n ],\r\n responses: {\r\n \"200\": {\r\n description: `Bundle of matching ${resource} resources`,\r\n content: fhirContent(\"Bundle\"),\r\n },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"create\")) {\r\n typeItem.post = {\r\n tags: [resource],\r\n summary: `Create a ${resource} resource`,\r\n operationId: `create${resource}`,\r\n requestBody: { required: true, content: body() },\r\n responses: {\r\n \"201\": { description: `${resource} created`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (Object.keys(typeItem).length > 0) paths[`/${resource}`] = typeItem;\r\n\r\n const instanceItem: Record<string, JsonSchemaNode> = {};\r\n if (want(\"read\")) {\r\n instanceItem.get = {\r\n tags: [resource],\r\n summary: `Read a ${resource} resource by id`,\r\n operationId: `read${resource}`,\r\n responses: {\r\n \"200\": { description: `The ${resource} resource`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"update\")) {\r\n instanceItem.put = {\r\n tags: [resource],\r\n summary: `Update (or create) a ${resource} resource by id`,\r\n operationId: `update${resource}`,\r\n parameters: [\r\n {\r\n name: \"If-Match\",\r\n in: \"header\",\r\n required: false,\r\n description: \"Version-aware update: weak ETag of the version being updated\",\r\n schema: { type: \"string\" },\r\n },\r\n ],\r\n requestBody: { required: true, content: body() },\r\n responses: {\r\n \"200\": { description: `${resource} updated`, content: body() },\r\n \"201\": { description: `${resource} created`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"patch\")) {\r\n instanceItem.patch = {\r\n tags: [resource],\r\n summary: `Patch a ${resource} resource by id`,\r\n operationId: `patch${resource}`,\r\n requestBody: {\r\n required: true,\r\n content: {\r\n \"application/json-patch+json\": {\r\n schema: {\r\n type: \"array\",\r\n items: { type: \"object\", additionalProperties: true },\r\n description: \"JSON Patch operations (RFC 6902)\",\r\n },\r\n },\r\n },\r\n },\r\n responses: {\r\n \"200\": { description: `${resource} patched`, content: body() },\r\n ...errorResponses(),\r\n },\r\n };\r\n }\r\n if (want(\"delete\")) {\r\n instanceItem.delete = {\r\n tags: [resource],\r\n summary: `Delete a ${resource} resource by id`,\r\n operationId: `delete${resource}`,\r\n responses: { \"204\": { description: `${resource} deleted` }, ...errorResponses() },\r\n };\r\n }\r\n if (Object.keys(instanceItem).length > 0) {\r\n paths[`/${resource}/{id}`] = { parameters: [idParam()], ...instanceItem };\r\n }\r\n\r\n if (want(\"history-instance\")) {\r\n paths[`/${resource}/{id}/_history`] = {\r\n parameters: [idParam()],\r\n get: {\r\n tags: [resource],\r\n summary: `History of a ${resource} instance`,\r\n operationId: `history${resource}Instance`,\r\n parameters: historyParameters(),\r\n responses: {\r\n \"200\": { description: \"History bundle\", content: fhirContent(\"Bundle\") },\r\n ...errorResponses(),\r\n },\r\n },\r\n };\r\n }\r\n if (want(\"vread\")) {\r\n paths[`/${resource}/{id}/_history/{vid}`] = {\r\n parameters: [idParam(), idParameter(\"vid\", \"Version id of the resource\")],\r\n get: {\r\n tags: [resource],\r\n summary: `Read a specific version of a ${resource} resource`,\r\n operationId: `vread${resource}`,\r\n responses: {\r\n \"200\": { description: `The ${resource} resource version`, content: body() },\r\n ...errorResponses(),\r\n },\r\n },\r\n };\r\n }\r\n if (want(\"history-type\")) {\r\n paths[`/${resource}/_history`] = {\r\n get: {\r\n tags: [resource],\r\n summary: `History across all ${resource} resources`,\r\n operationId: `history${resource}Type`,\r\n parameters: historyParameters(),\r\n responses: {\r\n \"200\": { description: \"History bundle\", content: fhirContent(\"Bundle\") },\r\n ...errorResponses(),\r\n },\r\n },\r\n };\r\n }\r\n\r\n return paths;\r\n}\r\n","import { buildRegistryFromSchemaJson } from \"./backends/schemaJson.js\";\r\nimport { buildRegistryFromStructureDefinitions } from \"./backends/structureDefinition.js\";\r\nimport type { Capability, ResourceCapability } from \"./capability.js\";\r\nimport { convertSchema } from \"./emit/schema.js\";\r\nimport { loadIgSync, type IgContext } from \"./ig/package.js\";\r\nimport { applyProfile, buildCoreValueSetFallback } from \"./ig/profile.js\";\r\nimport { extractClosure, type DefinitionRegistry } from \"./ir/registry.js\";\r\nimport { buildOperationPaths } from \"./operations.js\";\r\nimport { buildResourcePaths, commonSearchParameterComponents } from \"./paths.js\";\r\nimport {\r\n FHIR_VERSION_NUMBERS,\r\n FHIR_VERSIONS,\r\n type FhirVersion,\r\n type GenerateOptions,\r\n type JsonSchemaNode,\r\n type OpenApiDocument,\r\n type SourceBackend,\r\n} from \"./types.js\";\r\n\r\nfunction buildRegistry(fhirVersion: FhirVersion, source: SourceBackend): DefinitionRegistry {\r\n return source === \"structure-def\"\r\n ? buildRegistryFromStructureDefinitions(fhirVersion)\r\n : buildRegistryFromSchemaJson(fhirVersion);\r\n}\r\n\r\nfunction resolveResourceName(registry: DefinitionRegistry, requested: string): string {\r\n const match = registry.resourceNames.find(\r\n (name) => name.toLowerCase() === requested.toLowerCase(),\r\n );\r\n if (!match) {\r\n throw new Error(\r\n `Unknown FHIR ${registry.fhirVersion.toUpperCase()} resource: \"${requested}\". ` +\r\n `Run \"fhir-oas list --fhir-version ${registry.fhirVersion}\" to see available resources.`,\r\n );\r\n }\r\n return match;\r\n}\r\n\r\n/** Lists the resource type names available for a FHIR version. */\r\nexport function listResources(\r\n fhirVersion: FhirVersion,\r\n source: SourceBackend = \"schema-json\",\r\n): string[] {\r\n assertFhirVersion(fhirVersion);\r\n return [...buildRegistry(fhirVersion, source).resourceNames].sort();\r\n}\r\n\r\nfunction assertFhirVersion(fhirVersion: string): asserts fhirVersion is FhirVersion {\r\n if (!FHIR_VERSIONS.includes(fhirVersion as FhirVersion)) {\r\n throw new Error(\r\n `Unsupported FHIR version \"${fhirVersion}\". Supported: ${FHIR_VERSIONS.join(\", \")}`,\r\n );\r\n }\r\n}\r\n\r\n/** The FHIR version a CapabilityStatement fhirVersion string belongs to. */\r\nfunction assertCapabilityFhirVersion(capability: Capability, fhirVersion: FhirVersion): void {\r\n const declared = capability.fhirVersion;\r\n if (!declared) return; // statement omitted it; trust the caller's --fhir-version\r\n const expectedMajor = FHIR_VERSION_NUMBERS[fhirVersion].split(\".\").slice(0, 2).join(\".\");\r\n // R4 (4.0.x) and R4B (4.3.x) share major 4 but differ in minor; compare the\r\n // major.minor prefix, tolerating the statement carrying only \"4.0\" etc.\r\n const declaredPrefix = declared.split(\".\").slice(0, 2).join(\".\");\r\n if (declaredPrefix && expectedMajor && declaredPrefix !== expectedMajor) {\r\n throw new Error(\r\n `CapabilityStatement targets FHIR ${declared}, but generation is for ` +\r\n `${fhirVersion.toUpperCase()} (${FHIR_VERSION_NUMBERS[fhirVersion]}). ` +\r\n `Set --fhir-version to match the server.`,\r\n );\r\n }\r\n}\r\n\r\n/** Resolves options.ig to an IgContext: a local path is loaded synchronously. */\r\nfunction resolveIg(options: GenerateOptions): IgContext {\r\n const ig = options.ig;\r\n if (!ig) throw new Error(\"--profile requires --ig: point at the IG package.\");\r\n if (typeof ig === \"string\") {\r\n return loadIgSync(ig, { coreValueSetFallback: buildCoreValueSetFallback(options.fhirVersion) });\r\n }\r\n return ig as IgContext;\r\n}\r\n\r\n/**\r\n * Generates an OpenAPI document covering the requested FHIR resources: their\r\n * full schema dependency closure plus the standard FHIR RESTful interactions.\r\n */\r\nexport function generateOpenApi(options: GenerateOptions): OpenApiDocument {\r\n assertFhirVersion(options.fhirVersion);\r\n const openApiVersion = options.openApiVersion ?? \"3.0.3\";\r\n if (openApiVersion !== \"3.0.3\" && openApiVersion !== \"3.1.0\") {\r\n throw new Error(`Unsupported OpenAPI version \"${openApiVersion}\". Supported: 3.0.3, 3.1.0`);\r\n }\r\n\r\n const registry = buildRegistry(options.fhirVersion, options.source ?? \"schema-json\");\r\n\r\n // A CapabilityStatement restricts generation to one server's declared\r\n // surface: which resources, interactions, search params, and operations.\r\n const capability = options.capability as Capability | undefined;\r\n const capabilityByResource = new Map<string, ResourceCapability>();\r\n if (capability) {\r\n assertCapabilityFhirVersion(capability, options.fhirVersion);\r\n for (const cap of capability.resources) {\r\n const match = registry.resourceNames.find(\r\n (name) => name.toLowerCase() === cap.type.toLowerCase(),\r\n );\r\n // Skip resource types the FHIR version doesn't define (custom/unknown).\r\n if (match) capabilityByResource.set(match, cap);\r\n }\r\n }\r\n\r\n const requested = (options.resources ?? []).map((r) => resolveResourceName(registry, r));\r\n if (requested.length === 0 && capabilityByResource.size === 0) {\r\n throw new Error(\r\n capability\r\n ? \"The CapabilityStatement declares no resources this FHIR version supports.\"\r\n : \"At least one FHIR resource name (or a --capability statement) is required\",\r\n );\r\n }\r\n\r\n // Apply IG profiles (if any) into the registry, mapping each profiled base\r\n // resource to its emitted schema name. The base resource is auto-included.\r\n const schemaByResource = new Map<string, string>();\r\n // In capability mode, the resource set is the statement's (optionally\r\n // narrowed to the explicitly requested ones); otherwise it's the requested.\r\n const resourceSet = new Set<string>(\r\n capability\r\n ? requested.length > 0\r\n ? requested.filter((r) => capabilityByResource.has(r))\r\n : [...capabilityByResource.keys()]\r\n : requested,\r\n );\r\n if (options.profiles?.length) {\r\n const ig = resolveIg(options);\r\n if (ig.fhirVersion !== options.fhirVersion) {\r\n throw new Error(\r\n `IG package \"${ig.name}\" targets FHIR ${ig.fhirVersion.toUpperCase()}, but generation ` +\r\n `is for ${options.fhirVersion.toUpperCase()}. Use --fhir-version ${ig.fhirVersion}.`,\r\n );\r\n }\r\n for (const profileId of options.profiles) {\r\n const applied = applyProfile(ig, profileId, registry);\r\n const base = resolveResourceName(registry, applied.resourceType);\r\n if (schemaByResource.has(base)) {\r\n throw new Error(\r\n `Multiple profiles target ${base}; generate one profiled resource per run.`,\r\n );\r\n }\r\n schemaByResource.set(base, applied.schemaName);\r\n resourceSet.add(base);\r\n }\r\n } else if (options.ig) {\r\n throw new Error(\"--ig requires --profile: name the profile(s) to apply.\");\r\n }\r\n\r\n const resources = [...resourceSet];\r\n const schemaFor = (resource: string) => schemaByResource.get(resource) ?? resource;\r\n\r\n // Operations: in capability mode, emit exactly the operations each resource\r\n // declares (mapped to known OperationDefinitions); otherwise --operations\r\n // emits every applicable operation.\r\n const operationPaths: Record<string, JsonSchemaNode> = {};\r\n const operationRoots: string[] = [];\r\n if (capability || options.operations) {\r\n const knownResources = new Set(registry.resourceNames);\r\n for (const resource of resources) {\r\n const cap = capabilityByResource.get(resource);\r\n if (capability && (!cap || cap.operations.size === 0)) continue;\r\n const result = buildOperationPaths(options.fhirVersion, resource, knownResources, {\r\n schemaFor,\r\n only: cap?.operations,\r\n });\r\n Object.assign(operationPaths, result.paths);\r\n operationRoots.push(...result.extraSchemaRoots);\r\n }\r\n }\r\n\r\n // Closure roots use the profiled schema name where a resource is profiled,\r\n // so the base schema is only emitted if something else references it.\r\n // Bundle and OperationOutcome are always present: search/history responses\r\n // are Bundles and every error response is an OperationOutcome.\r\n const roots = [\r\n ...new Set([...resources.map(schemaFor), \"Bundle\", \"OperationOutcome\", ...operationRoots]),\r\n ];\r\n const { schemas } = extractClosure(registry, roots, options.trim ?? {}, roots);\r\n\r\n const componentSchemas: Record<string, JsonSchemaNode> = {};\r\n const convertOptions = { noEnums: options.trim?.noEnums };\r\n for (const name of [...schemas.keys()].sort()) {\r\n componentSchemas[name] = convertSchema(schemas.get(name)!, openApiVersion, convertOptions);\r\n }\r\n\r\n const paths: Record<string, JsonSchemaNode> = {};\r\n for (const resource of resources) {\r\n const cap = capabilityByResource.get(resource);\r\n Object.assign(\r\n paths,\r\n buildResourcePaths(options.fhirVersion, resource, schemaFor(resource), {\r\n interactions: cap?.interactions,\r\n searchParamCodes: cap?.searchParamCodes,\r\n }),\r\n );\r\n }\r\n Object.assign(paths, operationPaths);\r\n\r\n const fhirNumber = FHIR_VERSION_NUMBERS[options.fhirVersion];\r\n const document: OpenApiDocument = {\r\n openapi: openApiVersion,\r\n info: {\r\n title:\r\n options.title ??\r\n `FHIR ${options.fhirVersion.toUpperCase()} REST API: ${resources.join(\", \")}`,\r\n description:\r\n `OpenAPI definition of the FHIR ${options.fhirVersion.toUpperCase()} (${fhirNumber}) ` +\r\n `RESTful interactions and JSON schemas for: ${resources.join(\", \")}. ` +\r\n \"Generated by fhir-openapi-translator from the official HL7 FHIR definitions. \" +\r\n \"Schema validity does not imply full FHIR conformance: profiles, terminology \" +\r\n \"bindings, and FHIRPath invariants are not represented.\",\r\n version: fhirNumber,\r\n },\r\n ...(options.baseUrl ? { servers: [{ url: options.baseUrl }] } : {}),\r\n tags: resources.map((resource) => ({\r\n name: resource,\r\n description: `Operations on the ${resource} resource`,\r\n })),\r\n paths,\r\n components: {\r\n parameters: commonSearchParameterComponents(),\r\n schemas: componentSchemas,\r\n },\r\n };\r\n return document;\r\n}\r\n","import fs from \"node:fs\";\r\nimport type { FhirInteraction } from \"./paths.js\";\r\n\r\n/**\r\n * Loads and parses a FHIR CapabilityStatement (a server's `/metadata`) into a\r\n * per-resource description of what the server actually supports, so a spec can\r\n * be generated to match exactly one server's surface rather than the full\r\n * standard interaction set.\r\n */\r\n\r\nexport interface ResourceCapability {\r\n type: string;\r\n interactions: Set<FhirInteraction>;\r\n /** Search parameter codes the server declares for this resource. */\r\n searchParamCodes: Set<string>;\r\n /** Operation codes and canonical URLs the server declares for this resource. */\r\n operations: Set<string>;\r\n}\r\n\r\nexport interface Capability {\r\n /** FHIR version string from the statement, e.g. \"4.0.1\" (may be undefined). */\r\n fhirVersion?: string;\r\n resources: ResourceCapability[];\r\n}\r\n\r\ninterface RawInteraction {\r\n code?: string;\r\n}\r\ninterface RawSearchParam {\r\n name?: string;\r\n}\r\ninterface RawOperation {\r\n name?: string;\r\n definition?: string;\r\n}\r\ninterface RawResource {\r\n type?: string;\r\n interaction?: RawInteraction[];\r\n searchParam?: RawSearchParam[];\r\n operation?: RawOperation[];\r\n}\r\ninterface RawCapabilityStatement {\r\n resourceType?: string;\r\n fhirVersion?: string;\r\n rest?: { mode?: string; resource?: RawResource[] }[];\r\n}\r\n\r\nconst KNOWN_INTERACTIONS = new Set<string>([\r\n \"read\",\r\n \"vread\",\r\n \"update\",\r\n \"patch\",\r\n \"delete\",\r\n \"history-instance\",\r\n \"history-type\",\r\n \"create\",\r\n \"search-type\",\r\n]);\r\n\r\nexport interface LoadCapabilityOptions {\r\n fetchImpl?: typeof fetch;\r\n}\r\n\r\n/**\r\n * Loads a CapabilityStatement from a local JSON file or an http(s) URL. A URL\r\n * that does not already end in `/metadata` has it appended, so a base server\r\n * URL works directly.\r\n */\r\nexport async function loadCapabilityStatement(\r\n input: string,\r\n options: LoadCapabilityOptions = {},\r\n): Promise<Capability> {\r\n let json: unknown;\r\n if (/^https?:\\/\\//i.test(input)) {\r\n const url = /\\/metadata\\/?$/.test(input) ? input : `${input.replace(/\\/$/, \"\")}/metadata`;\r\n const doFetch = options.fetchImpl ?? fetch;\r\n let response: Response;\r\n try {\r\n response = await doFetch(url, { headers: { Accept: \"application/fhir+json\" } });\r\n } catch (cause) {\r\n throw new Error(\r\n `Failed to fetch CapabilityStatement from ${url}: ${(cause as Error).message}. ` +\r\n `Save it locally (curl -H 'Accept: application/fhir+json' ${url} > metadata.json) ` +\r\n `and pass the file instead.`,\r\n );\r\n }\r\n if (!response.ok) {\r\n throw new Error(`CapabilityStatement request to ${url} returned ${response.status}.`);\r\n }\r\n json = await response.json();\r\n } else {\r\n if (!fs.existsSync(input)) throw new Error(`No such CapabilityStatement file: ${input}`);\r\n json = JSON.parse(fs.readFileSync(input, \"utf8\"));\r\n }\r\n return parseCapabilityStatement(json);\r\n}\r\n\r\nexport function parseCapabilityStatement(json: unknown): Capability {\r\n const statement = json as RawCapabilityStatement;\r\n if (statement?.resourceType !== \"CapabilityStatement\") {\r\n throw new Error(\r\n `Expected a CapabilityStatement resource, got \"${statement?.resourceType ?? \"unknown\"}\".`,\r\n );\r\n }\r\n\r\n // Merge resource entries across all `rest` blocks with mode \"server\".\r\n const byType = new Map<string, ResourceCapability>();\r\n for (const rest of statement.rest ?? []) {\r\n if (rest.mode && rest.mode !== \"server\") continue;\r\n for (const raw of rest.resource ?? []) {\r\n if (!raw.type) continue;\r\n let cap = byType.get(raw.type);\r\n if (!cap) {\r\n cap = {\r\n type: raw.type,\r\n interactions: new Set(),\r\n searchParamCodes: new Set(),\r\n operations: new Set(),\r\n };\r\n byType.set(raw.type, cap);\r\n }\r\n for (const i of raw.interaction ?? []) {\r\n if (i.code && KNOWN_INTERACTIONS.has(i.code)) cap.interactions.add(i.code as FhirInteraction);\r\n }\r\n for (const sp of raw.searchParam ?? []) {\r\n if (sp.name) cap.searchParamCodes.add(sp.name);\r\n }\r\n for (const op of raw.operation ?? []) {\r\n if (op.name) cap.operations.add(op.name);\r\n if (op.definition) cap.operations.add(op.definition);\r\n }\r\n }\r\n }\r\n\r\n if (byType.size === 0) {\r\n throw new Error(\r\n \"CapabilityStatement declares no server resources (rest[].resource). Nothing to generate.\",\r\n );\r\n }\r\n\r\n return {\r\n fhirVersion: statement.fhirVersion,\r\n resources: [...byType.values()].sort((a, b) => a.type.localeCompare(b.type)),\r\n };\r\n}\r\n","import { Document, parseDocument, isMap, type YAMLMap } from \"yaml\";\r\nimport type { OpenApiDocument } from \"./types.js\";\r\n\r\nexport interface MergeOptions {\r\n /** Overwrite conflicting entries instead of failing. */\r\n force?: boolean;\r\n}\r\n\r\nexport interface MergeConflict {\r\n /** e.g. \"components.schemas.Patient\" or \"paths./Patient/{id}\" */\r\n location: string;\r\n}\r\n\r\nexport class MergeConflictError extends Error {\r\n constructor(public readonly conflicts: MergeConflict[]) {\r\n super(\r\n \"Refusing to overwrite existing, differing entries (use --force to overwrite):\\n\" +\r\n conflicts.map((c) => ` - ${c.location}`).join(\"\\n\"),\r\n );\r\n this.name = \"MergeConflictError\";\r\n }\r\n}\r\n\r\n/** Top-level maps whose entries are merged key-by-key. */\r\nconst MERGED_SECTIONS: [string, string][] = [\r\n [\"paths\", \"\"],\r\n [\"components\", \"schemas\"],\r\n [\"components\", \"parameters\"],\r\n];\r\n\r\nfunction deepEqual(a: unknown, b: unknown): boolean {\r\n return JSON.stringify(a) === JSON.stringify(b);\r\n}\r\n\r\n/**\r\n * `ResourceList` is narrowed to the resource types requested at generation\r\n * time (see ir/registry.ts), so two generated specs legitimately differ in\r\n * it. Merging unions the two narrowings instead of conflicting. Returns\r\n * undefined when either side is not the expected oneOf-of-$refs shape.\r\n */\r\nfunction unionResourceList(existing: unknown, generated: unknown): unknown | undefined {\r\n const refsOf = (node: unknown): string[] | undefined => {\r\n if (!node || typeof node !== \"object\" || Array.isArray(node)) return undefined;\r\n const oneOf = (node as { oneOf?: unknown }).oneOf;\r\n if (!Array.isArray(oneOf)) return undefined;\r\n const refs: string[] = [];\r\n for (const item of oneOf) {\r\n if (!item || typeof item !== \"object\" || Object.keys(item).length !== 1) return undefined;\r\n const ref = (item as { $ref?: unknown }).$ref;\r\n if (typeof ref !== \"string\") return undefined;\r\n refs.push(ref);\r\n }\r\n return refs;\r\n };\r\n const existingRefs = refsOf(existing);\r\n const generatedRefs = refsOf(generated);\r\n if (!existingRefs || !generatedRefs) return undefined;\r\n return {\r\n ...(generated as Record<string, unknown>),\r\n oneOf: [...new Set([...existingRefs, ...generatedRefs])].map(($ref) => ({ $ref })),\r\n };\r\n}\r\n\r\ninterface MergePlan {\r\n doc: ReturnType<typeof parseDocument>;\r\n conflicts: MergeConflict[];\r\n additions: { path: (string | number)[]; value: unknown }[];\r\n}\r\n\r\n/**\r\n * Parses the existing YAML and computes what a merge would do: entries to add\r\n * (absent from the file, or ResourceList unions) and conflicting entries\r\n * (present with different content). Shared by merge and check.\r\n */\r\nfunction computeMergePlan(\r\n generated: OpenApiDocument,\r\n existingText: string,\r\n options: MergeOptions,\r\n): MergePlan {\r\n const doc = parseDocument(existingText);\r\n if (doc.errors.length > 0) {\r\n throw new Error(`Cannot parse existing YAML: ${doc.errors[0]?.message}`);\r\n }\r\n if (doc.contents !== null && !isMap(doc.contents)) {\r\n throw new Error(\"Existing file is not a YAML mapping; refusing to merge\");\r\n }\r\n\r\n const existingVersion = doc.getIn([\"openapi\"]);\r\n const generatedVersion = generated.openapi;\r\n if (existingVersion !== undefined && String(existingVersion) !== String(generatedVersion)) {\r\n throw new Error(\r\n `OpenAPI version mismatch: existing file declares ${String(existingVersion)}, ` +\r\n `generating ${String(generatedVersion)}. Regenerate with a matching --openapi-version.`,\r\n );\r\n }\r\n\r\n const conflicts: MergeConflict[] = [];\r\n const additions: { path: (string | number)[]; value: unknown }[] = [];\r\n\r\n // Top-level scalars/objects that only apply when absent.\r\n for (const key of [\"openapi\", \"info\", \"servers\"]) {\r\n if (generated[key] !== undefined && doc.getIn([key]) === undefined) {\r\n additions.push({ path: [key], value: generated[key] });\r\n }\r\n }\r\n\r\n // Tags: append missing tag names.\r\n const generatedTags = (generated.tags ?? []) as { name: string }[];\r\n if (generatedTags.length > 0) {\r\n const existingTags = doc.toJS()?.tags as { name: string }[] | undefined;\r\n if (existingTags === undefined) {\r\n additions.push({ path: [\"tags\"], value: generatedTags });\r\n } else {\r\n const existingNames = new Set(existingTags.map((t) => t?.name));\r\n let index = existingTags.length;\r\n for (const tag of generatedTags) {\r\n if (!existingNames.has(tag.name)) {\r\n additions.push({ path: [\"tags\", index++], value: tag });\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (const [section, subsection] of MERGED_SECTIONS) {\r\n const generatedSection = subsection\r\n ? ((generated[section] as Record<string, unknown> | undefined)?.[subsection] as\r\n | Record<string, unknown>\r\n | undefined)\r\n : (generated[section] as Record<string, unknown> | undefined);\r\n if (!generatedSection) continue;\r\n const basePath = subsection ? [section, subsection] : [section];\r\n\r\n for (const [key, value] of Object.entries(generatedSection)) {\r\n const existing = doc.getIn([...basePath, key], true);\r\n if (existing === undefined) {\r\n additions.push({ path: [...basePath, key], value });\r\n } else {\r\n const existingJs =\r\n typeof (existing as YAMLMap)?.toJS === \"function\"\r\n ? (existing as YAMLMap).toJS(doc)\r\n : existing;\r\n if (!deepEqual(existingJs, value)) {\r\n if (section === \"components\" && subsection === \"schemas\" && key === \"ResourceList\") {\r\n const union = unionResourceList(existingJs, value);\r\n if (union !== undefined) {\r\n if (!deepEqual(existingJs, union)) {\r\n additions.push({ path: [...basePath, key], value: union });\r\n }\r\n continue;\r\n }\r\n }\r\n conflicts.push({ location: [...basePath, key].join(\".\") });\r\n if (options.force) additions.push({ path: [...basePath, key], value });\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { doc, conflicts, additions };\r\n}\r\n\r\n/**\r\n * Merges a generated OpenAPI document into existing YAML text, preserving the\r\n * existing file's comments, anchors, and key order. Generated entries are\r\n * added alongside existing content; an existing entry with different content\r\n * is a conflict (all conflicts are reported; nothing is written unless every\r\n * conflict is resolved by `force`). Identical entries are left untouched, so\r\n * re-running the generator is idempotent.\r\n */\r\nexport function mergeIntoYaml(\r\n generated: OpenApiDocument,\r\n existingText: string,\r\n options: MergeOptions = {},\r\n): string {\r\n const { doc, conflicts, additions } = computeMergePlan(generated, existingText, options);\r\n if (doc.contents === null) {\r\n // Empty file: treat as a fresh write.\r\n return stringifyDocument(generated);\r\n }\r\n if (conflicts.length > 0 && !options.force) {\r\n throw new MergeConflictError(conflicts);\r\n }\r\n for (const { path, value } of additions) {\r\n doc.setIn(path, doc.createNode(value));\r\n }\r\n return doc.toString({ lineWidth: 0 });\r\n}\r\n\r\nexport interface SpecDiff {\r\n /** Entries the file lacks (dot paths), e.g. \"components.schemas.Patient\". */\r\n missing: string[];\r\n /** Entries present in the file but differing from generation. */\r\n changed: string[];\r\n /** True when the file already contains exactly what generation produces. */\r\n inSync: boolean;\r\n}\r\n\r\n/**\r\n * Compares existing spec text against a generated document without writing\r\n * anything — the CI drift guard behind `fhir-oas check`. The file is in sync\r\n * when a merge would be a no-op: nothing to add, nothing conflicting.\r\n */\r\nexport function diffAgainstYaml(generated: OpenApiDocument, existingText: string): SpecDiff {\r\n const { doc, conflicts, additions } = computeMergePlan(generated, existingText, {});\r\n if (doc.contents === null) {\r\n return { missing: [\"(entire document: file is empty)\"], changed: [], inSync: false };\r\n }\r\n const missing = additions.map((a) => a.path.join(\".\"));\r\n const changed = conflicts.map((c) => c.location);\r\n return { missing, changed, inSync: missing.length === 0 && changed.length === 0 };\r\n}\r\n\r\n/** Serializes a generated document to YAML text. */\r\nexport function stringifyDocument(generated: OpenApiDocument): string {\r\n const doc = new Document(generated);\r\n return doc.toString({ lineWidth: 0 });\r\n}\r\n"],"mappings":"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","names":["fs","path","path","ref","FHIR_JSON","SCHEMAS","ref","fhirContent","errorResponses","fhirContent","errorResponses","fs","ref","path"]}