@imranq2/fhirpatientsummary 1.0.27 → 1.0.28
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/dist/index.cjs +149 -127
- package/dist/index.d.cts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +149 -127
- package/package.json +8 -5
package/dist/index.cjs
CHANGED
|
@@ -248,7 +248,7 @@ var TemplateUtilities = class {
|
|
|
248
248
|
renderOrganization(orgRef) {
|
|
249
249
|
const organization = orgRef && this.resolveReference(orgRef);
|
|
250
250
|
if (organization && organization.resourceType === "Organization" && organization.name) {
|
|
251
|
-
return organization.name;
|
|
251
|
+
return this.renderTextAsHtml(organization.name);
|
|
252
252
|
}
|
|
253
253
|
return "";
|
|
254
254
|
}
|
|
@@ -260,7 +260,7 @@ var TemplateUtilities = class {
|
|
|
260
260
|
renderVaccineManufacturer(immunization) {
|
|
261
261
|
const organization = immunization.manufacturer && this.resolveReference(immunization.manufacturer);
|
|
262
262
|
if (organization && organization.resourceType === "Organization" && organization.name) {
|
|
263
|
-
return organization.name;
|
|
263
|
+
return this.renderTextAsHtml(organization.name);
|
|
264
264
|
}
|
|
265
265
|
return "";
|
|
266
266
|
}
|
|
@@ -299,7 +299,7 @@ var TemplateUtilities = class {
|
|
|
299
299
|
*/
|
|
300
300
|
renderMedicationCode(medication) {
|
|
301
301
|
if (medication && medication.code) {
|
|
302
|
-
return this.codeableConcept(medication.code, "display");
|
|
302
|
+
return this.renderTextAsHtml(this.codeableConcept(medication.code, "display"));
|
|
303
303
|
}
|
|
304
304
|
return "";
|
|
305
305
|
}
|
|
@@ -310,7 +310,7 @@ var TemplateUtilities = class {
|
|
|
310
310
|
*/
|
|
311
311
|
renderDoseNumber(doseNumber) {
|
|
312
312
|
if (doseNumber && doseNumber.value !== void 0) {
|
|
313
|
-
return doseNumber.value.toString();
|
|
313
|
+
return this.renderTextAsHtml(doseNumber.value.toString());
|
|
314
314
|
}
|
|
315
315
|
return "";
|
|
316
316
|
}
|
|
@@ -321,7 +321,7 @@ var TemplateUtilities = class {
|
|
|
321
321
|
*/
|
|
322
322
|
renderValueUnit(value) {
|
|
323
323
|
if (value && value.constructor?.name === "Quantity" && value.unit) {
|
|
324
|
-
return value.unit;
|
|
324
|
+
return this.renderTextAsHtml(value.unit);
|
|
325
325
|
}
|
|
326
326
|
return "";
|
|
327
327
|
}
|
|
@@ -387,7 +387,7 @@ var TemplateUtilities = class {
|
|
|
387
387
|
* @returns Comma-separated string of items
|
|
388
388
|
*/
|
|
389
389
|
safeConcat(list, attr) {
|
|
390
|
-
return this.concat(list || [], attr);
|
|
390
|
+
return this.renderTextAsHtml(this.concat(list || [], attr));
|
|
391
391
|
}
|
|
392
392
|
/**
|
|
393
393
|
* Concatenates text from a list of CodeableConcept objects
|
|
@@ -404,7 +404,7 @@ var TemplateUtilities = class {
|
|
|
404
404
|
items.push(item.text);
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
|
-
return items.join(", ");
|
|
407
|
+
return this.renderTextAsHtml(items.join(", "));
|
|
408
408
|
}
|
|
409
409
|
/**
|
|
410
410
|
* Concatenates reaction manifestations
|
|
@@ -425,7 +425,7 @@ var TemplateUtilities = class {
|
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
}
|
|
428
|
-
return texts.join(", ");
|
|
428
|
+
return this.renderTextAsHtml(texts.join(", "));
|
|
429
429
|
}
|
|
430
430
|
/**
|
|
431
431
|
* Concatenates dose numbers
|
|
@@ -442,7 +442,7 @@ var TemplateUtilities = class {
|
|
|
442
442
|
doseNumbers.push(item.doseNumberPositiveInt.toString());
|
|
443
443
|
}
|
|
444
444
|
}
|
|
445
|
-
return doseNumbers.join(", ");
|
|
445
|
+
return this.renderTextAsHtml(doseNumbers.join(", "));
|
|
446
446
|
}
|
|
447
447
|
/**
|
|
448
448
|
* Concatenates dosage routes
|
|
@@ -459,7 +459,7 @@ var TemplateUtilities = class {
|
|
|
459
459
|
routes.push(item.route.text);
|
|
460
460
|
}
|
|
461
461
|
}
|
|
462
|
-
return routes.join(", ");
|
|
462
|
+
return this.renderTextAsHtml(routes.join(", "));
|
|
463
463
|
}
|
|
464
464
|
/**
|
|
465
465
|
* Returns the first item from a list of CodeableConcept objects
|
|
@@ -468,7 +468,7 @@ var TemplateUtilities = class {
|
|
|
468
468
|
*/
|
|
469
469
|
firstFromCodeableConceptList(list) {
|
|
470
470
|
if (list && Array.isArray(list) && list[0]) {
|
|
471
|
-
return this.codeableConcept(list[0], "display");
|
|
471
|
+
return this.renderTextAsHtml(this.codeableConcept(list[0], "display"));
|
|
472
472
|
}
|
|
473
473
|
return "";
|
|
474
474
|
}
|
|
@@ -487,7 +487,7 @@ var TemplateUtilities = class {
|
|
|
487
487
|
texts.push(item.text);
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
|
-
return texts.join(", ");
|
|
490
|
+
return this.renderTextAsHtml(texts.join(", "));
|
|
491
491
|
}
|
|
492
492
|
/**
|
|
493
493
|
* Renders component codes
|
|
@@ -819,9 +819,11 @@ var TemplateUtilities = class {
|
|
|
819
819
|
return "";
|
|
820
820
|
}
|
|
821
821
|
/**
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
822
|
+
* Public method to render plain text as HTML, escaping special characters and replacing newlines with <br />.
|
|
823
|
+
* This method should be used whenever displaying user-supplied or FHIR resource text in HTML to prevent XSS vulnerabilities
|
|
824
|
+
* and to preserve formatting. Use this in templates or UI components that need to safely display multi-line or arbitrary text.
|
|
825
|
+
* @param text - The text to render as HTML
|
|
826
|
+
* @returns The HTML-safe string with newlines converted to <br />
|
|
825
827
|
*/
|
|
826
828
|
renderTextAsHtml(text) {
|
|
827
829
|
if (!text || text.trim() === "") {
|
|
@@ -885,7 +887,7 @@ var TemplateUtilities = class {
|
|
|
885
887
|
dateTime = import_luxon.DateTime.fromISO(String(dateValue));
|
|
886
888
|
}
|
|
887
889
|
if (!dateTime.isValid) {
|
|
888
|
-
return String(dateValue);
|
|
890
|
+
return this.renderTextAsHtml(String(dateValue));
|
|
889
891
|
}
|
|
890
892
|
if (dateOnly) {
|
|
891
893
|
dateTime = dateTime.toUTC();
|
|
@@ -901,9 +903,9 @@ var TemplateUtilities = class {
|
|
|
901
903
|
hour12: true,
|
|
902
904
|
timeZoneName: "short"
|
|
903
905
|
};
|
|
904
|
-
return dateTime.toLocaleString(formatOptions);
|
|
906
|
+
return this.renderTextAsHtml(dateTime.toLocaleString(formatOptions));
|
|
905
907
|
} catch {
|
|
906
|
-
return String(dateValue);
|
|
908
|
+
return this.renderTextAsHtml(String(dateValue));
|
|
907
909
|
}
|
|
908
910
|
}
|
|
909
911
|
/**
|
|
@@ -1607,7 +1609,7 @@ var PatientTemplate = class _PatientTemplate {
|
|
|
1607
1609
|
const uniqueLanguages = /* @__PURE__ */ new Set();
|
|
1608
1610
|
const preferredLanguages = /* @__PURE__ */ new Set();
|
|
1609
1611
|
patient.communication.forEach((comm) => {
|
|
1610
|
-
const language = templateUtilities.codeableConcept(comm.language);
|
|
1612
|
+
const language = templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(comm.language));
|
|
1611
1613
|
if (language) {
|
|
1612
1614
|
if (comm.preferred) {
|
|
1613
1615
|
preferredLanguages.add(language);
|
|
@@ -1665,13 +1667,13 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1665
1667
|
for (const columnData of rowData.section ?? []) {
|
|
1666
1668
|
switch (columnData.title) {
|
|
1667
1669
|
case "Allergen Name":
|
|
1668
|
-
data["allergen"] = columnData.text?.div ?? "";
|
|
1670
|
+
data["allergen"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1669
1671
|
break;
|
|
1670
1672
|
case "Criticality":
|
|
1671
|
-
data["criticality"] = columnData.text?.div ?? "";
|
|
1673
|
+
data["criticality"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1672
1674
|
break;
|
|
1673
1675
|
case "Recorded Date":
|
|
1674
|
-
data["recordedDate"] = columnData.text?.div ?? "";
|
|
1676
|
+
data["recordedDate"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1675
1677
|
break;
|
|
1676
1678
|
default:
|
|
1677
1679
|
break;
|
|
@@ -1792,11 +1794,11 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1792
1794
|
for (const allergy of allergies) {
|
|
1793
1795
|
html += `
|
|
1794
1796
|
<tr id="${templateUtilities.narrativeLinkId(allergy.extension)}">
|
|
1795
|
-
<td class="Name"><span class="AllergenName">${templateUtilities.codeableConcept(allergy.code)}</span></td>
|
|
1796
|
-
<td class="Status">${templateUtilities.codeableConcept(allergy.clinicalStatus) || "-"}</td>
|
|
1797
|
-
<td class="Category">${templateUtilities.safeConcat(allergy.category) || "-"}</td>
|
|
1798
|
-
<td class="Reaction">${templateUtilities.concatReactionManifestation(allergy.reaction) || "-"}</td>
|
|
1799
|
-
<td class="OnsetDate">${templateUtilities.renderTime(allergy.onsetDateTime, timezone) || "-"}</td>
|
|
1797
|
+
<td class="Name"><span class="AllergenName">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(allergy.code))}</span></td>
|
|
1798
|
+
<td class="Status">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(allergy.clinicalStatus)) || "-"}</td>
|
|
1799
|
+
<td class="Category">${templateUtilities.renderTextAsHtml(templateUtilities.safeConcat(allergy.category)) || "-"}</td>
|
|
1800
|
+
<td class="Reaction">${templateUtilities.renderTextAsHtml(templateUtilities.concatReactionManifestation(allergy.reaction)) || "-"}</td>
|
|
1801
|
+
<td class="OnsetDate">${templateUtilities.renderTextAsHtml(templateUtilities.renderTime(allergy.onsetDateTime, timezone)) || "-"}</td>
|
|
1800
1802
|
<td class="Comments">${templateUtilities.renderNotes(allergy.note, timezone, { styled: true, warning: true })}</td>`;
|
|
1801
1803
|
if (includeResolved) {
|
|
1802
1804
|
let endDate = "-";
|
|
@@ -1809,7 +1811,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
|
|
|
1809
1811
|
}
|
|
1810
1812
|
}
|
|
1811
1813
|
html += `
|
|
1812
|
-
<td class="ResolvedDate">${endDate}</td>`;
|
|
1814
|
+
<td class="ResolvedDate">${templateUtilities.renderTextAsHtml(endDate)}</td>`;
|
|
1813
1815
|
}
|
|
1814
1816
|
html += `</tr>`;
|
|
1815
1817
|
}
|
|
@@ -1832,17 +1834,21 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1832
1834
|
* Generate HTML narrative for Medication resources using summary
|
|
1833
1835
|
* @param resources - FHIR Composition resources
|
|
1834
1836
|
* @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
|
|
1837
|
+
* @param now - Optional current date to use for calculations (defaults to new Date())
|
|
1835
1838
|
* @returns HTML string for rendering
|
|
1836
1839
|
*/
|
|
1837
|
-
generateSummaryNarrative(resources, timezone) {
|
|
1840
|
+
generateSummaryNarrative(resources, timezone, now) {
|
|
1838
1841
|
const templateUtilities = new TemplateUtilities(resources);
|
|
1839
1842
|
let isSummaryCreated = false;
|
|
1843
|
+
const currentDate = now || /* @__PURE__ */ new Date();
|
|
1844
|
+
const twelveMonthsAgo = new Date(currentDate.getFullYear(), currentDate.getMonth() - 12, currentDate.getDate());
|
|
1840
1845
|
let html = `
|
|
1841
1846
|
<div>
|
|
1842
1847
|
<table>
|
|
1843
1848
|
<thead>
|
|
1844
1849
|
<tr>
|
|
1845
1850
|
<th>Medication</th>
|
|
1851
|
+
<th>Status</th>
|
|
1846
1852
|
<th>Sig</th>
|
|
1847
1853
|
<th>Days of Supply</th>
|
|
1848
1854
|
<th>Refills</th>
|
|
@@ -1856,40 +1862,48 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
|
|
|
1856
1862
|
for (const columnData of rowData.section ?? []) {
|
|
1857
1863
|
switch (columnData.title) {
|
|
1858
1864
|
case "Medication Name":
|
|
1859
|
-
data["medication"] = columnData.text?.div ?? "";
|
|
1865
|
+
data["medication"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1860
1866
|
break;
|
|
1861
1867
|
case "Status":
|
|
1862
|
-
data["status"] = columnData.text?.div ?? "";
|
|
1868
|
+
data["status"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1863
1869
|
break;
|
|
1864
1870
|
case "Prescriber Instruction":
|
|
1865
|
-
data["sig-prescriber"] = columnData.text?.div ?? "";
|
|
1871
|
+
data["sig-prescriber"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1866
1872
|
break;
|
|
1867
1873
|
case "Pharmacy Instruction":
|
|
1868
|
-
data["sig-pharmacy"] = columnData.text?.div ?? "";
|
|
1874
|
+
data["sig-pharmacy"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1869
1875
|
break;
|
|
1870
1876
|
case "Days Of Supply":
|
|
1871
|
-
data["daysOfSupply"] = columnData.text?.div ?? "";
|
|
1877
|
+
data["daysOfSupply"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1872
1878
|
break;
|
|
1873
1879
|
case "Refills Remaining":
|
|
1874
|
-
data["refills"] = columnData.text?.div ?? "";
|
|
1880
|
+
data["refills"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1875
1881
|
break;
|
|
1876
1882
|
case "Authored On Date":
|
|
1877
|
-
data["startDate"] = columnData.text?.div ?? "";
|
|
1883
|
+
data["startDate"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
1878
1884
|
break;
|
|
1879
1885
|
default:
|
|
1880
1886
|
break;
|
|
1881
1887
|
}
|
|
1882
1888
|
}
|
|
1883
|
-
|
|
1889
|
+
let startDateObj;
|
|
1890
|
+
if (data["startDate"]) {
|
|
1891
|
+
startDateObj = new Date(data["startDate"]);
|
|
1892
|
+
if (isNaN(startDateObj.getTime())) {
|
|
1893
|
+
startDateObj = void 0;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
if (data["status"] === "active" || startDateObj && startDateObj >= twelveMonthsAgo) {
|
|
1884
1897
|
isSummaryCreated = true;
|
|
1885
1898
|
html += `
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1899
|
+
<tr>
|
|
1900
|
+
<td>${templateUtilities.renderTextAsHtml(data["medication"])}</td>
|
|
1901
|
+
<td>${templateUtilities.renderTextAsHtml(data["status"])}</td>
|
|
1902
|
+
<td>${templateUtilities.renderTextAsHtml(data["sig-prescriber"] || data["sig-pharmacy"])}</td>
|
|
1903
|
+
<td>${templateUtilities.renderTextAsHtml(data["daysOfSupply"])}</td>
|
|
1904
|
+
<td>${templateUtilities.renderTextAsHtml(data["refills"])}</td>
|
|
1905
|
+
<td>${templateUtilities.renderTime(data["startDate"], timezone)}</td>
|
|
1906
|
+
</tr>`;
|
|
1893
1907
|
}
|
|
1894
1908
|
}
|
|
1895
1909
|
}
|
|
@@ -2111,13 +2125,13 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2111
2125
|
for (const columnData of rowData.section ?? []) {
|
|
2112
2126
|
switch (columnData.title) {
|
|
2113
2127
|
case "Immunization Name":
|
|
2114
|
-
data["immunization"] = columnData.text?.div ?? "";
|
|
2128
|
+
data["immunization"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2115
2129
|
break;
|
|
2116
2130
|
case "Status":
|
|
2117
|
-
data["status"] = columnData.text?.div ?? "";
|
|
2131
|
+
data["status"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2118
2132
|
break;
|
|
2119
2133
|
case "occurrenceDateTime":
|
|
2120
|
-
data["occurrenceDateTime"] = columnData.text?.div ?? "";
|
|
2134
|
+
data["occurrenceDateTime"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2121
2135
|
break;
|
|
2122
2136
|
default:
|
|
2123
2137
|
break;
|
|
@@ -2168,7 +2182,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
2168
2182
|
const imm = resourceItem;
|
|
2169
2183
|
html += `
|
|
2170
2184
|
<tr id="${templateUtilities.narrativeLinkId(imm)}">
|
|
2171
|
-
<td>${templateUtilities.codeableConcept(imm.vaccineCode)}</td>
|
|
2185
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(imm.vaccineCode))}</td>
|
|
2172
2186
|
<td>${imm.status || ""}</td>
|
|
2173
2187
|
<td>${templateUtilities.concatDoseNumber(imm.protocolApplied)}</td>
|
|
2174
2188
|
<td>${templateUtilities.renderVaccineManufacturer(imm)}</td>
|
|
@@ -2224,7 +2238,7 @@ var ProblemListTemplate = class _ProblemListTemplate {
|
|
|
2224
2238
|
<tbody>`;
|
|
2225
2239
|
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
2226
2240
|
for (const cond of activeConditions) {
|
|
2227
|
-
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
2241
|
+
const conditionCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(cond.code));
|
|
2228
2242
|
if (!addedConditionCodes.has(conditionCode)) {
|
|
2229
2243
|
addedConditionCodes.add(conditionCode);
|
|
2230
2244
|
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
@@ -2284,7 +2298,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2284
2298
|
const vitalData = {};
|
|
2285
2299
|
for (const component of columnData.section?.[0]?.section ?? []) {
|
|
2286
2300
|
if (component.title) {
|
|
2287
|
-
vitalData[component.title] = component.text?.div ?? "";
|
|
2301
|
+
vitalData[component.title] = templateUtilities.renderTextAsHtml(component.text?.div ?? "");
|
|
2288
2302
|
}
|
|
2289
2303
|
}
|
|
2290
2304
|
const vitalValue = templateUtilities.extractObservationSummaryValue(
|
|
@@ -2296,7 +2310,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2296
2310
|
data[dataKey] = vitalValue;
|
|
2297
2311
|
}
|
|
2298
2312
|
}
|
|
2299
|
-
data[columnTitle] = columnData.text?.div ?? "";
|
|
2313
|
+
data[columnTitle] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2300
2314
|
}
|
|
2301
2315
|
}
|
|
2302
2316
|
isSummaryCreated = true;
|
|
@@ -2346,7 +2360,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
|
|
|
2346
2360
|
for (const obs of observations) {
|
|
2347
2361
|
html += `
|
|
2348
2362
|
<tr id="${templateUtilities.narrativeLinkId(obs)}">
|
|
2349
|
-
<td>${templateUtilities.codeableConcept(obs.code, "display")}</td>
|
|
2363
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(obs.code, "display"))}</td>
|
|
2350
2364
|
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
2351
2365
|
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
2352
2366
|
<td>${templateUtilities.firstFromCodeableConceptList(obs.interpretation)}</td>
|
|
@@ -2400,10 +2414,10 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
|
|
|
2400
2414
|
for (const dus of deviceStatements) {
|
|
2401
2415
|
html += `
|
|
2402
2416
|
<tr id="${templateUtilities.narrativeLinkId(dus)}">
|
|
2403
|
-
<td>${templateUtilities.renderDevice(dus.device)}</td>
|
|
2404
|
-
<td>${dus.status || ""}</td>
|
|
2417
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device))}</td>
|
|
2418
|
+
<td>${templateUtilities.renderTextAsHtml(dus.status || "")}</td>
|
|
2405
2419
|
<td>${templateUtilities.renderNotes(dus.note, timezone)}</td>
|
|
2406
|
-
<td>${templateUtilities.renderRecorded(dus.recordedOn, timezone)}</td>
|
|
2420
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.renderRecorded(dus.recordedOn, timezone))}</td>
|
|
2407
2421
|
</tr>`;
|
|
2408
2422
|
}
|
|
2409
2423
|
html += `
|
|
@@ -2539,149 +2553,150 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2539
2553
|
* Helper function to extract observation field data
|
|
2540
2554
|
* @param column - Column data from the summary
|
|
2541
2555
|
* @param targetData - Record to populate with extracted data
|
|
2556
|
+
* @param templateUtilities - Instance of TemplateUtilities for utility functions
|
|
2542
2557
|
*/
|
|
2543
|
-
extractSummaryObservationFields(column, targetData) {
|
|
2558
|
+
extractSummaryObservationFields(column, targetData, templateUtilities) {
|
|
2544
2559
|
switch (column.title) {
|
|
2545
2560
|
case "Labs Name":
|
|
2546
|
-
targetData["code"] = column.text?.div ?? "";
|
|
2561
|
+
targetData["code"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2547
2562
|
break;
|
|
2548
2563
|
case "effectiveDateTime":
|
|
2549
|
-
targetData["effectiveDateTime"] = column.text?.div ?? "";
|
|
2564
|
+
targetData["effectiveDateTime"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2550
2565
|
break;
|
|
2551
2566
|
case "effectivePeriod.start":
|
|
2552
|
-
targetData["effectivePeriodStart"] = column.text?.div ?? "";
|
|
2567
|
+
targetData["effectivePeriodStart"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2553
2568
|
break;
|
|
2554
2569
|
case "effectivePeriod.end":
|
|
2555
|
-
targetData["effectivePeriodEnd"] = column.text?.div ?? "";
|
|
2570
|
+
targetData["effectivePeriodEnd"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2556
2571
|
break;
|
|
2557
2572
|
// valueQuantity
|
|
2558
2573
|
case "valueQuantity.value":
|
|
2559
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2574
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2560
2575
|
targetData["valueType"] = "valueQuantity";
|
|
2561
2576
|
break;
|
|
2562
2577
|
case "valueQuantity.unit":
|
|
2563
|
-
targetData["unit"] = column.text?.div ?? "";
|
|
2578
|
+
targetData["unit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2564
2579
|
break;
|
|
2565
2580
|
// valueCodeableConcept
|
|
2566
2581
|
case "valueCodeableConcept.text":
|
|
2567
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2582
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2568
2583
|
targetData["valueType"] = "valueCodeableConcept";
|
|
2569
2584
|
break;
|
|
2570
2585
|
case "valueCodeableConcept.coding.display":
|
|
2571
2586
|
if (!targetData["value"]) {
|
|
2572
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2587
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2573
2588
|
targetData["valueType"] = "valueCodeableConcept";
|
|
2574
2589
|
}
|
|
2575
2590
|
break;
|
|
2576
2591
|
// valueString
|
|
2577
2592
|
case "valueString":
|
|
2578
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2593
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2579
2594
|
targetData["valueType"] = "valueString";
|
|
2580
2595
|
break;
|
|
2581
2596
|
// valueBoolean
|
|
2582
2597
|
case "valueBoolean":
|
|
2583
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2598
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2584
2599
|
targetData["valueType"] = "valueBoolean";
|
|
2585
2600
|
break;
|
|
2586
2601
|
// valueInteger
|
|
2587
2602
|
case "valueInteger":
|
|
2588
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2603
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2589
2604
|
targetData["valueType"] = "valueInteger";
|
|
2590
2605
|
break;
|
|
2591
2606
|
// valueDateTime
|
|
2592
2607
|
case "valueDateTime":
|
|
2593
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2608
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2594
2609
|
targetData["valueType"] = "valueDateTime";
|
|
2595
2610
|
break;
|
|
2596
2611
|
// valuePeriod
|
|
2597
2612
|
case "valuePeriod.start":
|
|
2598
|
-
targetData["valuePeriodStart"] = column.text?.div ?? "";
|
|
2613
|
+
targetData["valuePeriodStart"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2599
2614
|
targetData["valueType"] = "valuePeriod";
|
|
2600
2615
|
break;
|
|
2601
2616
|
case "valuePeriod.end":
|
|
2602
|
-
targetData["valuePeriodEnd"] = column.text?.div ?? "";
|
|
2617
|
+
targetData["valuePeriodEnd"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2603
2618
|
targetData["valueType"] = "valuePeriod";
|
|
2604
2619
|
break;
|
|
2605
2620
|
// valueTime
|
|
2606
2621
|
case "valueTime":
|
|
2607
|
-
targetData["value"] = column.text?.div ?? "";
|
|
2622
|
+
targetData["value"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2608
2623
|
targetData["valueType"] = "valueTime";
|
|
2609
2624
|
break;
|
|
2610
2625
|
// valueSampledData
|
|
2611
2626
|
case "valueSampledData.origin.value":
|
|
2612
|
-
targetData["sampledDataOriginValue"] = column.text?.div ?? "";
|
|
2627
|
+
targetData["sampledDataOriginValue"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2613
2628
|
targetData["valueType"] = "valueSampledData";
|
|
2614
2629
|
break;
|
|
2615
2630
|
case "valueSampledData.origin.unit":
|
|
2616
|
-
targetData["sampledDataOriginUnit"] = column.text?.div ?? "";
|
|
2631
|
+
targetData["sampledDataOriginUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2617
2632
|
break;
|
|
2618
2633
|
case "valueSampledData.period":
|
|
2619
|
-
targetData["sampledDataPeriod"] = column.text?.div ?? "";
|
|
2634
|
+
targetData["sampledDataPeriod"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2620
2635
|
break;
|
|
2621
2636
|
case "valueSampledData.factor":
|
|
2622
|
-
targetData["sampledDataFactor"] = column.text?.div ?? "";
|
|
2637
|
+
targetData["sampledDataFactor"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2623
2638
|
break;
|
|
2624
2639
|
case "valueSampledData.lowerLimit":
|
|
2625
|
-
targetData["sampledDataLowerLimit"] = column.text?.div ?? "";
|
|
2640
|
+
targetData["sampledDataLowerLimit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2626
2641
|
break;
|
|
2627
2642
|
case "valueSampledData.upperLimit":
|
|
2628
|
-
targetData["sampledDataUpperLimit"] = column.text?.div ?? "";
|
|
2643
|
+
targetData["sampledDataUpperLimit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2629
2644
|
break;
|
|
2630
2645
|
case "valueSampledData.data":
|
|
2631
|
-
targetData["sampledDataData"] = column.text?.div ?? "";
|
|
2646
|
+
targetData["sampledDataData"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2632
2647
|
break;
|
|
2633
2648
|
// valueRange
|
|
2634
2649
|
case "valueRange.low.value":
|
|
2635
|
-
targetData["valueRangeLowValue"] = column.text?.div ?? "";
|
|
2650
|
+
targetData["valueRangeLowValue"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2636
2651
|
targetData["valueType"] = "valueRange";
|
|
2637
2652
|
break;
|
|
2638
2653
|
case "valueRange.low.unit":
|
|
2639
|
-
targetData["valueRangeLowUnit"] = column.text?.div ?? "";
|
|
2654
|
+
targetData["valueRangeLowUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2640
2655
|
break;
|
|
2641
2656
|
case "valueRange.high.value":
|
|
2642
|
-
targetData["valueRangeHighValue"] = column.text?.div ?? "";
|
|
2657
|
+
targetData["valueRangeHighValue"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2643
2658
|
break;
|
|
2644
2659
|
case "valueRange.high.unit":
|
|
2645
|
-
targetData["valueRangeHighUnit"] = column.text?.div ?? "";
|
|
2660
|
+
targetData["valueRangeHighUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2646
2661
|
break;
|
|
2647
2662
|
// valueRatio
|
|
2648
2663
|
case "valueRatio.numerator.value":
|
|
2649
|
-
targetData["valueRatioNumeratorValue"] = column.text?.div ?? "";
|
|
2664
|
+
targetData["valueRatioNumeratorValue"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2650
2665
|
targetData["valueType"] = "valueRatio";
|
|
2651
2666
|
break;
|
|
2652
2667
|
case "valueRatio.numerator.unit":
|
|
2653
|
-
targetData["valueRatioNumeratorUnit"] = column.text?.div ?? "";
|
|
2668
|
+
targetData["valueRatioNumeratorUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2654
2669
|
break;
|
|
2655
2670
|
case "valueRatio.denominator.value":
|
|
2656
|
-
targetData["valueRatioDenominatorValue"] = column.text?.div ?? "";
|
|
2671
|
+
targetData["valueRatioDenominatorValue"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2657
2672
|
break;
|
|
2658
2673
|
case "valueRatio.denominator.unit":
|
|
2659
|
-
targetData["valueRatioDenominatorUnit"] = column.text?.div ?? "";
|
|
2674
|
+
targetData["valueRatioDenominatorUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2660
2675
|
break;
|
|
2661
2676
|
// referenceRange
|
|
2662
2677
|
case "referenceRange.low.value":
|
|
2663
|
-
targetData["referenceRangeLow"] = column.text?.div ?? "";
|
|
2678
|
+
targetData["referenceRangeLow"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2664
2679
|
break;
|
|
2665
2680
|
case "referenceRange.low.unit":
|
|
2666
|
-
targetData["referenceRangeLowUnit"] = column.text?.div ?? "";
|
|
2681
|
+
targetData["referenceRangeLowUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2667
2682
|
break;
|
|
2668
2683
|
case "referenceRange.high.value":
|
|
2669
|
-
targetData["referenceRangeHigh"] = column.text?.div ?? "";
|
|
2684
|
+
targetData["referenceRangeHigh"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2670
2685
|
break;
|
|
2671
2686
|
case "referenceRange.high.unit":
|
|
2672
|
-
targetData["referenceRangeHighUnit"] = column.text?.div ?? "";
|
|
2687
|
+
targetData["referenceRangeHighUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2673
2688
|
break;
|
|
2674
2689
|
case "referenceRange.age.low.value":
|
|
2675
|
-
targetData["referenceRangeAgeLowValue"] = column.text?.div ?? "";
|
|
2690
|
+
targetData["referenceRangeAgeLowValue"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2676
2691
|
break;
|
|
2677
2692
|
case "referenceRange.age.low.unit":
|
|
2678
|
-
targetData["referenceRangeAgeLowUnit"] = column.text?.div ?? "";
|
|
2693
|
+
targetData["referenceRangeAgeLowUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2679
2694
|
break;
|
|
2680
2695
|
case "referenceRange.age.high.value":
|
|
2681
|
-
targetData["referenceRangeAgeHighValue"] = column.text?.div ?? "";
|
|
2696
|
+
targetData["referenceRangeAgeHighValue"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2682
2697
|
break;
|
|
2683
2698
|
case "referenceRange.age.high.unit":
|
|
2684
|
-
targetData["referenceRangeAgeHighUnit"] = column.text?.div ?? "";
|
|
2699
|
+
targetData["referenceRangeAgeHighUnit"] = templateUtilities.renderTextAsHtml(column.text?.div ?? "");
|
|
2685
2700
|
break;
|
|
2686
2701
|
default:
|
|
2687
2702
|
break;
|
|
@@ -2734,28 +2749,28 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2734
2749
|
for (const componentSection of columnData.section) {
|
|
2735
2750
|
const componentData = {};
|
|
2736
2751
|
for (const nestedColumn of componentSection.section ?? []) {
|
|
2737
|
-
this.extractSummaryObservationFields(nestedColumn, componentData);
|
|
2752
|
+
this.extractSummaryObservationFields(nestedColumn, componentData, templateUtilities);
|
|
2738
2753
|
}
|
|
2739
2754
|
if (Object.keys(componentData).length > 0) {
|
|
2740
2755
|
components.push(componentData);
|
|
2741
2756
|
}
|
|
2742
2757
|
}
|
|
2743
2758
|
} else {
|
|
2744
|
-
this.extractSummaryObservationFields(columnData, data);
|
|
2759
|
+
this.extractSummaryObservationFields(columnData, data, templateUtilities);
|
|
2745
2760
|
}
|
|
2746
2761
|
} else if (resourceItem.title === "DiagnosticReportLab Summary Grouped by DiagnosticReport|Lab Code") {
|
|
2747
2762
|
switch (columnData.title) {
|
|
2748
2763
|
case "Diagnostic Report Name":
|
|
2749
|
-
data["report"] = columnData.text?.div ?? "";
|
|
2764
|
+
data["report"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2750
2765
|
break;
|
|
2751
2766
|
case "Performer":
|
|
2752
|
-
data["performer"] = columnData.text?.div ?? "";
|
|
2767
|
+
data["performer"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2753
2768
|
break;
|
|
2754
2769
|
case "Issued Date":
|
|
2755
|
-
data["issued"] = columnData.text?.div ?? "";
|
|
2770
|
+
data["issued"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2756
2771
|
break;
|
|
2757
2772
|
case "Status":
|
|
2758
|
-
data["status"] = columnData.text?.div ?? "";
|
|
2773
|
+
data["status"] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
2759
2774
|
break;
|
|
2760
2775
|
default:
|
|
2761
2776
|
break;
|
|
@@ -2780,8 +2795,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2780
2795
|
observationhtml += `
|
|
2781
2796
|
<tr>
|
|
2782
2797
|
<td>${componentCode}</td>
|
|
2783
|
-
<td>${component["formattedValue"] ?? "-"}</td>
|
|
2784
|
-
<td>${component["referenceRange"]?.trim() ?? "-"}</td>
|
|
2798
|
+
<td>${templateUtilities.renderTextAsHtml(component["formattedValue"]) ?? "-"}</td>
|
|
2799
|
+
<td>${templateUtilities.renderTextAsHtml(component["referenceRange"])?.trim() ?? "-"}</td>
|
|
2785
2800
|
<td>${date ?? "-"}</td>
|
|
2786
2801
|
</tr>`;
|
|
2787
2802
|
}
|
|
@@ -2794,8 +2809,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2794
2809
|
observationhtml += `
|
|
2795
2810
|
<tr>
|
|
2796
2811
|
<td>${data["code"] ?? "-"}</td>
|
|
2797
|
-
<td>${data["formattedValue"] ?? "-"}</td>
|
|
2798
|
-
<td>${data["referenceRange"]?.trim() ?? "-"}</td>
|
|
2812
|
+
<td>${templateUtilities.renderTextAsHtml(data["formattedValue"]) ?? "-"}</td>
|
|
2813
|
+
<td>${templateUtilities.renderTextAsHtml(data["referenceRange"])?.trim() ?? "-"}</td>
|
|
2799
2814
|
<td>${date ?? "-"}</td>
|
|
2800
2815
|
</tr>`;
|
|
2801
2816
|
}
|
|
@@ -2955,7 +2970,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2955
2970
|
<tbody>`;
|
|
2956
2971
|
const observationAdded = /* @__PURE__ */ new Set();
|
|
2957
2972
|
for (const obs of observations) {
|
|
2958
|
-
const obsCode = templateUtilities.codeableConcept(obs.code);
|
|
2973
|
+
const obsCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(obs.code));
|
|
2959
2974
|
if (!observationAdded.has(obsCode)) {
|
|
2960
2975
|
observationAdded.add(obsCode);
|
|
2961
2976
|
html += `
|
|
@@ -2994,7 +3009,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
|
|
|
2994
3009
|
<tbody>`;
|
|
2995
3010
|
const diagnosticReportAdded = /* @__PURE__ */ new Set();
|
|
2996
3011
|
for (const report of reports) {
|
|
2997
|
-
const reportName = templateUtilities.codeableConcept(report.code);
|
|
3012
|
+
const reportName = templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(report.code));
|
|
2998
3013
|
if (!diagnosticReportAdded.has(reportName)) {
|
|
2999
3014
|
diagnosticReportAdded.add(reportName);
|
|
3000
3015
|
let resultCount = "";
|
|
@@ -3108,7 +3123,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
|
|
|
3108
3123
|
const proc = resourceItem;
|
|
3109
3124
|
html += `
|
|
3110
3125
|
<tr id="${templateUtilities.narrativeLinkId(proc)}">
|
|
3111
|
-
<td>${templateUtilities.codeableConcept(proc.code, "display")}</td>
|
|
3126
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(proc.code, "display"))}</td>
|
|
3112
3127
|
<td>${templateUtilities.renderNotes(proc.note, timezone)}</td>
|
|
3113
3128
|
<td>${proc.performedDateTime ? templateUtilities.renderTime(proc.performedDateTime, timezone) : proc.performedPeriod ? templateUtilities.renderPeriod(proc.performedPeriod, timezone) : ""}</td>
|
|
3114
3129
|
</tr>`;
|
|
@@ -3160,7 +3175,7 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
|
|
|
3160
3175
|
for (const obs of observations) {
|
|
3161
3176
|
html += `
|
|
3162
3177
|
<tr id="${templateUtilities.narrativeLinkId(obs)}">
|
|
3163
|
-
<td>${templateUtilities.codeableConcept(obs.code)}</td>
|
|
3178
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(obs.code))}</td>
|
|
3164
3179
|
<td>${templateUtilities.extractObservationValue(obs)}</td>
|
|
3165
3180
|
<td>${templateUtilities.extractObservationValueUnit(obs)}</td>
|
|
3166
3181
|
<td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
|
|
@@ -3205,7 +3220,7 @@ var PastHistoryOfIllnessTemplate = class {
|
|
|
3205
3220
|
<tbody>`;
|
|
3206
3221
|
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
3207
3222
|
for (const cond of resolvedConditions) {
|
|
3208
|
-
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
3223
|
+
const conditionCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(cond.code));
|
|
3209
3224
|
if (!addedConditionCodes.has(conditionCode)) {
|
|
3210
3225
|
addedConditionCodes.add(conditionCode);
|
|
3211
3226
|
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
@@ -3291,7 +3306,7 @@ var PlanOfCareTemplate = class {
|
|
|
3291
3306
|
const data = {};
|
|
3292
3307
|
for (const columnData of rowData.section ?? []) {
|
|
3293
3308
|
if (columnData.title) {
|
|
3294
|
-
data[columnData.title] = columnData.text?.div ?? "";
|
|
3309
|
+
data[columnData.title] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
|
|
3295
3310
|
}
|
|
3296
3311
|
}
|
|
3297
3312
|
if (data["status"] !== "active") {
|
|
@@ -3367,7 +3382,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3367
3382
|
<tbody>`;
|
|
3368
3383
|
const addedConditionCodes = /* @__PURE__ */ new Set();
|
|
3369
3384
|
for (const cond of activeConditions) {
|
|
3370
|
-
const conditionCode = templateUtilities.codeableConcept(cond.code);
|
|
3385
|
+
const conditionCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(cond.code));
|
|
3371
3386
|
if (!addedConditionCodes.has(conditionCode)) {
|
|
3372
3387
|
addedConditionCodes.add(conditionCode);
|
|
3373
3388
|
html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
|
|
@@ -3412,7 +3427,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
|
|
|
3412
3427
|
if (impression.finding && impression.finding.length > 0) {
|
|
3413
3428
|
findingsHtml = "<ul>";
|
|
3414
3429
|
for (const finding of impression.finding) {
|
|
3415
|
-
const findingText = finding.itemCodeableConcept ? templateUtilities.codeableConcept(finding.itemCodeableConcept) : finding.itemReference ? templateUtilities.renderReference(finding.itemReference) : "";
|
|
3430
|
+
const findingText = finding.itemCodeableConcept ? templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(finding.itemCodeableConcept)) : finding.itemReference ? templateUtilities.renderReference(finding.itemReference) : "";
|
|
3416
3431
|
const cause = finding.basis || "";
|
|
3417
3432
|
findingsHtml += `<li>${findingText}${cause ? ` - ${cause}` : ""}</li>`;
|
|
3418
3433
|
}
|
|
@@ -3473,9 +3488,9 @@ var PregnancyTemplate = class _PregnancyTemplate {
|
|
|
3473
3488
|
const obs = resource;
|
|
3474
3489
|
html += `
|
|
3475
3490
|
<tr id="${templateUtilities.narrativeLinkId(obs)}">
|
|
3476
|
-
<td>${templateUtilities.extractPregnancyStatus(obs)}</td>
|
|
3491
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.extractPregnancyStatus(obs))}</td>
|
|
3477
3492
|
<td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
|
|
3478
|
-
<td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
|
|
3493
|
+
<td>${obs.effectiveDateTime ? templateUtilities.renderTextAsHtml(templateUtilities.renderTime(obs.effectiveDateTime, timezone)) : obs.effectivePeriod ? templateUtilities.renderTextAsHtml(templateUtilities.renderPeriod(obs.effectivePeriod, timezone)) : ""}</td>
|
|
3479
3494
|
</tr>`;
|
|
3480
3495
|
}
|
|
3481
3496
|
html += `
|
|
@@ -3525,7 +3540,7 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
|
|
|
3525
3540
|
const consent = resourceItem;
|
|
3526
3541
|
html += `
|
|
3527
3542
|
<tr id="${templateUtilities.narrativeLinkId(consent)}">
|
|
3528
|
-
<td>${templateUtilities.codeableConcept(consent.scope, "display")}</td>
|
|
3543
|
+
<td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConcept(consent.scope, "display"))}</td>
|
|
3529
3544
|
<td>${consent.status || ""}</td>
|
|
3530
3545
|
<td>${consent.provision?.action ? templateUtilities.concatCodeableConcept(consent.provision.action) : ""}</td>
|
|
3531
3546
|
<td>${consent.dateTime || ""}</td>
|
|
@@ -3546,16 +3561,18 @@ var TypeScriptTemplateMapper = class {
|
|
|
3546
3561
|
* @param resources - FHIR resources
|
|
3547
3562
|
* @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
|
|
3548
3563
|
* @param useSectionSummary - Whether to use the section summary for narrative generation
|
|
3564
|
+
* @param now - Optional current date to use for generating relative dates in the narrative
|
|
3549
3565
|
* @returns HTML string for rendering
|
|
3550
3566
|
*/
|
|
3551
|
-
static generateNarrative(section, resources, timezone, useSectionSummary = false) {
|
|
3567
|
+
static generateNarrative(section, resources, timezone, useSectionSummary = false, now) {
|
|
3552
3568
|
const templateClass = this.sectionToTemplate[section];
|
|
3553
3569
|
if (!templateClass) {
|
|
3554
3570
|
throw new Error(`No template found for section: ${section}`);
|
|
3555
3571
|
}
|
|
3556
3572
|
return useSectionSummary ? templateClass.generateSummaryNarrative(
|
|
3557
3573
|
resources,
|
|
3558
|
-
timezone
|
|
3574
|
+
timezone,
|
|
3575
|
+
now
|
|
3559
3576
|
) : templateClass.generateNarrative(resources, timezone);
|
|
3560
3577
|
}
|
|
3561
3578
|
};
|
|
@@ -3613,14 +3630,15 @@ var NarrativeGenerator = class {
|
|
|
3613
3630
|
* @param resources - Array of domain resources
|
|
3614
3631
|
* @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
|
|
3615
3632
|
* @param useSectionSummary - Whether to use section summary for narrative generation (default: false)
|
|
3633
|
+
* @param now - Optional date parameter
|
|
3616
3634
|
* @returns Generated HTML content or undefined if no resources
|
|
3617
3635
|
*/
|
|
3618
|
-
static async generateNarrativeContentAsync(section, resources, timezone, useSectionSummary = false) {
|
|
3636
|
+
static async generateNarrativeContentAsync(section, resources, timezone, useSectionSummary = false, now) {
|
|
3619
3637
|
if (!resources || resources.length === 0) {
|
|
3620
3638
|
return void 0;
|
|
3621
3639
|
}
|
|
3622
3640
|
try {
|
|
3623
|
-
const content = TypeScriptTemplateMapper.generateNarrative(section, resources, timezone, useSectionSummary);
|
|
3641
|
+
const content = TypeScriptTemplateMapper.generateNarrative(section, resources, timezone, useSectionSummary, now);
|
|
3624
3642
|
if (!content) {
|
|
3625
3643
|
return void 0;
|
|
3626
3644
|
}
|
|
@@ -3642,8 +3660,8 @@ var NarrativeGenerator = class {
|
|
|
3642
3660
|
const options = aggressive ? AGGRESSIVE_MINIFY_OPTIONS : DEFAULT_MINIFY_OPTIONS;
|
|
3643
3661
|
return await (0, import_html_minifier_terser.minify)(html, options);
|
|
3644
3662
|
} catch (error) {
|
|
3645
|
-
console.warn("HTML minification failed", error);
|
|
3646
|
-
return
|
|
3663
|
+
console.warn("HTML minification failed", error, html);
|
|
3664
|
+
return `${error instanceof Error ? error.message : String(error)}`;
|
|
3647
3665
|
}
|
|
3648
3666
|
}
|
|
3649
3667
|
/**
|
|
@@ -3672,10 +3690,11 @@ var NarrativeGenerator = class {
|
|
|
3672
3690
|
* @param timezone - Optional timezone to use for date formatting
|
|
3673
3691
|
* @param minify - Whether to minify the HTML content (default: true)
|
|
3674
3692
|
* @param useSectionSummary - Whether to use section summary for narrative generation (default: false)
|
|
3693
|
+
* @param now - Optional date parameter
|
|
3675
3694
|
* @returns Promise that resolves to a FHIR Narrative object or undefined if no resources
|
|
3676
3695
|
*/
|
|
3677
|
-
static async generateNarrativeAsync(section, resources, timezone, minify = true, useSectionSummary = false) {
|
|
3678
|
-
const content = await this.generateNarrativeContentAsync(section, resources, timezone, useSectionSummary);
|
|
3696
|
+
static async generateNarrativeAsync(section, resources, timezone, minify = true, useSectionSummary = false, now) {
|
|
3697
|
+
const content = await this.generateNarrativeContentAsync(section, resources, timezone, useSectionSummary, now);
|
|
3679
3698
|
if (!content) {
|
|
3680
3699
|
return void 0;
|
|
3681
3700
|
}
|
|
@@ -3852,8 +3871,9 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
3852
3871
|
* @param baseUrl - Base URL for the FHIR server (e.g., 'https://example.com/fhir')
|
|
3853
3872
|
* @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
|
|
3854
3873
|
* @param patientId - Optional patient ID to use as primary patient for composition reference
|
|
3874
|
+
* @param now - Optional current date to use for composition date (defaults to new Date())
|
|
3855
3875
|
*/
|
|
3856
|
-
async buildBundleAsync(authorOrganizationId, authorOrganizationName, baseUrl, timezone, patientId) {
|
|
3876
|
+
async buildBundleAsync(authorOrganizationId, authorOrganizationName, baseUrl, timezone, patientId, now) {
|
|
3857
3877
|
if (baseUrl.endsWith("/")) {
|
|
3858
3878
|
baseUrl = baseUrl.slice(0, -1);
|
|
3859
3879
|
}
|
|
@@ -3880,20 +3900,22 @@ var ComprehensiveIPSCompositionBuilder = class {
|
|
|
3880
3900
|
// Assuming patient is also a practitioner for simplicity
|
|
3881
3901
|
display: authorOrganizationName
|
|
3882
3902
|
}],
|
|
3883
|
-
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3903
|
+
date: (now || /* @__PURE__ */ new Date()).toISOString(),
|
|
3884
3904
|
title: "International Patient Summary",
|
|
3885
3905
|
section: this.sections,
|
|
3886
3906
|
text: await NarrativeGenerator.generateNarrativeAsync(
|
|
3887
3907
|
"Patient" /* PATIENT */,
|
|
3888
3908
|
this.patients,
|
|
3889
3909
|
timezone,
|
|
3890
|
-
true
|
|
3910
|
+
true,
|
|
3911
|
+
false,
|
|
3912
|
+
now
|
|
3891
3913
|
)
|
|
3892
3914
|
};
|
|
3893
3915
|
const bundle = {
|
|
3894
3916
|
resourceType: "Bundle",
|
|
3895
3917
|
type: "document",
|
|
3896
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3918
|
+
timestamp: (now || /* @__PURE__ */ new Date()).toISOString(),
|
|
3897
3919
|
identifier: {
|
|
3898
3920
|
"system": "urn:ietf:rfc:3986",
|
|
3899
3921
|
"value": "urn:uuid:4dcfd353-49fd-4ab0-b521-c8d57ced74d6"
|