babelfhir-ts 1.6.2 → 1.6.4

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/README.md CHANGED
@@ -36,7 +36,7 @@
36
36
  <a href="https://www.npmjs.com/package/@babelfhir-ts/dicomweb"><img src="https://img.shields.io/npm/v/@babelfhir-ts/dicomweb.svg?label=%40babelfhir-ts%2Fdicomweb" alt="dicomweb"></a>
37
37
  </p>
38
38
 
39
- **BabelFHIR-TS** transforms FHIR® StructureDefinitions into production-ready TypeScript code with full type safety and built-in validation. Unlike generic FHIR type definitions, BabelFHIR-TS generates **profile-aware** interfaces that understand your Implementation Guide's constraints, extensions, and slicing rules.
39
+ **BabelFHIR-TS** transforms FHIR® StructureDefinitions into production-ready TypeScript code with full type safety and built-in validation. BabelFHIR-TS generates **profile-aware** interfaces that understand your Implementation Guide's constraints, extensions, and slicing rules.
40
40
 
41
41
  ### What you get
42
42
 
@@ -48,118 +48,7 @@
48
48
  - **Zero manual mapping**—consume any FHIR package or Implementation Guide directly from registries
49
49
  - **Fast and lightweight**—the CLI pulls no FHIRPath engine of its own; generated packages declare `fhirpath` as a *peer* dependency (`>=4.9.1 <6`), so the host app owns the version
50
50
  - **Type-safe FHIR client** — generated client extends [`@babelfhir-ts/client-r4`](https://www.npmjs.com/package/@babelfhir-ts/client-r4) / [`client-r4b`](https://www.npmjs.com/package/@babelfhir-ts/client-r4b) / [`client-r5`](https://www.npmjs.com/package/@babelfhir-ts/client-r5) with profile-specific methods (e.g., `.uSCorePatientProfile()`, `.pASClaim()`) on top of base resource accessors
51
- - **Install any FHIR profile as a node module**—use `babelfhir-ts install` to add Implementation Guides directly to your project
52
-
53
- <!-- PARITY-BADGES:START - Do not remove or modify this section -->
54
- ## Continuous Validation
55
-
56
- Every push to `develop` and `main` runs the parity pipeline, which validates generated code against real-world FHIR Implementation Guides. (Pull requests run the faster `CI` workflow: typecheck, unit tests, and generated-artifact drift checks.) For each IG, the pipeline:
57
-
58
- 1. Downloads the FHIR package from a registry
59
- 2. Generates TypeScript interfaces, validators, and classes
60
- 3. Compiles the output with `tsc` (zero errors required)
61
- 4. Generates `empty()` and `random()` test resources for every profile
62
- 5. Validates those resources against two independent external FHIR validators
63
-
64
- ### Validated Implementation Guides (31)
65
-
66
- Every parity run validates **31 real-world IGs** (29 R4, 2 R5). The list is not duplicated here — it is generated from the parity suite's own source of truth into [`parity-matrix.json`](./parity-matrix.json).
67
-
68
- Each validated IG is also published as a ready-to-install package — `@max-health-inc/fhir-<name>` — so you do not have to generate it yourself:
69
-
70
- **[→ Browse the FHIR IG registry](https://github.com/orgs/Max-Health-Inc/packages?ecosystem=npm&q=fhir-)**
71
-
72
- ```bash
73
- # GitHub Packages needs the scope mapped, and a token with read:packages
74
- echo "@max-health-inc:registry=https://npm.pkg.github.com" >> .npmrc
75
- npm install @max-health-inc/fhir-us-core
76
- ```
77
-
78
- Published by [Max-Health-Inc/fhir-igs](https://github.com/Max-Health-Inc/fhir-igs), which pins a babelfhir-ts version and republishes an IG only when the IG version, the pinned generator, or the generation flags actually change.
79
-
80
- ### Validation with the Firely SDK Validator
81
-
82
- The `firely` job validates generated resources using the [Firely SDK Validator](https://docs.fire.ly/projects/Firely-NET-SDK/validation.html) (`Firely.Fhir.Validation`, v3.x) running on the Firely .NET SDK (`Hl7.Fhir`, v6.x) — two separately versioned packages. Results are published as live badges:
83
-
84
- <details><summary>Per-IG results</summary>
85
-
86
- ![US Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-us-core.json)
87
- ![QI-Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-qicore.json)
88
- ![mCODE](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-mcode.json)
89
- ![SDOH Clinical Care](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-sdoh.json)
90
- ![NDH (National Directory)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ndh.json)
91
- ![CARIN BB](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-carin-bb.json)
92
- ![CQF Measures](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-cqfmeasures.json)
93
- ![Physical Activity](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-physical-activity.json)
94
- ![DaVinci PAS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-pas.json)
95
- ![DaVinci CDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-cdex.json)
96
- ![DaVinci PDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-pdex.json)
97
- ![DaVinci DTR](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-dtr.json)
98
- ![DaVinci Alerts](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-alerts.json)
99
- ![DaVinci DEQM](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-deqm.json)
100
- ![DaVinci Drug Formulary](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-drug-formulary.json)
101
- ![IPS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ips.json)
102
- ![SMART App Launch](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-smart.json)
103
- ![SDC (Structured Data Capture)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-sdc.json)
104
- ![Genomics Reporting](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-genomics-reporting.json)
105
- ![CPG (Clinical Practice Guidelines)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-cpg.json)
106
- ![ISiK Basis](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-isik-basis.json)
107
- ![KBV eRezept](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-kbv-erp.json)
108
- ![DE Basisprofil](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-de-basisprofil.json)
109
- ![ISiK Medikation](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-isik-medikation.json)
110
- ![CH Core (Switzerland)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ch-core.json)
111
- ![AU Core (Australia)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-au-core.json)
112
- ![PIXm](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-pixm.json)
113
- ![MHD](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-mhd.json)
114
- ![vitals](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-vitals.json)
115
-
116
- </details>
117
-
118
- ### Validation with HL7 Java Validator
119
-
120
- The `hl7` job validates the same artifacts using the [official HL7 FHIR Validator](https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator), the reference implementation for FHIR conformance checking:
121
-
122
- <details><summary>Per-IG results</summary>
123
-
124
- ![US Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-us-core.json)
125
- ![QI-Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-qicore.json)
126
- ![mCODE](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-mcode.json)
127
- ![SDOH Clinical Care](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-sdoh.json)
128
- ![NDH (National Directory)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ndh.json)
129
- ![CARIN BB](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-carin-bb.json)
130
- ![CQF Measures](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-cqfmeasures.json)
131
- ![Physical Activity](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-physical-activity.json)
132
- ![DaVinci PAS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-pas.json)
133
- ![DaVinci CDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-cdex.json)
134
- ![DaVinci PDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-pdex.json)
135
- ![DaVinci DTR](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-dtr.json)
136
- ![DaVinci Alerts](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-alerts.json)
137
- ![DaVinci DEQM](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-deqm.json)
138
- ![DaVinci Drug Formulary](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-drug-formulary.json)
139
- ![IPS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ips.json)
140
- ![SMART App Launch](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-smart.json)
141
- ![SDC (Structured Data Capture)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-sdc.json)
142
- ![Genomics Reporting](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-genomics-reporting.json)
143
- ![CPG (Clinical Practice Guidelines)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-cpg.json)
144
- ![ISiK Basis](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-isik-basis.json)
145
- ![KBV eRezept](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-kbv-erp.json)
146
- ![DE Basisprofil](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-de-basisprofil.json)
147
- ![ISiK Medikation](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-isik-medikation.json)
148
- ![CH Core (Switzerland)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ch-core.json)
149
- ![AU Core (Australia)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-au-core.json)
150
- ![PIXm](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-pixm.json)
151
- ![MHD](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-mhd.json)
152
- ![vitals](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-vitals.json)
153
-
154
- </details>
155
-
156
- > External-validator badges cover the 29 R4/R4B IGs. R5 packages are generated and typechecked, but neither external validator publishes R5 badges yet.
157
-
158
- > Terminology validation requires a tx server. The pipeline uses `--tx-server https://tx.fhir.org/{r4|r5}` (matching the package's FHIR version) during generation to expand ValueSets and produce valid codes.
159
-
160
- 📊 **[Full Report](https://max-health-inc.github.io/BabelFHIR-TS/)**
161
- <!-- HL7-PARITY-BADGES:END -->
162
- <!-- PARITY-BADGES:END -->
51
+ - **Install any FHIR profile as a node module**—use `babelfhir-ts install` to add Implementation Guides (FHIR Packages) directly to your project
163
52
 
164
53
  ## Installation
165
54
 
@@ -274,6 +163,117 @@ Full documentation is available at **[max-health-inc.github.io/BabelFHIR-TS/docs
274
163
  - [Limitations](https://max-health-inc.github.io/BabelFHIR-TS/docs/limitations) — edge cases, random() caveats
275
164
  - [Contributing](https://max-health-inc.github.io/BabelFHIR-TS/docs/contributing) — dev setup, scripts, project structure
276
165
 
166
+ <!-- PARITY-BADGES:START - Do not remove or modify this section -->
167
+ ## Continuous Validation
168
+
169
+ Every push to `develop` and `main` runs the parity pipeline, which validates generated code against real-world FHIR Implementation Guides. (Pull requests run the faster `CI` workflow: typecheck, unit tests, and generated-artifact drift checks.) For each IG, the pipeline:
170
+
171
+ 1. Downloads the FHIR package from a registry
172
+ 2. Generates TypeScript interfaces, validators, and classes
173
+ 3. Compiles the output with `tsc` (zero errors required)
174
+ 4. Generates `empty()` and `random()` test resources for every profile
175
+ 5. Validates those resources against two independent external FHIR validators
176
+
177
+ ### Validated Implementation Guides (31)
178
+
179
+ Every parity run validates **31 real-world IGs** (29 R4, 2 R5). The list is not duplicated here — it is generated from the parity suite's own source of truth into [`parity-matrix.json`](./parity-matrix.json).
180
+
181
+ Each validated IG is also published as a ready-to-install package — `@max-health-inc/fhir-<name>` — so you do not have to generate it yourself:
182
+
183
+ **[→ Browse the FHIR IG registry](https://github.com/orgs/Max-Health-Inc/packages?ecosystem=npm&q=fhir-)**
184
+
185
+ ```bash
186
+ # GitHub Packages needs the scope mapped, and a token with read:packages
187
+ echo "@max-health-inc:registry=https://npm.pkg.github.com" >> .npmrc
188
+ npm install @max-health-inc/fhir-us-core
189
+ ```
190
+
191
+ Published by [Max-Health-Inc/fhir-igs](https://github.com/Max-Health-Inc/fhir-igs), which pins a babelfhir-ts version and republishes an IG only when the IG version, the pinned generator, or the generation flags actually change.
192
+
193
+ ### Validation with the Firely SDK Validator
194
+
195
+ The `firely` job validates generated resources using the [Firely SDK Validator](https://docs.fire.ly/projects/Firely-NET-SDK/validation.html) (`Firely.Fhir.Validation`, v3.x) running on the Firely .NET SDK (`Hl7.Fhir`, v6.x) — two separately versioned packages. Results are published as live badges:
196
+
197
+ <details><summary>Per-IG results</summary>
198
+
199
+ ![US Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-us-core.json)
200
+ ![QI-Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-qicore.json)
201
+ ![mCODE](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-mcode.json)
202
+ ![SDOH Clinical Care](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-sdoh.json)
203
+ ![NDH (National Directory)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ndh.json)
204
+ ![CARIN BB](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-carin-bb.json)
205
+ ![CQF Measures](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-cqfmeasures.json)
206
+ ![Physical Activity](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-physical-activity.json)
207
+ ![DaVinci PAS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-pas.json)
208
+ ![DaVinci CDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-cdex.json)
209
+ ![DaVinci PDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-pdex.json)
210
+ ![DaVinci DTR](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-dtr.json)
211
+ ![DaVinci Alerts](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-alerts.json)
212
+ ![DaVinci DEQM](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-deqm.json)
213
+ ![DaVinci Drug Formulary](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-davinci-drug-formulary.json)
214
+ ![IPS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ips.json)
215
+ ![SMART App Launch](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-smart.json)
216
+ ![SDC (Structured Data Capture)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-sdc.json)
217
+ ![Genomics Reporting](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-genomics-reporting.json)
218
+ ![CPG (Clinical Practice Guidelines)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-cpg.json)
219
+ ![ISiK Basis](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-isik-basis.json)
220
+ ![KBV eRezept](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-kbv-erp.json)
221
+ ![DE Basisprofil](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-de-basisprofil.json)
222
+ ![ISiK Medikation](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-isik-medikation.json)
223
+ ![CH Core (Switzerland)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-ch-core.json)
224
+ ![AU Core (Australia)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-au-core.json)
225
+ ![PIXm](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-pixm.json)
226
+ ![MHD](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-mhd.json)
227
+ ![vitals](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-vitals.json)
228
+
229
+ </details>
230
+
231
+ ### Validation with HL7 Java Validator
232
+
233
+ The `hl7` job validates the same artifacts using the [official HL7 FHIR Validator](https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator), the reference implementation for FHIR conformance checking:
234
+
235
+ <details><summary>Per-IG results</summary>
236
+
237
+ ![US Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-us-core.json)
238
+ ![QI-Core](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-qicore.json)
239
+ ![mCODE](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-mcode.json)
240
+ ![SDOH Clinical Care](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-sdoh.json)
241
+ ![NDH (National Directory)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ndh.json)
242
+ ![CARIN BB](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-carin-bb.json)
243
+ ![CQF Measures](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-cqfmeasures.json)
244
+ ![Physical Activity](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-physical-activity.json)
245
+ ![DaVinci PAS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-pas.json)
246
+ ![DaVinci CDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-cdex.json)
247
+ ![DaVinci PDex](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-pdex.json)
248
+ ![DaVinci DTR](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-dtr.json)
249
+ ![DaVinci Alerts](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-alerts.json)
250
+ ![DaVinci DEQM](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-deqm.json)
251
+ ![DaVinci Drug Formulary](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-davinci-drug-formulary.json)
252
+ ![IPS](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ips.json)
253
+ ![SMART App Launch](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-smart.json)
254
+ ![SDC (Structured Data Capture)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-sdc.json)
255
+ ![Genomics Reporting](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-genomics-reporting.json)
256
+ ![CPG (Clinical Practice Guidelines)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-cpg.json)
257
+ ![ISiK Basis](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-isik-basis.json)
258
+ ![KBV eRezept](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-kbv-erp.json)
259
+ ![DE Basisprofil](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-de-basisprofil.json)
260
+ ![ISiK Medikation](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-isik-medikation.json)
261
+ ![CH Core (Switzerland)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-ch-core.json)
262
+ ![AU Core (Australia)](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-au-core.json)
263
+ ![PIXm](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-pixm.json)
264
+ ![MHD](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-mhd.json)
265
+ ![vitals](https://img.shields.io/endpoint?url=https://max-health-inc.github.io/BabelFHIR-TS/badges/badge-hl7-vitals.json)
266
+
267
+ </details>
268
+
269
+ > External-validator badges cover the 29 R4/R4B IGs. R5 packages are generated and typechecked, but neither external validator publishes R5 badges yet.
270
+
271
+ > Terminology validation requires a tx server. The pipeline uses `--tx-server https://tx.fhir.org/{r4|r5}` (matching the package's FHIR version) during generation to expand ValueSets and produce valid codes.
272
+
273
+ 📊 **[Full Report](https://max-health-inc.github.io/BabelFHIR-TS/)**
274
+ <!-- HL7-PARITY-BADGES:END -->
275
+ <!-- PARITY-BADGES:END -->
276
+
277
277
  ## License
278
278
 
279
279
  ISC © Maximilian Nussbaumer
@@ -5,7 +5,7 @@ import { primitivePlaceholder, generateCodeDefault, makeCodeableConcept, chooseC
5
5
  import { generateSliceElement, buildNestedRequirementsObject } from './sliceElementGenerator.js';
6
6
  import { COMPLEX_SKELETON_MAP, propKey, buildValueExpression, buildCrossReferencedEntryArray, } from './classGeneratorHelpers.js';
7
7
  import { renderClassTemplate } from './classTemplate.js';
8
- export function generateClass(className, interfaceName, baseResource, requiredFields = [], profileUrl, fieldPatterns = [], forbiddenFields = [], valueSetBindings = {}, fieldOrder = [], codeableConceptBindings = []) {
8
+ export function generateClass(className, interfaceName, baseResource, requiredFields = [], profileUrl, fieldPatterns = [], forbiddenFields = [], valueSetBindings = {}, fieldOrder = [], codeableConceptBindings = [], hasValueSetRegistry = false) {
9
9
  // Decide whether to emit resourceType. If baseResource points at a known resource or ends with 'Resource'.
10
10
  const CORE_RESOURCE_BASES = ctx().coreResourceBases;
11
11
  const addResourceType = !!baseResource && CORE_RESOURCE_BASES.has(baseResource);
@@ -578,6 +578,6 @@ export function generateClass(className, interfaceName, baseResource, requiredFi
578
578
  profileUrl, constructorMetaProfile, setterMetaProfile,
579
579
  randomMetaProfileInit, resourceTypeLine, baseResource,
580
580
  fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder,
581
- codeableConceptBindings,
581
+ codeableConceptBindings, hasValueSetRegistry,
582
582
  });
583
583
  }
@@ -93,12 +93,13 @@ export function buildCrossReferencedEntryArray(sliceElements) {
93
93
  return `(() => { ${decls.join(' ')} return [${rewritten.join(', ')}]; })()`;
94
94
  }
95
95
  /** Generate the static pattern/forbidden/order/binding metadata properties for a class. */
96
- export function generatePatternMetadata(fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder = [], codeableConceptBindings = []) {
96
+ export function generatePatternMetadata(fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder = [], codeableConceptBindings = [],
97
+ /** Whether the class file imports `getRandomConceptByUrl` — see renderClassTemplate. */
98
+ emitCodeResolver = false) {
97
99
  const patternMap = {};
98
100
  for (const fp of fieldPatterns) {
99
101
  patternMap[fp.fieldName] = fp.pattern;
100
102
  }
101
- const hasBindings = Object.keys(valueSetBindings).length > 0;
102
103
  return `
103
104
  /**
104
105
  * Pattern constraints this profile fixes on its fields, keyed by field path
@@ -127,16 +128,10 @@ export function generatePatternMetadata(fieldPatterns, forbiddenFields, valueSet
127
128
  */
128
129
  protected static readonly _codeableConceptBindings: string[] = ${JSON.stringify(codeableConceptBindings)};
129
130
 
130
- /** Code resolver for ValueSet bindings - returns a random valid code from a ValueSet by URL */
131
- protected static readonly _codeResolver: ((url: string) => { code: string; system: string; display?: string } | undefined) | undefined = ${hasBindings ? `(() => {
132
- // Try to load the ValueSetRegistry - it may not exist if no ValueSets were generated
133
- try {
134
- const registry = __require('./valuesets/index.js') as Record<string, unknown>;
135
- if (registry && typeof registry.getRandomConceptByUrl === 'function') {
136
- return registry.getRandomConceptByUrl as (url: string) => { code: string; system: string; display?: string } | undefined;
137
- }
138
- } catch { /* ValueSetRegistry not available */ }
139
- return undefined;
140
- })()` : 'undefined'};
131
+ /**
132
+ * Random-example code resolver for ValueSet bindings. \`undefined\` when this package emitted no
133
+ * ValueSet registry; enrichResource and resolveSliceCode both fall back to a placeholder.
134
+ */
135
+ protected static readonly _codeResolver: ((url: string) => { code: string; system: string; display?: string } | undefined) | undefined = ${emitCodeResolver ? 'getRandomConceptByUrl' : 'undefined'};
141
136
  `;
142
137
  }
@@ -1,7 +1,7 @@
1
1
  import { COMPLEX_SKELETON_MAP, generatePatternMetadata } from './classGeneratorHelpers.js';
2
2
  /** Render the final class file content from pre-computed template parameters. */
3
3
  export function renderClassTemplate(params) {
4
- const { interfaceName, className, requiredInitBlock, enableMetaProfile, profileUrl, constructorMetaProfile, setterMetaProfile, randomMetaProfileInit, resourceTypeLine, baseResource, fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder, codeableConceptBindings, } = params;
4
+ const { interfaceName, className, requiredInitBlock, enableMetaProfile, profileUrl, constructorMetaProfile, setterMetaProfile, randomMetaProfileInit, resourceTypeLine, baseResource, fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder, codeableConceptBindings, hasValueSetRegistry, } = params;
5
5
  // Determine which skeleton helpers are actually used in requiredInitBlock
6
6
  const usedSkeletons = new Set();
7
7
  for (const helper of Object.values(COMPLEX_SKELETON_MAP)) {
@@ -24,14 +24,17 @@ export function renderClassTemplate(params) {
24
24
  helperImports.add(helper);
25
25
  }
26
26
  const helperImportList = Array.from(helperImports).join(', ');
27
- const hasVsBindings = Object.keys(valueSetBindings).length > 0;
27
+ // Both halves needed: bindings can all point at ValueSets this package does not emit, and a
28
+ // registry with no bindings is dead weight.
29
+ const emitCodeResolver = Object.keys(valueSetBindings).length > 0 && hasValueSetRegistry;
28
30
  return `
29
31
  import { validate${interfaceName}, type ${interfaceName} } from "./${interfaceName}.js";
30
32
  import type { ValidatorOptions } from "./ValidatorOptions.js";
31
33
  // Only import helpers actually referenced below (dynamic based on required fields)
32
34
  import { ${helperImportList} } from "./random/index.js";
33
- ${hasVsBindings ? `import { createRequire } from 'module';
34
- const __require = createRequire(import.meta.url);` : ''}
35
+ ${emitCodeResolver ? `// Static on purpose: a Node-only runtime require here dies at module init under any bundler
36
+ // that strips module metadata, which kept this package off Workers and Deno.
37
+ import { getRandomConceptByUrl } from "./valuesets/index.js";` : ''}
35
38
 
36
39
  // Helper emitted only when meta.profile enforcement is applicable (resource profiles)
37
40
  ${enableMetaProfile ? `type WithMeta = { meta?: { profile?: string[] } };
@@ -54,7 +57,7 @@ function safeClone<T>(value: T): T {
54
57
  }
55
58
 
56
59
  export class ${className} {
57
- ${generatePatternMetadata(fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder, codeableConceptBindings)}
60
+ ${generatePatternMetadata(fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder, codeableConceptBindings, emitCodeResolver)}
58
61
  private resource: ${interfaceName};
59
62
 
60
63
  // Declared and assigned rather than written as a parameter property, which
@@ -611,11 +611,6 @@ export async function generateIntoPackage(packageArchivePath, outArchivePath, fl
611
611
  // Install fhirpath type stub so tsc can resolve validator imports
612
612
  const { installFhirpathStub, removeFhirpathStub } = await import('./emitters/validator/fhirpathStubInstaller.js');
613
613
  installFhirpathStub(outputDir);
614
- // Install minimal @types/node stub so tsc can resolve `import { createRequire } from 'module'`
615
- const nodeTypesDir = path.join(outputDir, 'node_modules', '@types', 'node');
616
- fs.mkdirSync(nodeTypesDir, { recursive: true });
617
- fs.writeFileSync(path.join(nodeTypesDir, 'index.d.ts'), `declare module 'module' {\n export function createRequire(filename: string | URL): NodeRequire;\n}\n`);
618
- fs.writeFileSync(path.join(nodeTypesDir, 'package.json'), JSON.stringify({ name: '@types/node', version: '0.0.0-stub', types: 'index.d.ts' }));
619
614
  // Compile TypeScript to JavaScript
620
615
  endPhase = startPhase('compile');
621
616
  logger.log('Compiling TypeScript to JavaScript...');
@@ -623,11 +618,6 @@ export async function generateIntoPackage(packageArchivePath, outArchivePath, fl
623
618
  endPhase(); // compile
624
619
  // Remove fhirpath stub — the real package is a peer dependency
625
620
  removeFhirpathStub(outputDir);
626
- // Remove @types/node stub — only needed for compilation
627
- try {
628
- fs.rmSync(path.join(outputDir, 'node_modules', '@types'), { recursive: true, force: true });
629
- }
630
- catch { /* ignore */ }
631
621
  // Remove base client type stubs — they were only needed for tsc to resolve
632
622
  // @babelfhir-ts/client-<version> imports during compilation. The real package is
633
623
  // installed by the consumer via npm.
@@ -843,19 +833,11 @@ export async function generateIntoPackageDirect(packageArchivePath, flags) {
843
833
  }
844
834
  const { installFhirpathStub, removeFhirpathStub } = await import('./emitters/validator/fhirpathStubInstaller.js');
845
835
  installFhirpathStub(outputDir);
846
- const nodeTypesDir = path.join(outputDir, 'node_modules', '@types', 'node');
847
- fs.mkdirSync(nodeTypesDir, { recursive: true });
848
- fs.writeFileSync(path.join(nodeTypesDir, 'index.d.ts'), `declare module 'module' {\n export function createRequire(filename: string | URL): NodeRequire;\n}\n`);
849
- fs.writeFileSync(path.join(nodeTypesDir, 'package.json'), JSON.stringify({ name: '@types/node', version: '0.0.0-stub', types: 'index.d.ts' }));
850
836
  endPhase = startPhase('compile');
851
837
  logger.log('Compiling TypeScript to JavaScript...');
852
838
  await compileTypeScriptToJS(outputDir);
853
839
  endPhase(); // compile
854
840
  removeFhirpathStub(outputDir);
855
- try {
856
- fs.rmSync(path.join(outputDir, 'node_modules', '@types'), { recursive: true, force: true });
857
- }
858
- catch { /* ignore */ }
859
841
  const babelfhirDir = path.join(outputDir, 'node_modules', '@babelfhir-ts');
860
842
  if (fs.existsSync(babelfhirDir)) {
861
843
  for (const entry of fs.readdirSync(babelfhirDir)) {
@@ -6,6 +6,7 @@
6
6
  * Helpers and types live in sdProcessorHelpers.ts.
7
7
  * Required-field dedup lives in sdProcessorRequiredFields.ts.
8
8
  */
9
+ import fs from 'fs';
9
10
  import path from 'path';
10
11
  import { generateClass } from './emitters/class/classGenerator.js';
11
12
  import { generateInterfaces } from './emitters/interface/interfaceGenerator.js';
@@ -733,7 +734,10 @@ export async function processStructureDefinition(sd, ctx) {
733
734
  }
734
735
  // ── Emit artifacts ───────────────────────────────────────────────
735
736
  const { fieldPatterns, forbiddenFields, valueSetBindings, codeableConceptBindings, fieldOrder } = await extractFieldPatternsAndMetadata([parsed.newFields || [], aligned.alignedNewFields || [], parsed.oldFields || []], baseResource, sd, requiredFields, candidateRequiredFields, nestedRequirementsMap, resolvedProfilePatterns);
736
- const classContent = generateClass(`${interfaceName}Class`, interfaceName, baseResource, requiredFields, sd.url, fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder, codeableConceptBindings);
737
+ // Read off disk, not threaded through ctx: emitValueSetFiles has already run by now, and ten
738
+ // call sites would otherwise carry a flag most of them always pass false.
739
+ const hasValueSetRegistry = fs.existsSync(path.join(outputDir, 'valuesets', 'index.ts'));
740
+ const classContent = generateClass(`${interfaceName}Class`, interfaceName, baseResource, requiredFields, sd.url, fieldPatterns, forbiddenFields, valueSetBindings, fieldOrder, codeableConceptBindings, hasValueSetRegistry);
737
741
  ensureRandomSupportFile(outputDir);
738
742
  ensureValidatorOptionsFile(outputDir);
739
743
  writeInterfaceAndValidatorToFile(outputDir, interfaceName, finalInterfaceContent, validateFn);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babelfhir-ts",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "BabelFHIR-TS: generate TypeScript interfaces, validators, and helper classes from FHIR R4/R4B/R5 StructureDefinitions (profiles) directly inside package archives.",
5
5
  "type": "module",
6
6
  "main": "out/src/main.js",