fhir-openapi-translator 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,106 @@
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.2.0] - 2026-09-17
8
+
9
+ Search parameters gain derived metadata and a way to emit fewer of them.
10
+
11
+ No API or CLI breakage — every 0.1.1 invocation behaves as before. Generated
12
+ output does change, though, so **a committed spec will show drift**: on an R4
13
+ `Observation`, schemas and paths are byte-identical, 6 of 38 search parameters
14
+ gain `x-fhir-search-values`/`x-fhir-search-prefixes` and a fuller description,
15
+ and 4 more have trailing whitespace trimmed from HL7's description text.
16
+ Regenerate committed specs, or `fhir-oas check` will fail in CI.
17
+
18
+ ### Added
19
+
20
+ - `--search-params` limits which resource-specific search parameters are
21
+ emitted: a preset (`all`, `minimal`, `none`), an explicit code list
22
+ (`code,date,subject`), or per-resource (`Patient:name,birthdate`). Unknown
23
+ codes are an error rather than being silently dropped. Combines with
24
+ `--capability` by intersection. The common result parameters (`_id`,
25
+ `_count`, ...) are always emitted. `minimal` is tiered — common parameter
26
+ names first, then parameters addressing a top-level element directly, then
27
+ everything — so no resource that defines a search parameter is left with
28
+ none, while a median resource keeps 4. Presets can be tuned with `+code` and
29
+ `-code` (`minimal,+based-on`, `all,-note`), because no fixed rule can know
30
+ that `Observation.based-on`, `CarePlan.goal` or
31
+ `MedicationStatement.adherence` matter for their resource.
32
+ - `fhir-oas --version` (and `-V`) prints the installed version. It is read from
33
+ `package.json` at runtime rather than inlined at build time, so the CLI
34
+ cannot report a version the package does not have.
35
+ - `./package.json` is now a subpath export. Reaching for it previously raised
36
+ `ERR_PACKAGE_PATH_NOT_EXPORTED`, which some bundlers and
37
+ version-introspection scripts trip over.
38
+ - `x-fhir-search-values` on token search parameters bound to a required
39
+ ValueSet, and `x-fhir-search-prefixes` on `number`/`date`/`quantity`
40
+ parameters, listing the comparison prefixes (`eq`, `ne`, `gt`, `lt`, `ge`,
41
+ `le`, `sa`, `eb`, `ap`) their values may carry. Both are metadata rather than
42
+ schema constraints: an `enum` would reject the comma-OR, `system|code` and
43
+ `:modifier` forms that FHIR search permits.
44
+
45
+ ### Changed
46
+
47
+ - Search parameter descriptions are now derived from the definitions rather
48
+ than passed through from HL7's prose, which is not uniform — `Encounter-status`
49
+ spelled its codes out while `Observation-status` did not, though both are
50
+ token parameters over a required binding. Every parameter of a given kind now
51
+ reads the same way, and reports the codes its own FHIR version defines.
52
+ - Search parameters shared across resources carry a union expression
53
+ (`Patient.gender | Person.gender | ...`); the branch matching the resource
54
+ being generated is now resolved, so `MedicationRequest.status` and
55
+ `MedicationDispense.status` each report their own code list. Previously such
56
+ parameters were left unenumerated entirely.
57
+
58
+ ## [0.1.1] - 2026-09-13
59
+
60
+ Three correctness fixes. Specs generated with 0.1.0 should be regenerated:
61
+ all three produced silently wrong output rather than errors.
62
+
63
+ ### Fixed
64
+
65
+ - **Every schema was missing its `id` property.** The OpenAPI emitter stripped
66
+ the JSON Schema `id`/`$id` keywords everywhere, including inside `properties`
67
+ maps where `id` is an ordinary FHIR element name. 660 of 679 R4 definitions
68
+ declare one, so nearly every generated model lacked its resource id.
69
+ - **Binding enums were absent on R4B and R5.** Enum generation read inline
70
+ enums from the official `fhir.schema.json`, but HL7 stopped inlining them
71
+ after R4 (R4 has 246 occurrences; R4B has 27 and R5 has 26). Required-binding
72
+ codes are now resolved from the vendored definitions on every version, so
73
+ `--no-enums` is once again the only thing that turns them off.
74
+ - **Profiles failed to generate against real IG packages.** A `contentReference`
75
+ written in the absolute canonical form that IG snapshot generators emit
76
+ (`http://hl7.org/fhir/StructureDefinition/Observation#Observation.referenceRange`)
77
+ was parsed as though it were the core `#Observation.referenceRange` short
78
+ form, producing a mangled schema name and aborting generation. US Core Blood
79
+ Pressure, among others, could not be generated at all.
80
+
81
+ ### Documentation
82
+
83
+ - Corrected the `fixed[x]` → `const` claim. Real IGs usually pin values at
84
+ paths _inside_ a datatype or slice (`Observation.category.coding.code`).
85
+ Those datatypes are emitted once as shared schemas and referenced by `$ref`,
86
+ so such constraints cannot be represented and are **not** applied. Only fixed
87
+ values on elements a profile emits as their own property become a `const`.
88
+
89
+ ### Testing
90
+
91
+ - Added `claims.test.ts`: one assertion block per README capability claim,
92
+ across every FHIR version, OpenAPI target and backend it claims to support.
93
+ - Added `fidelity.test.ts`: field-level checks that use the vendored FHIR
94
+ definitions as an oracle instead of hand-written expectations. Covers 45
95
+ resources drawn from the Foundation, Base, Clinical, Financial and
96
+ Specialized modules, in R4/R4B/R5, down to backbone depth — cardinality,
97
+ requiredness, primitive JSON types, choice expansion, `_field` primitive
98
+ extension siblings, and `$ref` resolution.
99
+
100
+ All three bugs above shared a cause: coverage that confirmed expectations at a
101
+ single point of a multi-point matrix. Enums were asserted only on R4, profiles
102
+ only on `us-core-patient`, and `id` never at all.
103
+
104
+ ## [0.1.0] - 2026-09-12
105
+
106
+ 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
@@ -45,6 +50,9 @@ fhir-oas generate Patient -f r4 --operations
45
50
  # Apply an Implementation Guide profile (e.g. US Core)
46
51
  fhir-oas generate Patient -f r4 --ig hl7.fhir.us.core@5.0.1 --profile us-core-patient
47
52
 
53
+ # Emit only the search parameters your deployment indexes (38 -> 9 here)
54
+ fhir-oas generate Observation -f r4 --search-params minimal,+based-on
55
+
48
56
  # Match one server's declared surface (reads its /metadata)
49
57
  fhir-oas generate -f r4 --capability https://server.example.org/fhir
50
58
 
@@ -71,16 +79,17 @@ const doc = generateOpenApi({ resources: ["Patient"], fhirVersion: "r4" });
71
79
  - **Custom operations** from the official OperationDefinitions.
72
80
  - **Profiles / IGs** — apply US Core-style constraints from any IG package.
73
81
  - **CapabilityStatement-driven** — generate exactly what a server supports.
82
+ - **Search parameters, documented and tunable** — accepted codes and comparison prefixes per FHIR version; emit only the ones your deployment indexes.
74
83
  - **Merge mode & drift guard** — coexist with hand-written specs, catch drift in CI.
75
84
 
76
85
  ## Where it fits
77
86
 
78
- | | fhir-openapi-translator | HAPI / Firely |
79
- |---|:---:|:---:|
80
- | Output | OpenAPI (→ any language) | Java / .NET models |
81
- | Runtime needed | none (offline CLI) | a running server / SDK |
82
- | US Core / IG profiles | ✅ | ✅ |
83
- | Per-resource, codegen-tuned specs | ✅ | — |
87
+ | | fhir-openapi-translator | HAPI / Firely |
88
+ | --------------------------------- | :----------------------: | :--------------------: |
89
+ | Output | OpenAPI (→ any language) | Java / .NET models |
90
+ | Runtime needed | none (offline CLI) | a running server / SDK |
91
+ | US Core / IG profiles | ✅ | ✅ |
92
+ | Per-resource, codegen-tuned specs | ✅ | — |
84
93
 
85
94
  **Complements a FHIR SDK, doesn't replace it.** Keep HAPI or Firely for server-side models and conformance — this produces the OpenAPI contract around them: for consumers in any language, and for the tooling you already run (gateways, mock servers, contract tests).
86
95
 
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 ?? "";
@@ -495,6 +496,148 @@ function applyProfile(context, requested, registry) {
495
496
  return { schemaName, resourceType: profile.type, url: profile.url };
496
497
  }
497
498
 
499
+ // src/searchParams.ts
500
+ var SEARCH_PREFIXES = ["eq", "ne", "gt", "lt", "ge", "le", "sa", "eb", "ap"];
501
+ var PREFIXABLE_TYPES = /* @__PURE__ */ new Set(["number", "date", "quantity"]);
502
+ function prefixesFor(searchParamType) {
503
+ return PREFIXABLE_TYPES.has(searchParamType) ? SEARCH_PREFIXES : void 0;
504
+ }
505
+ function requiredBindingCodes(fhirVersion) {
506
+ const index = /* @__PURE__ */ new Map();
507
+ for (const sd of loadStructureDefinitions(fhirVersion)) {
508
+ for (const el of sd.elements) {
509
+ if (el.binding?.strength === "required" && el.binding.codes?.length) {
510
+ index.set(el.path, el.binding.codes);
511
+ }
512
+ }
513
+ }
514
+ return index;
515
+ }
516
+ var bindingCache = /* @__PURE__ */ new Map();
517
+ function searchParamCodes(fhirVersion, resource, type, expression) {
518
+ if (type !== "token" || !expression) return void 0;
519
+ const branch = expression.split("|").map((part) => part.trim()).find((part) => part.startsWith(`${resource}.`) || !expression.includes("|"));
520
+ if (!branch || !/^[A-Za-z]+(?:\.[A-Za-z]+)+$/.test(branch)) return void 0;
521
+ if (branch.split(".")[0] !== resource) return void 0;
522
+ let index = bindingCache.get(fhirVersion);
523
+ if (!index) {
524
+ index = requiredBindingCodes(fhirVersion);
525
+ bindingCache.set(fhirVersion, index);
526
+ }
527
+ return index.get(branch);
528
+ }
529
+ var COMMON_CODES = /* @__PURE__ */ new Set([
530
+ "identifier",
531
+ "status",
532
+ "patient",
533
+ "subject",
534
+ "encounter",
535
+ "code",
536
+ "category",
537
+ "date",
538
+ "type",
539
+ "url",
540
+ "name"
541
+ ]);
542
+ function directElementBranch(resource, expression) {
543
+ if (!expression) return void 0;
544
+ const branch = expression.split("|").map((part) => part.trim()).find((part) => part.startsWith(`${resource}.`));
545
+ return branch && /^[A-Za-z]+\.[A-Za-z]+$/.test(branch) ? branch : void 0;
546
+ }
547
+ function minimalCodes(resource, available) {
548
+ const common = available.filter((sp) => COMMON_CODES.has(sp.code));
549
+ if (common.length > 0) return new Set(common.map((sp) => sp.code));
550
+ const direct = available.filter((sp) => directElementBranch(resource, sp.expression));
551
+ if (direct.length > 0) return new Set(direct.map((sp) => sp.code));
552
+ return new Set(available.map((sp) => sp.code));
553
+ }
554
+ var PRESETS = /* @__PURE__ */ new Set(["all", "minimal", "none"]);
555
+ function parseOne(value) {
556
+ const parts = value.split(",").map((part) => part.trim()).filter(Boolean);
557
+ if (parts.length === 0) throw new Error(`--search-params: empty selection in "${value}"`);
558
+ const add = /* @__PURE__ */ new Set();
559
+ const remove = /* @__PURE__ */ new Set();
560
+ const literal = /* @__PURE__ */ new Set();
561
+ let preset;
562
+ for (const [index, part] of parts.entries()) {
563
+ if (part.startsWith("+") || part.startsWith("-")) {
564
+ const code = part.slice(1);
565
+ if (!code) throw new Error(`--search-params: "${part}" names no parameter`);
566
+ (part.startsWith("+") ? add : remove).add(code);
567
+ continue;
568
+ }
569
+ const lower = part.toLowerCase();
570
+ if (PRESETS.has(lower)) {
571
+ if (index !== 0) {
572
+ throw new Error(
573
+ `--search-params: preset "${part}" must come first in "${value}" (e.g. "minimal,+${parts[0]}").`
574
+ );
575
+ }
576
+ preset = lower;
577
+ continue;
578
+ }
579
+ literal.add(part);
580
+ }
581
+ if (preset && literal.size > 0) {
582
+ throw new Error(
583
+ `--search-params: "${value}" mixes the preset "${preset}" with bare codes ${[...literal].map((c) => `"${c}"`).join(", ")}. Prefix them with + to add to the preset, or drop the preset to list codes exactly.`
584
+ );
585
+ }
586
+ const rule = { base: preset ?? literal };
587
+ if (add.size > 0) rule.add = add;
588
+ if (remove.size > 0) rule.remove = remove;
589
+ return rule;
590
+ }
591
+ function parseSearchParamSpec(specs) {
592
+ const selection = {};
593
+ const byResource = /* @__PURE__ */ new Map();
594
+ for (const spec of specs) {
595
+ const colon = spec.indexOf(":");
596
+ if (colon > 0 && /^[A-Z][A-Za-z]*$/.test(spec.slice(0, colon))) {
597
+ const resource = spec.slice(0, colon);
598
+ if (byResource.has(resource)) {
599
+ throw new Error(`--search-params: ${resource} given more than once`);
600
+ }
601
+ byResource.set(resource, parseOne(spec.slice(colon + 1)));
602
+ continue;
603
+ }
604
+ if (selection.default !== void 0) {
605
+ throw new Error(
606
+ `--search-params: more than one unscoped selection ("${spec}"). Scope them per resource (Patient:name,birthdate) or pass a single list.`
607
+ );
608
+ }
609
+ selection.default = parseOne(spec);
610
+ }
611
+ if (byResource.size > 0) selection.byResource = byResource;
612
+ return selection;
613
+ }
614
+ function resolveSearchParamCodes(selection, fhirVersion, resource) {
615
+ const rule = selection?.byResource?.get(resource) ?? selection?.default;
616
+ if (rule === void 0) return void 0;
617
+ if (rule.base === "all" && !rule.add && !rule.remove) return void 0;
618
+ const available = loadSearchParameters(fhirVersion).filter((sp) => sp.base.includes(resource));
619
+ const codes = new Set(available.map((sp) => sp.code));
620
+ const named = [
621
+ ...typeof rule.base === "string" ? [] : rule.base,
622
+ ...rule.add ?? [],
623
+ ...rule.remove ?? []
624
+ ];
625
+ const unknown = named.filter((code) => !codes.has(code));
626
+ if (unknown.length > 0) {
627
+ throw new Error(
628
+ `--search-params: ${resource} has no search parameter ${unknown.map((c) => `"${c}"`).join(", ")} in ${fhirVersion.toUpperCase()}. Run "fhir-oas generate ${resource} -f ${fhirVersion}" to see the available codes.`
629
+ );
630
+ }
631
+ let selected;
632
+ if (rule.base === "all") selected = new Set(codes);
633
+ else if (rule.base === "none") selected = /* @__PURE__ */ new Set();
634
+ else if (rule.base === "minimal") selected = minimalCodes(resource, available);
635
+ else selected = new Set(rule.base);
636
+ for (const code of rule.add ?? []) selected.add(code);
637
+ for (const code of rule.remove ?? []) selected.delete(code);
638
+ return selected;
639
+ }
640
+
498
641
  // src/backends/schemaJson.ts
499
642
  function buildRegistryFromSchemaJson(fhirVersion) {
500
643
  const schema = loadFhirSchema(fhirVersion);
@@ -508,8 +651,44 @@ function buildRegistryFromSchemaJson(fhirVersion) {
508
651
  return props?.resourceType !== void 0 && "const" in (props.resourceType ?? {});
509
652
  }).map(([name]) => name);
510
653
  }
654
+ applyBindingEnums(definitions, fhirVersion);
511
655
  return { fhirVersion, definitions, resourceNames };
512
656
  }
657
+ var lowerFirst = (s) => s.charAt(0).toLowerCase() + s.slice(1);
658
+ function elementPathFor(definitionName, property) {
659
+ const [root, ...backbones] = definitionName.split("_");
660
+ return [root, ...backbones.map(lowerFirst), property].join(".");
661
+ }
662
+ function bindingCodeIndex(fhirVersion) {
663
+ const index = /* @__PURE__ */ new Map();
664
+ for (const sd of loadStructureDefinitions(fhirVersion)) {
665
+ for (const el of sd.elements) {
666
+ if (el.binding?.strength === "required" && el.binding.codes?.length) {
667
+ index.set(el.path, el.binding.codes);
668
+ }
669
+ }
670
+ }
671
+ return index;
672
+ }
673
+ function applyBindingEnums(definitions, fhirVersion) {
674
+ const codesByPath = bindingCodeIndex(fhirVersion);
675
+ const isCodeRef = (node) => !!node && node.$ref === "#/definitions/code";
676
+ for (const [name, definition] of definitions) {
677
+ const properties = definition.properties;
678
+ if (!properties) continue;
679
+ for (const [property, schema] of Object.entries(properties)) {
680
+ const codes = codesByPath.get(elementPathFor(name, property));
681
+ if (!codes) continue;
682
+ const description = schema.description;
683
+ const withDescription = (node) => description ? { description, ...node } : node;
684
+ if (isCodeRef(schema)) {
685
+ properties[property] = withDescription({ enum: [...codes] });
686
+ } else if (schema.type === "array" && isCodeRef(schema.items)) {
687
+ properties[property] = withDescription({ type: "array", items: { enum: [...codes] } });
688
+ }
689
+ }
690
+ }
691
+ }
513
692
 
514
693
  // src/backends/structureDefinition.ts
515
694
  function buildRegistryFromStructureDefinitions(fhirVersion) {
@@ -593,9 +772,22 @@ function convertNode(node, target, options) {
593
772
  switch (key) {
594
773
  case "$schema":
595
774
  case "$comment":
775
+ // Draft-04/06 schema keywords. These are only keywords at schema-node
776
+ // level: inside `properties` the same names are FHIR element names, and
777
+ // nearly every FHIR element has an `id`. See the "properties" case.
596
778
  case "id":
597
779
  case "$id":
598
780
  break;
781
+ case "properties": {
782
+ const converted = {};
783
+ for (const [propertyName, propertySchema] of Object.entries(
784
+ value ?? {}
785
+ )) {
786
+ converted[propertyName] = convertNode(propertySchema, target, options);
787
+ }
788
+ out.properties = converted;
789
+ break;
790
+ }
599
791
  case "$ref":
600
792
  out.$ref = typeof value === "string" && value.startsWith(DEFINITIONS_REF) ? COMPONENTS_REF + value.slice(DEFINITIONS_REF.length) : value;
601
793
  break;
@@ -870,16 +1062,41 @@ function commonSearchParameterComponents() {
870
1062
  }
871
1063
  return out;
872
1064
  }
1065
+ function isCodeListDescription(description) {
1066
+ return description.includes("|") && /^[A-Za-z0-9\-.\s|+]+$/.test(description);
1067
+ }
1068
+ function describeSearchParameter(description, codes, prefixes) {
1069
+ let base = description.trim();
1070
+ if (codes?.length && isCodeListDescription(base)) base = "";
1071
+ const notes = [];
1072
+ if (codes?.length) notes.push(`Accepted values: ${codes.join(" | ")}.`);
1073
+ if (prefixes?.length) {
1074
+ notes.push(`Values may carry a comparison prefix (${prefixes.join(", ")}), e.g. ge2021-01-01.`);
1075
+ }
1076
+ if (notes.length === 0) return base;
1077
+ if (base.length === 0) return notes.join(" ");
1078
+ const separator = base.includes("\n") ? "\n\n" : /[.?!]$/.test(base) ? " " : ". ";
1079
+ return `${base}${separator}${notes.join(" ")}`;
1080
+ }
873
1081
  function resourceSearchParameters(fhirVersion, resource, only) {
874
- return loadSearchParameters(fhirVersion).filter((sp) => sp.base.includes(resource) && (!only || only.has(sp.code))).sort((a, b) => a.code.localeCompare(b.code)).map((sp) => ({
875
- name: sp.code,
876
- in: "query",
877
- required: false,
878
- description: sp.description,
879
- // FHIR search values carry prefixes and modifiers, so all are strings.
880
- schema: { type: "string" },
881
- "x-fhir-search-type": sp.type
882
- }));
1082
+ return loadSearchParameters(fhirVersion).filter((sp) => sp.base.includes(resource) && (!only || only.has(sp.code))).sort((a, b) => a.code.localeCompare(b.code)).map((sp) => {
1083
+ const codes = searchParamCodes(fhirVersion, resource, sp.type, sp.expression);
1084
+ const prefixes = prefixesFor(sp.type);
1085
+ return {
1086
+ name: sp.code,
1087
+ in: "query",
1088
+ required: false,
1089
+ description: describeSearchParameter(sp.description ?? "", codes, prefixes),
1090
+ // FHIR search values carry prefixes and modifiers, so all are strings.
1091
+ // The accepted values are advertised via x-fhir-search-values rather
1092
+ // than `enum`, which would reject the comma-OR (`status=final,amended`),
1093
+ // system|code and `:modifier` forms that FHIR search permits.
1094
+ schema: { type: "string" },
1095
+ "x-fhir-search-type": sp.type,
1096
+ ...codes?.length ? { "x-fhir-search-values": codes } : {},
1097
+ ...prefixes?.length ? { "x-fhir-search-prefixes": prefixes } : {}
1098
+ };
1099
+ });
883
1100
  }
884
1101
  var historyParameters = () => [
885
1102
  { $ref: `${PARAMETERS}_count` },
@@ -1165,11 +1382,13 @@ function generateOpenApi(options) {
1165
1382
  const paths = {};
1166
1383
  for (const resource of resources) {
1167
1384
  const cap = capabilityByResource.get(resource);
1385
+ const selected = resolveSearchParamCodes(options.searchParams, options.fhirVersion, resource);
1386
+ const searchParamCodes2 = cap?.searchParamCodes && selected ? new Set([...selected].filter((code) => cap.searchParamCodes.has(code))) : selected ?? cap?.searchParamCodes;
1168
1387
  Object.assign(
1169
1388
  paths,
1170
1389
  buildResourcePaths(options.fhirVersion, resource, schemaFor(resource), {
1171
1390
  interactions: cap?.interactions,
1172
- searchParamCodes: cap?.searchParamCodes
1391
+ searchParamCodes: searchParamCodes2
1173
1392
  })
1174
1393
  );
1175
1394
  }
@@ -1417,6 +1636,7 @@ export {
1417
1636
  loadIg,
1418
1637
  loadIgSync,
1419
1638
  buildCoreValueSetFallback,
1639
+ parseSearchParamSpec,
1420
1640
  listResources,
1421
1641
  generateOpenApi,
1422
1642
  loadCapabilityStatement,
@@ -1426,4 +1646,4 @@ export {
1426
1646
  diffAgainstYaml,
1427
1647
  stringifyDocument
1428
1648
  };
1429
- //# sourceMappingURL=chunk-G3DCRADV.js.map
1649
+ //# sourceMappingURL=chunk-RRAIF3A2.js.map