@claudebernard/node-fhir-mapper 2.1.2

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/LICENSE.md ADDED
@@ -0,0 +1 @@
1
+ # License
package/README.md ADDED
@@ -0,0 +1,512 @@
1
+ # @claudebernard/fhir-mapper
2
+ This library will be composed of several bidirectional mapping entities between Claude Bernard (alias BCB) interfaces and FHIR specifications.
3
+
4
+ Each mapper will contain at the very least a _fhirToBcb_ and a _bcbToFhir_ functions, will return a **MappingResponse** object and is expected to work offline as long as the codification mappers you provide don't call any APIs.
5
+
6
+ ```ts
7
+ interface MappingResponse<T = unknown> {
8
+ result: T | undefined;
9
+ errors?: MappingError[];
10
+ }
11
+ type MappingError = {
12
+ field: string;
13
+ message: string;
14
+ }
15
+ ```
16
+
17
+ Some of those mappers can accept optional **CodificationFunction** parameters which are meant to provide a way for the user to be able to choose how the mapping between a fhir resource's [Coding](https://www.hl7.org/fhir/datatypes.html#Coding) field and the corresponding Claude Bernard class codification property is done.
18
+
19
+ Of course, if the value of the respective fields is not provided or if they use the Claude Bernard codification already, those parameters should be omitted.
20
+
21
+ **CodificationFunction** type :
22
+
23
+ ```ts
24
+ type CodificationFunction = ((coding: Coding) => SimpleCodification[] | Promise<SimpleCodification[]>) | undefined;
25
+
26
+ type SimpleCodification = {
27
+ code: string;
28
+ label: string;
29
+ };
30
+ ```
31
+ The **CodificationFunction** type expects a fhir r5 **Coding** resource as input and must return an array of **SimpleCodification** objects (or a Promise resolving to such an array). This allows you to use either synchronous or asynchronous logic (e.g., API calls) in your codification mappers. If your codification will map to a single value, return a single-element array. If no mapping is found, return an empty array.
32
+
33
+ **Note:** All mapping functions that accept a `CodificationFunction` (such as `fhirToBcb`, `fhirToCb` etc.) are now asynchronous and must be called with `await` or handled as Promises, even if your mappers are synchronous.
34
+
35
+ ## Dependencies
36
+ The library uses the _@types/fhir_ lib to gain access to fhir r5 official objects and methods.
37
+
38
+ ## Peer Dependencies
39
+ The library uses the @claudebernard/types lib for common object structures used by other Claude Bernard tools and apps.
40
+
41
+ ## Installation
42
+
43
+ ```sh
44
+ npm install --save @claudebernard/fhir-mapper
45
+ ```
46
+
47
+ ## Mappers list
48
+
49
+ Below the list of all mappers currently comprised in this library :
50
+ - A [**Dosage**](https://www.hl7.org/fhir/dosage.html#Dosage) mapper exported as _dosageMapper_.
51
+ - A [**Patient**](https://www.hl7.org/fhir/patient.html#Patient) mapper exported as _patientMapper_.
52
+ - A [**Medication**](https://www.hl7.org/fhir/medication.html#Medication) mapper exported as _medicationMapper_.
53
+ - A [**MedicationRequest**](https://www.hl7.org/fhir/medicationrequest.html#MedicationRequest) mapper exported as _medicationRequestMapper_.
54
+
55
+ ## Mappers details
56
+
57
+ ### Dosage mapper : functions
58
+
59
+ #### - fhirToBcb
60
+
61
+
62
+ ```ts
63
+ async function fhirToBcb(
64
+ dosageInstructions: Dosage[],
65
+ indicationMapper?: CodificationFunction,
66
+ routeMapper?: CodificationFunction,
67
+ intakeMapper?: CodificationFunction
68
+ ): Promise<MappingResponse<BCBPosologieStructuree2>[]> {}
69
+ ```
70
+
71
+ The function takes 4 parameters :
72
+ - 1 mandatory parameter 'dosageInstructions' which will be the fhir r5 [Dosage](https://www.hl7.org/fhir/dosage.html#Dosage) resources that need to be mapped.
73
+ - 3 optional parameters of type **CodificationFunction**.
74
+
75
+ Those optional parameters are meant to be used to map fhir (asNeededFor, route, doseAndRate) fields to (codeIndication, codeVoie, codeUnitePrise) **BCBPosologieStructuree2** class properties.
76
+
77
+ ##### Usage
78
+
79
+ ```ts
80
+ import { dosageMapper } from '@claudebernard/fhir-mapper';
81
+ // other imports ...
82
+
83
+ const fhirDosages = [];
84
+
85
+ // synchronous codification mapper
86
+ const routeMapper = (coding : Coding) => {
87
+ // some logic implemented by yourself ...
88
+ return {
89
+ code : routeCode,
90
+ label : routeLabel
91
+ }
92
+ }
93
+
94
+ // asynchronous codification mapper
95
+ const indicationMapper = async (coding: Coding) => {
96
+ // await someApiCall(coding)
97
+ return {
98
+ code: routeCode,
99
+ label: routeLabel
100
+ }
101
+ }
102
+
103
+ // ...
104
+
105
+ const bcbDosages = await dosageMapper.fhirToBcb(fhirDosages, indicationMapper, routeMapper, undefined);
106
+
107
+ // ...
108
+ ```
109
+
110
+ #### - bcbToFhir
111
+
112
+ ```ts
113
+ function bcbToFhir(bcbDosages: BCBPosologieStructuree2[]): MappingResponse<Dosage>[] {}
114
+ ```
115
+
116
+ This function takes only one parameter, an array of **BCBPosologieStructuree2** objects and returns a **MappingResponse** containing the corresponding fhir **Dosage** resources.
117
+
118
+ It will for now by default keep the Claude Bernard codification for the **Coding** fields in the output fhir **Dosage** resources.
119
+
120
+ ##### Usage
121
+
122
+ ```ts
123
+ import { dosageMapper } from '@claudebernard/fhir-mapper';
124
+ // other imports ...
125
+
126
+ const bcbDosages = [];
127
+
128
+ // ...
129
+
130
+ const fhirDosages = dosageMapper.bcbToFhir(bcbDosages);
131
+
132
+ // ...
133
+ ```
134
+
135
+ #### - fhirToCb
136
+
137
+ ```ts
138
+ async function fhirToCb(dosageInstructions: Dosage[]): Promise<MappingResponse<CBPosologyBean>[]> {}
139
+ ```
140
+
141
+ Converts FHIR Dosage instructions to CB (Claude Bernard) Posology Bean format. This function uses the existing fhirToBcb conversion and then transforms the result to CB format.
142
+
143
+ ##### Usage
144
+
145
+ ```ts
146
+ import { dosageMapper } from '@claudebernard/fhir-mapper';
147
+
148
+ const fhirDosages = /* array of FHIR Dosage instructions */;
149
+ const cbResults = await dosageMapper.fhirToCb(fhirDosages);
150
+
151
+ cbResults.forEach(response => {
152
+ if (response.result) {
153
+ console.log(response.result.posologyLabel);
154
+ }
155
+ });
156
+ ```
157
+
158
+ #### - cbToFhir
159
+
160
+ ```ts
161
+ function cbToFhir(cbPosologies: CBPosologyBean[]): MappingResponse<Dosage>[] {}
162
+ ```
163
+
164
+ Converts CB Posology Bean format to FHIR Dosage instructions. This function transforms CB format to BCB format and then uses the existing bcbToFhir conversion.
165
+
166
+ ##### Usage
167
+
168
+ ```ts
169
+ import { dosageMapper } from '@claudebernard/fhir-mapper';
170
+
171
+ const cbPosologies = /* array of CBPosologyBean */;
172
+ const fhirResults = dosageMapper.cbToFhir(cbPosologies);
173
+
174
+ fhirResults.forEach(response => {
175
+ if (response.result) {
176
+ console.log(response.result.text);
177
+ }
178
+ });
179
+ ```
180
+
181
+ #### Dosage mapper : current limitations
182
+ Even though the mapper works and allows us to transform Dosage resources in Claude Bernard resources, there are some caveats : - some fields are currently unmapped due to a lack of overlap between the two structures.
183
+ - some fields are only partially mapped due to the fact that on one side (fhir) they are arrays and on the other (claude bernard), they are unitary values.
184
+
185
+ ## Claude Bernard codifications
186
+ Below is listed the different Claude Bernard coding systems or valuesets that will be used internally by the mappers.
187
+ - https://platform.claudebernard.fr/fhir/CodeSystem/dosage-routes
188
+ - https://platform.claudebernard.fr/fhir/CodeSystem/dosage-intake-units
189
+ - https://platform.claudebernard.fr/fhir/CodeSystem/amm-pathologies
190
+
191
+ ### Patient mapper : FHIR representation
192
+
193
+ The patient mapping uses the same FHIR representation as the Java library
194
+ [`mvn-fhir-mapper`](../mvn-fhir-mapper/README.md), so that a bundle produced by one can be read
195
+ back by the other.
196
+
197
+ | BCB / CB field | FHIR resource | Code |
198
+ | --- | --- | --- |
199
+ | `age` (months), `sexe` / `gender` | `Patient` (`birthDate`, `gender`) | — |
200
+ | `poids` / `weight` | `Observation` | LOINC `29463-7` |
201
+ | `taille` / `height` | `Observation` | LOINC `8302-2` |
202
+ | `grossesse` / `pregnancy` | `Observation` | LOINC `82810-3` |
203
+ | `weeksOfPregnancy` | `Observation.valueQuantity`, or gestational age as a fallback | LOINC `82810-3`, `18185-9` |
204
+ | `allaitement` / `breastfeeding` | `Observation` | LOINC `63895-7` |
205
+ | `clairanceCreatinine` / `creatinineClearance` | `Observation` | any code of the accepted clearance list |
206
+ | `gfr` | `Observation` | any code of the accepted GFR lists |
207
+ | `creatininemieMol` / `molCreatinine` | `Observation` | LOINC `14682-9` |
208
+ | `creatininemieMg` / `mglCreatinine` | `Observation` | LOINC `2160-0` |
209
+ | `insuffisanceHepatique` / `hepaticStage` | Child-Pugh `Observation` | LOINC `98152-2` + SNOMED class |
210
+ | `lstPathologiesAMM` / `ammPathologies` | `Condition` | `.../CodeSystem/amm-pathologies` |
211
+ | `lstPathologiesCIM10` | `Condition` | `http://hl7.org/fhir/sid/icd-10` |
212
+ | `lstIdComposantAllergie` / `allergies` | `AllergyIntolerance` | `.../CodeSystem/products-ingredients` |
213
+
214
+ #### Hepatic insufficiency
215
+
216
+ The Child-Pugh `Observation` carries the numeric score in `valueQuantity` and the class as a
217
+ SNOMED CT coding in a `component` (`710065009` / `710066005` / `710067001` for stages A / B / C).
218
+ When reading, the component is inspected first, then a direct `valueCodeableConcept`, then the
219
+ score (`< 7` → A, `7-9` → B, `>= 10` → C).
220
+
221
+ > **Breaking change.** Up to version 2.1.1 the hepatic insufficiency was written as an ICD-10
222
+ > `Condition` (`K72.90` / `K72.91` / `K72.92`). It is now written as the Child-Pugh `Observation`
223
+ > described above. Reading still accepts the ICD-10 `Condition` as a fallback, so bundles produced
224
+ > by earlier versions remain readable, but consumers reading the output of `bcbToFhir` / `cbToFhir`
225
+ > must be updated.
226
+
227
+ #### Renal function
228
+
229
+ Creatinine clearance and GFR are recognised through the same extended LOINC code lists as
230
+ `mvn-fhir-mapper`. An absolute GFR observation is used as is; otherwise a GFR normalized to
231
+ 1.73 m² is converted to an absolute value using the body surface area (Du Bois formula), which
232
+ requires both weight and height to be present in the bundle.
233
+
234
+ ### Patient mapper : functions
235
+
236
+ #### - fhirToBcb
237
+
238
+ ```ts
239
+ async function fhirToBcb(
240
+ fhirPatient: BundleEntry[],
241
+ allergiesMapper?: CodificationFunction,
242
+ snomedPathologiesMapper?: CodificationFunction,
243
+ ): Promise<MappingResponse<BCBPatient>> {}
244
+ ```
245
+ The function takes 3 parameters :
246
+ - 1 mandatory parameter 'fhirPatient' which will be an array of r5 [BundleEntry](https://www.hl7.org/fhir/bundle.html) resources that need to be mapped.
247
+ - 2 optional parameters of type **CodificationFunction**.
248
+
249
+ Those optional parameters are meant to be used to map fhir (Condition.code.coding, AllergyIntolerance.code.coding) fields to (lstPathologiesAMM, lstIdComposantAllergie) **BCBPatient** class properties.
250
+
251
+ ##### Usage
252
+
253
+ ```ts
254
+ import { patientMapper } from '@claudebernard/fhir-mapper';
255
+ // other imports ...
256
+
257
+ const fhirPatient = [];
258
+ const allergiesMapper = (coding : Coding) => {
259
+ // some logic implemented by yourself ...
260
+ return [
261
+ {
262
+ code : allergyCode,
263
+ label : allergyLabel
264
+ }
265
+ ];
266
+ }
267
+
268
+ const snomedPathologiesMapper = async (coding : Coding) => {
269
+ // await someApiCall(coding)
270
+ return [
271
+ {
272
+ code : pathologyCode,
273
+ label : pathologyLabel
274
+ }
275
+ ];
276
+ }
277
+
278
+ // ...
279
+
280
+ const bcbPatient = await patientMapper.fhirToBcb(fhirPatient, allergiesMapper, snomedPathologiesMapper);
281
+
282
+ // ...
283
+ ```
284
+
285
+ #### - bcbToFhir
286
+
287
+ ```ts
288
+ function bcbToFhir(
289
+ bcbPatient: BCBPatient,
290
+ ): MappingResponse<BundleEntry[]> {}
291
+ ```
292
+ The function takes 1 parameter of type BCBPatient and returns a **MappingResponse** containing the an array of the corresponding fhir **BundleEntry** resources.
293
+
294
+ ##### Usage
295
+
296
+ ```ts
297
+ import { patientMapper } from '@claudebernard/fhir-mapper';
298
+ // other imports ...
299
+
300
+ const bcbPatient = [];
301
+
302
+ // ...
303
+
304
+ const fhirPatient = patientMapper.bcbToFhir(bcbPatient);
305
+
306
+ // ...
307
+ ```
308
+
309
+ #### - fhirTocb
310
+
311
+ ```ts
312
+ async function fhirTocb(
313
+ fhirPatient: BundleEntry[],
314
+ allergiesMapper?: CodificationFunction,
315
+ snomedPathologiesMapper?: CodificationFunction,
316
+ ): Promise<MappingResponse<BCBPatient>> {}
317
+ ```
318
+ The function takes 3 parameters :
319
+ - 1 mandatory parameter 'fhirPatient' which will be an array of r5 [BundleEntry](https://www.hl7.org/fhir/bundle.html) resources that need to be mapped.
320
+ - 2 optional parameters of type **CodificationFunction**.
321
+
322
+ Those optional parameters are meant to be used to map fhir (Condition.code.coding, AllergyIntolerance.code.coding) fields to (lstPathologiesAMM, lstIdComposantAllergie) **CBPatient** class properties.
323
+
324
+ ##### Usage
325
+
326
+ ```ts
327
+ import { patientMapper } from '@claudebernard/fhir-mapper';
328
+ // other imports ...
329
+
330
+ const fhirPatient = [];
331
+ const allergiesMapper = (coding : Coding) => {
332
+ // some api call or logic implemented by yourself ...
333
+ return {
334
+ code : allergyCode,
335
+ label : allergyLabel
336
+ }
337
+ }
338
+
339
+ const snomedPathologiesMapper = (coding : Coding) => {
340
+ // some api call or logic implemented by yourself ...
341
+ return [
342
+ {
343
+ code : pathologyCode,
344
+ label : pathologyLabel
345
+ }
346
+ ];
347
+ }
348
+
349
+ // ...
350
+
351
+ const cbPatient = await patientMapper.fhirToCb(fhirPatient, allergiesMapper, snomedPathologiesMapper);
352
+
353
+ // ...
354
+ ```
355
+
356
+ #### - cbToFhir
357
+
358
+ ```ts
359
+ function cbToFhir(
360
+ cbPatient: CBPatient,
361
+ ): MappingResponse<BundleEntry[]> {}
362
+ ```
363
+ The function takes 1 parameter of type BCBPatient and returns a **MappingResponse** containing the an array of the corresponding fhir **BundleEntry** resources.
364
+
365
+ ##### Usage
366
+
367
+ ```ts
368
+ import { patientMapper } from '@claudebernard/fhir-mapper';
369
+ // other imports ...
370
+
371
+ const cbPatient = [];
372
+
373
+ // ...
374
+
375
+ const fhirPatient = patientMapper.cbToFhir(cbPatient);
376
+
377
+ // ...
378
+ ```
379
+
380
+ ### Medication mapper : functions
381
+
382
+ The medication mapper provides utilities for creating and extracting medication codes from FHIR Bundle resources. It supports BCB codes, CIP13 codes, and CIS codes.
383
+
384
+ #### - createMedicationsFromBcbCodes
385
+
386
+ ```ts
387
+ function createMedicationsFromBcbCodes(codes: string[]): MappingResponse<Bundle> {}
388
+ ```
389
+
390
+ Creates a FHIR Bundle containing Medication resources from BCB codes.
391
+
392
+ ##### Usage
393
+
394
+ ```ts
395
+ import { medicationMapper } from '@claudebernard/fhir-mapper';
396
+
397
+ const bcbCodes = ['BCB001', 'BCB002', 'BCB003'];
398
+ const response = medicationMapper.createMedicationsFromBcbCodes(bcbCodes);
399
+
400
+ if (response.result) {
401
+ // Bundle with Medication resources
402
+ console.log(response.result.entry?.length); // 3 medications
403
+ }
404
+ ```
405
+
406
+ #### - createMedicationsFromCIP13Codes / createMedicationsFromCISCodes
407
+
408
+ ```ts
409
+ function createMedicationsFromCIP13Codes(codes: string[]): MappingResponse<Bundle> {}
410
+ function createMedicationsFromCISCodes(codes: string[]): MappingResponse<Bundle> {}
411
+ ```
412
+
413
+ Similar functions for creating medications from CIP13 and CIS codes respectively.
414
+
415
+ #### - extractBcbCodesFromMedications / extractCIP13CodesFromMedications / extractCISCodesFromMedications
416
+
417
+ ```ts
418
+ function extractBcbCodesFromMedications(bundle: Bundle): string[] {}
419
+ function extractCIP13CodesFromMedications(bundle: Bundle): string[] {}
420
+ function extractCISCodesFromMedications(bundle: Bundle): string[] {}
421
+ ```
422
+
423
+ Extract specific types of medication codes from a FHIR Bundle containing Medication resources.
424
+
425
+ ##### Usage
426
+
427
+ ```ts
428
+ import { medicationMapper } from '@claudebernard/fhir-mapper';
429
+
430
+ const bundle = /* your FHIR Bundle */;
431
+ const bcbCodes = medicationMapper.extractBcbCodesFromMedications(bundle);
432
+ const cip13Codes = medicationMapper.extractCIP13CodesFromMedications(bundle);
433
+ ```
434
+
435
+ ### MedicationRequest mapper : functions
436
+
437
+ The medication request mapper handles conversion of dosage instructions between FHIR MedicationRequest resources and BCB format, focusing purely on dosage conversion.
438
+
439
+ #### - fhirToBcb
440
+
441
+ ```ts
442
+ async function fhirToBcb(bundle: Bundle): Promise<MappingResponse<BCBPosologieStructuree2>[]> {}
443
+ ```
444
+
445
+ Extracts and converts dosage instructions from MedicationRequest resources in a Bundle to BCB format using the dosage-mapper.
446
+
447
+ ##### Usage
448
+
449
+ ```ts
450
+ import { medicationRequestMapper } from '@claudebernard/fhir-mapper';
451
+
452
+ const bundle = /* FHIR Bundle with MedicationRequest resources */;
453
+ const bcbDosages = await medicationRequestMapper.fhirToBcb(bundle);
454
+
455
+ // Array of BCB dosage mapping responses
456
+ bcbDosages.forEach(response => {
457
+ if (response.result) {
458
+ console.log(response.result.libellePosologie);
459
+ }
460
+ });
461
+ ```
462
+
463
+ #### - bcbToFhir
464
+
465
+ ```ts
466
+ function bcbToFhir(bcbDosages: BCBPosologieStructuree2[]): MappingResponse<Bundle> {}
467
+ ```
468
+
469
+ Creates a FHIR Bundle with a MedicationRequest resource containing the converted dosage instructions from BCB format.
470
+
471
+ ##### Usage
472
+
473
+ ```ts
474
+ import { medicationRequestMapper } from '@claudebernard/fhir-mapper';
475
+
476
+ const bcbDosages = /* array of BCBPosologieStructuree2 */;
477
+ const response = medicationRequestMapper.bcbToFhir(bcbDosages);
478
+
479
+ if (response.result) {
480
+ // Bundle with MedicationRequest containing converted dosage instructions
481
+ const medReq = response.result.entry?.[0]?.resource as MedicationRequest;
482
+ console.log(medReq.dosageInstruction?.length);
483
+ }
484
+ ```
485
+
486
+ ## Browser support
487
+ - [x] Chrome
488
+ - [x] Firefox
489
+ - [x] Safari
490
+ - [x] Microsoft Edge
491
+
492
+ ## Versioning
493
+
494
+ This package carries the version of the `fhir-monorepo` repository — one version, tag and changelog
495
+ for the whole repo. Published versions are therefore sparse: a release only reaches npm when this
496
+ package actually changed. Releases up to `2.2.4` were cut from the former standalone
497
+ `npmjs-bcb-fhir-mapper` repository; their history is kept in [CHANGELOG.md](CHANGELOG.md), later
498
+ entries live in the repository root changelog.
499
+
500
+ ## Development
501
+
502
+ ```sh
503
+ npm ci
504
+ npm test # jest
505
+ npm run lint # eslint
506
+ npm run build
507
+ ```
508
+
509
+ ## License
510
+
511
+ Copyright of Cegedim. See [LICENSE](LICENSE.md) for details.
512
+