@claudebernard/node-fhir-mapper 2.1.3 → 2.1.5

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
@@ -436,6 +436,45 @@ function createMedicationsFromCISCodes(codes: string[]): MappingResponse<Bundle>
436
436
 
437
437
  Similar functions for creating medications from CIP13 and CIS codes respectively. They also add a blank MedicationRequest per Medication.
438
438
 
439
+ #### - createMedicationsFromProducts / createMedicationFromProduct
440
+
441
+ ```ts
442
+ function createMedicationsFromProducts(products: Product[]): MappingResponse<Bundle> {}
443
+ function createMedicationFromProduct(product: Product): Medication | undefined {}
444
+ ```
445
+
446
+ Same as `createMedicationsFromBcbCodes`, but starting from the `Product` objects returned by the BCB APIs (`@claudebernard/types`), so the medication labels are kept along with the codes. Each Medication carries one Coding per code the Product holds — `code` for the bcb-code, `properties.codes.cip13` (or `code13`) for the cip13-code, `properties.codes.cis` for the cis-code — each with the product label as `display`, and the same label as the CodeableConcept `text` :
447
+
448
+ ```json
449
+ {
450
+ "resourceType": "Medication",
451
+ "id": "95175bcb-f3cf-4eb8-83be-7956554cd0b8",
452
+ "code": {
453
+ "coding": [
454
+ { "system": "https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code", "code": "76461", "display": "JANUMET 50 mg/1000 mg, comprimé pelliculé" },
455
+ { "system": "http://terminology.hl7.org/CodeSystem/cip13-code", "code": "3400957312114", "display": "JANUMET 50 mg/1000 mg, comprimé pelliculé" },
456
+ { "system": "http://terminology.hl7.org/CodeSystem/cis-code", "code": "66010671", "display": "JANUMET 50 mg/1000 mg, comprimé pelliculé" }
457
+ ],
458
+ "text": "JANUMET 50 mg/1000 mg, comprimé pelliculé"
459
+ }
460
+ }
461
+ ```
462
+
463
+ The label is read from `labels.label`, falling back on `labels.longLabel` then `labels.shortLabel`, depending on which fields the API in use fills ; the HTML flavoured fields (`labelHtml` & co) are never used. Unlike the other creation functions, the Bundle `id` is a UUID v4 as well, so it differs from one call to the next. A Product carrying none of the three codes is skipped and reported in the `errors` field of the response ; `createMedicationFromProduct` returns `undefined` for it.
464
+
465
+ ##### Usage
466
+
467
+ ```ts
468
+ import { medicationMapper } from '@claudebernard/fhir-mapper';
469
+
470
+ const response = medicationMapper.createMedicationsFromProducts(products);
471
+
472
+ if (response.result) {
473
+ // Bundle with the Medication resources first, then their MedicationRequest resources
474
+ console.log(response.result.entry?.length);
475
+ }
476
+ ```
477
+
439
478
  #### - extractBcbCodesFromMedications / extractCIP13CodesFromMedications / extractCISCodesFromMedications
440
479
 
441
480
  ```ts
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Dosage, Bundle } from 'fhir/r5';
2
- import { CBPatient } from '@claudebernard/types';
1
+ import { Dosage, Bundle, Medication } from 'fhir/r5';
2
+ import { CBPatient, Product } from '@claudebernard/types';
3
3
 
4
4
  interface BCBPosologieStructuree2 {
5
5
  adequationUP?: number | null;
@@ -191,6 +191,9 @@ declare namespace patientMapper_d {
191
191
  };
192
192
  }
193
193
 
194
+ declare const BCB_CODE_SYSTEM = "https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code";
195
+ declare const CIP13_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/cip13-code";
196
+ declare const CIS_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/cis-code";
194
197
  /**
195
198
  * Generate a hash-based ID for a medication based on its codes
196
199
  */
@@ -204,21 +207,21 @@ declare const generateMedicationId: (codes: string[], system: string) => string;
204
207
  declare function extractCodesFromMedications(bundle: Bundle, system: string): string[];
205
208
  /**
206
209
  * Extracts a list of bcb-code strings from a Bundle containing Medication resources.
207
- * Only codes with system "https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code" are included.
210
+ * Only codes with system BCB_CODE_SYSTEM are included.
208
211
  * @param bundle Bundle containing Medication resources
209
212
  * @returns List of BCB codes
210
213
  */
211
214
  declare function extractBcbCodesFromMedications(bundle: Bundle): string[];
212
215
  /**
213
216
  * Extracts a list of cip13-code strings from a Bundle containing Medication resources.
214
- * Only codes with system "http://terminology.hl7.org/CodeSystem/cip13-code" are included.
217
+ * Only codes with system CIP13_CODE_SYSTEM are included.
215
218
  * @param bundle Bundle containing Medication resources
216
219
  * @returns List of CIP13 codes
217
220
  */
218
221
  declare function extractCIP13CodesFromMedications(bundle: Bundle): string[];
219
222
  /**
220
223
  * Extracts a list of cis-code strings from a Bundle containing Medication resources.
221
- * Only codes with system "http://terminology.hl7.org/CodeSystem/cis-code" are included.
224
+ * Only codes with system CIS_CODE_SYSTEM are included.
222
225
  * @param bundle Bundle containing Medication resources
223
226
  * @returns List of CIS codes
224
227
  */
@@ -247,24 +250,64 @@ declare function createMedicationsFromCIP13Codes(cip13Codes: string[]): MappingR
247
250
  * @returns MappingResponse containing a Bundle with Medication and MedicationRequest resources
248
251
  */
249
252
  declare function createMedicationsFromCISCodes(cisCodes: string[]): MappingResponse<Bundle>;
253
+ /**
254
+ * Reads the human readable label of a Product, falling back on the other plain text
255
+ * label fields when the preferred one is not filled by the BCB API in use.
256
+ * The HTML flavoured fields (labelHtml and friends) are never used.
257
+ * @param product Product to read the label from
258
+ * @returns The product label, or undefined when the Product carries none
259
+ */
260
+ declare const extractProductLabel: (product: Product) => string | undefined;
261
+ /**
262
+ * Creates a Medication from a Claude Bernard Product, keeping both its codes and its label.
263
+ * The Medication holds one Coding per code the Product carries (bcb-code, cip13-code, cis-code),
264
+ * each with the product label as `display`, and the same label as the CodeableConcept `text`.
265
+ * The Medication id is a UUID v4, so it differs from one call to the next.
266
+ * @param product Product to convert to a Medication resource
267
+ * @returns The Medication resource, or undefined when the Product carries no code at all
268
+ */
269
+ declare function createMedicationFromProduct(product: Product): Medication | undefined;
270
+ /**
271
+ * Creates a Bundle containing a Medication and its associated MedicationRequest for each Product.
272
+ * Each Medication keeps the product codes and label (see createMedicationFromProduct), and each
273
+ * MedicationRequest references its Medication without any dosage instruction.
274
+ * Products carrying no code at all are skipped and reported in the `errors` field.
275
+ * Every id, the Bundle one included, is a UUID v4, so they all differ from one call to
276
+ * the next, and every entry carries a fullUrl built as "<ResourceType>/<id>".
277
+ * @param products List of Products to convert to Medication / MedicationRequest resources
278
+ * @returns MappingResponse containing a Bundle with Medication and MedicationRequest resources
279
+ */
280
+ declare function createMedicationsFromProducts(products: Product[]): MappingResponse<Bundle>;
250
281
 
282
+ declare const medicationMapper_d_BCB_CODE_SYSTEM: typeof BCB_CODE_SYSTEM;
283
+ declare const medicationMapper_d_CIP13_CODE_SYSTEM: typeof CIP13_CODE_SYSTEM;
284
+ declare const medicationMapper_d_CIS_CODE_SYSTEM: typeof CIS_CODE_SYSTEM;
285
+ declare const medicationMapper_d_createMedicationFromProduct: typeof createMedicationFromProduct;
251
286
  declare const medicationMapper_d_createMedicationsFromBcbCodes: typeof createMedicationsFromBcbCodes;
252
287
  declare const medicationMapper_d_createMedicationsFromCIP13Codes: typeof createMedicationsFromCIP13Codes;
253
288
  declare const medicationMapper_d_createMedicationsFromCISCodes: typeof createMedicationsFromCISCodes;
289
+ declare const medicationMapper_d_createMedicationsFromProducts: typeof createMedicationsFromProducts;
254
290
  declare const medicationMapper_d_extractBcbCodesFromMedications: typeof extractBcbCodesFromMedications;
255
291
  declare const medicationMapper_d_extractCIP13CodesFromMedications: typeof extractCIP13CodesFromMedications;
256
292
  declare const medicationMapper_d_extractCISCodesFromMedications: typeof extractCISCodesFromMedications;
257
293
  declare const medicationMapper_d_extractCodesFromMedications: typeof extractCodesFromMedications;
294
+ declare const medicationMapper_d_extractProductLabel: typeof extractProductLabel;
258
295
  declare const medicationMapper_d_generateMedicationId: typeof generateMedicationId;
259
296
  declare namespace medicationMapper_d {
260
297
  export {
298
+ medicationMapper_d_BCB_CODE_SYSTEM as BCB_CODE_SYSTEM,
299
+ medicationMapper_d_CIP13_CODE_SYSTEM as CIP13_CODE_SYSTEM,
300
+ medicationMapper_d_CIS_CODE_SYSTEM as CIS_CODE_SYSTEM,
301
+ medicationMapper_d_createMedicationFromProduct as createMedicationFromProduct,
261
302
  medicationMapper_d_createMedicationsFromBcbCodes as createMedicationsFromBcbCodes,
262
303
  medicationMapper_d_createMedicationsFromCIP13Codes as createMedicationsFromCIP13Codes,
263
304
  medicationMapper_d_createMedicationsFromCISCodes as createMedicationsFromCISCodes,
305
+ medicationMapper_d_createMedicationsFromProducts as createMedicationsFromProducts,
264
306
  medicationMapper_d_extractBcbCodesFromMedications as extractBcbCodesFromMedications,
265
307
  medicationMapper_d_extractCIP13CodesFromMedications as extractCIP13CodesFromMedications,
266
308
  medicationMapper_d_extractCISCodesFromMedications as extractCISCodesFromMedications,
267
309
  medicationMapper_d_extractCodesFromMedications as extractCodesFromMedications,
310
+ medicationMapper_d_extractProductLabel as extractProductLabel,
268
311
  medicationMapper_d_generateMedicationId as generateMedicationId,
269
312
  };
270
313
  }
package/dist/index.js CHANGED
@@ -1439,6 +1439,9 @@ const generateUuidV4 = () => {
1439
1439
  ].join('-');
1440
1440
  };
1441
1441
 
1442
+ const BCB_CODE_SYSTEM = "https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code";
1443
+ const CIP13_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/cip13-code";
1444
+ const CIS_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/cis-code";
1442
1445
  /**
1443
1446
  * Generate a hash-based ID for a medication based on its codes
1444
1447
  */
@@ -1485,30 +1488,30 @@ function extractCodesFromMedications(bundle, system) {
1485
1488
  }
1486
1489
  /**
1487
1490
  * Extracts a list of bcb-code strings from a Bundle containing Medication resources.
1488
- * Only codes with system "https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code" are included.
1491
+ * Only codes with system BCB_CODE_SYSTEM are included.
1489
1492
  * @param bundle Bundle containing Medication resources
1490
1493
  * @returns List of BCB codes
1491
1494
  */
1492
1495
  function extractBcbCodesFromMedications(bundle) {
1493
- return extractCodesFromMedications(bundle, "https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code");
1496
+ return extractCodesFromMedications(bundle, BCB_CODE_SYSTEM);
1494
1497
  }
1495
1498
  /**
1496
1499
  * Extracts a list of cip13-code strings from a Bundle containing Medication resources.
1497
- * Only codes with system "http://terminology.hl7.org/CodeSystem/cip13-code" are included.
1500
+ * Only codes with system CIP13_CODE_SYSTEM are included.
1498
1501
  * @param bundle Bundle containing Medication resources
1499
1502
  * @returns List of CIP13 codes
1500
1503
  */
1501
1504
  function extractCIP13CodesFromMedications(bundle) {
1502
- return extractCodesFromMedications(bundle, "http://terminology.hl7.org/CodeSystem/cip13-code");
1505
+ return extractCodesFromMedications(bundle, CIP13_CODE_SYSTEM);
1503
1506
  }
1504
1507
  /**
1505
1508
  * Extracts a list of cis-code strings from a Bundle containing Medication resources.
1506
- * Only codes with system "http://terminology.hl7.org/CodeSystem/cis-code" are included.
1509
+ * Only codes with system CIS_CODE_SYSTEM are included.
1507
1510
  * @param bundle Bundle containing Medication resources
1508
1511
  * @returns List of CIS codes
1509
1512
  */
1510
1513
  function extractCISCodesFromMedications(bundle) {
1511
- return extractCodesFromMedications(bundle, "http://terminology.hl7.org/CodeSystem/cis-code");
1514
+ return extractCodesFromMedications(bundle, CIS_CODE_SYSTEM);
1512
1515
  }
1513
1516
  /**
1514
1517
  * Wraps a resource into a Bundle entry, carrying its fullUrl as "<ResourceType>/<id>"
@@ -1586,7 +1589,7 @@ const createMedicationsFromCodes = (codes, system) => {
1586
1589
  * @returns MappingResponse containing a Bundle with Medication and MedicationRequest resources
1587
1590
  */
1588
1591
  function createMedicationsFromBcbCodes(bcbCodes) {
1589
- return createMedicationsFromCodes(bcbCodes, "https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code");
1592
+ return createMedicationsFromCodes(bcbCodes, BCB_CODE_SYSTEM);
1590
1593
  }
1591
1594
  /**
1592
1595
  * Creates a Bundle containing Medication resources from a list of CIP13 codes.
@@ -1596,7 +1599,7 @@ function createMedicationsFromBcbCodes(bcbCodes) {
1596
1599
  * @returns MappingResponse containing a Bundle with Medication and MedicationRequest resources
1597
1600
  */
1598
1601
  function createMedicationsFromCIP13Codes(cip13Codes) {
1599
- return createMedicationsFromCodes(cip13Codes, "http://terminology.hl7.org/CodeSystem/cip13-code");
1602
+ return createMedicationsFromCodes(cip13Codes, CIP13_CODE_SYSTEM);
1600
1603
  }
1601
1604
  /**
1602
1605
  * Creates a Bundle containing Medication resources from a list of CIS codes.
@@ -1606,18 +1609,138 @@ function createMedicationsFromCIP13Codes(cip13Codes) {
1606
1609
  * @returns MappingResponse containing a Bundle with Medication and MedicationRequest resources
1607
1610
  */
1608
1611
  function createMedicationsFromCISCodes(cisCodes) {
1609
- return createMedicationsFromCodes(cisCodes, "http://terminology.hl7.org/CodeSystem/cis-code");
1612
+ return createMedicationsFromCodes(cisCodes, CIS_CODE_SYSTEM);
1613
+ }
1614
+ /**
1615
+ * Reads the human readable label of a Product, falling back on the other plain text
1616
+ * label fields when the preferred one is not filled by the BCB API in use.
1617
+ * The HTML flavoured fields (labelHtml and friends) are never used.
1618
+ * @param product Product to read the label from
1619
+ * @returns The product label, or undefined when the Product carries none
1620
+ */
1621
+ const extractProductLabel = (product) => {
1622
+ const label = product.labels?.label
1623
+ ?? product.labels?.longLabel
1624
+ ?? product.labels?.shortLabel;
1625
+ return label?.trim() || undefined;
1626
+ };
1627
+ /**
1628
+ * Builds one Coding per code the Product carries (bcb-code, cip13-code, cis-code),
1629
+ * each one carrying the product label as its display.
1630
+ */
1631
+ const buildProductCodings = (product) => {
1632
+ const display = extractProductLabel(product);
1633
+ const codes = [
1634
+ { system: BCB_CODE_SYSTEM, code: product.code },
1635
+ { system: CIP13_CODE_SYSTEM, code: product.properties?.codes?.cip13 ?? product.code13 },
1636
+ { system: CIS_CODE_SYSTEM, code: product.properties?.codes?.cis }
1637
+ ];
1638
+ return codes
1639
+ .filter(({ code }) => !!code)
1640
+ .map(({ system, code }) => ({ system, code, ...(display ? { display } : {}) }));
1641
+ };
1642
+ /**
1643
+ * Creates a Medication from a Claude Bernard Product, keeping both its codes and its label.
1644
+ * The Medication holds one Coding per code the Product carries (bcb-code, cip13-code, cis-code),
1645
+ * each with the product label as `display`, and the same label as the CodeableConcept `text`.
1646
+ * The Medication id is a UUID v4, so it differs from one call to the next.
1647
+ * @param product Product to convert to a Medication resource
1648
+ * @returns The Medication resource, or undefined when the Product carries no code at all
1649
+ */
1650
+ function createMedicationFromProduct(product) {
1651
+ const coding = buildProductCodings(product);
1652
+ if (coding.length === 0) {
1653
+ return undefined;
1654
+ }
1655
+ const label = extractProductLabel(product);
1656
+ return {
1657
+ resourceType: 'Medication',
1658
+ id: generateUuidV4(),
1659
+ code: {
1660
+ coding,
1661
+ ...(label ? { text: label } : {})
1662
+ }
1663
+ };
1664
+ }
1665
+ /**
1666
+ * Creates a Bundle containing a Medication and its associated MedicationRequest for each Product.
1667
+ * Each Medication keeps the product codes and label (see createMedicationFromProduct), and each
1668
+ * MedicationRequest references its Medication without any dosage instruction.
1669
+ * Products carrying no code at all are skipped and reported in the `errors` field.
1670
+ * Every id, the Bundle one included, is a UUID v4, so they all differ from one call to
1671
+ * the next, and every entry carries a fullUrl built as "<ResourceType>/<id>".
1672
+ * @param products List of Products to convert to Medication / MedicationRequest resources
1673
+ * @returns MappingResponse containing a Bundle with Medication and MedicationRequest resources
1674
+ */
1675
+ function createMedicationsFromProducts(products) {
1676
+ if (!products || products.length === 0) {
1677
+ return {
1678
+ result: {
1679
+ resourceType: "Bundle",
1680
+ id: generateUuidV4(),
1681
+ type: "collection",
1682
+ entry: []
1683
+ },
1684
+ errors: []
1685
+ };
1686
+ }
1687
+ const errors = [];
1688
+ const medications = [];
1689
+ products.forEach((product, index) => {
1690
+ const medication = createMedicationFromProduct(product);
1691
+ if (!medication) {
1692
+ errors.push({
1693
+ field: `products[${index}]`,
1694
+ message: 'Product carries no bcb-code, cip13-code nor cis-code, no Medication created'
1695
+ });
1696
+ return;
1697
+ }
1698
+ medications.push(medication);
1699
+ });
1700
+ const medicationRequests = medications.map(medication => ({
1701
+ resourceType: 'MedicationRequest',
1702
+ id: generateUuidV4(),
1703
+ status: 'active',
1704
+ intent: 'order',
1705
+ medication: {
1706
+ reference: {
1707
+ reference: `Medication/${medication.id}`
1708
+ }
1709
+ },
1710
+ subject: {
1711
+ reference: 'Patient/unknown'
1712
+ }
1713
+ }));
1714
+ const bundle = {
1715
+ resourceType: "Bundle",
1716
+ id: generateUuidV4(),
1717
+ type: "collection",
1718
+ entry: [
1719
+ ...medications.map(medication => toBundleEntry(medication)),
1720
+ ...medicationRequests.map(medicationRequest => toBundleEntry(medicationRequest))
1721
+ ]
1722
+ };
1723
+ return {
1724
+ result: bundle,
1725
+ errors
1726
+ };
1610
1727
  }
1611
1728
 
1612
1729
  var medicationMapper = /*#__PURE__*/Object.freeze({
1613
1730
  __proto__: null,
1731
+ BCB_CODE_SYSTEM: BCB_CODE_SYSTEM,
1732
+ CIP13_CODE_SYSTEM: CIP13_CODE_SYSTEM,
1733
+ CIS_CODE_SYSTEM: CIS_CODE_SYSTEM,
1734
+ createMedicationFromProduct: createMedicationFromProduct,
1614
1735
  createMedicationsFromBcbCodes: createMedicationsFromBcbCodes,
1615
1736
  createMedicationsFromCIP13Codes: createMedicationsFromCIP13Codes,
1616
1737
  createMedicationsFromCISCodes: createMedicationsFromCISCodes,
1738
+ createMedicationsFromProducts: createMedicationsFromProducts,
1617
1739
  extractBcbCodesFromMedications: extractBcbCodesFromMedications,
1618
1740
  extractCIP13CodesFromMedications: extractCIP13CodesFromMedications,
1619
1741
  extractCISCodesFromMedications: extractCISCodesFromMedications,
1620
1742
  extractCodesFromMedications: extractCodesFromMedications,
1743
+ extractProductLabel: extractProductLabel,
1621
1744
  generateMedicationId: generateMedicationId
1622
1745
  });
1623
1746
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudebernard/node-fhir-mapper",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "A simple FHIR / BCB resource mapper to help stay interoperable while still using the Claude Bernard intelligence",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",