@imranq2/fhirpatientsummary 1.0.20 → 1.0.22
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 +64 -3
- package/dist/index.js +64 -3
- package/package.json +22 -21
package/dist/index.cjs
CHANGED
|
@@ -145,12 +145,18 @@ var IPSSectionResourceFilters = {
|
|
|
145
145
|
var IPSSectionSummaryCompositionFilter = {
|
|
146
146
|
["AllergyIntoleranceSection" /* ALLERGIES */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "allergy_summary_document"),
|
|
147
147
|
["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "vital_summary_document"),
|
|
148
|
-
["PlanOfCareSection" /* CARE_PLAN */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "careplan_summary_document")
|
|
148
|
+
["PlanOfCareSection" /* CARE_PLAN */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "careplan_summary_document"),
|
|
149
|
+
["ImmunizationSection" /* IMMUNIZATIONS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "immunization_summary_document")
|
|
149
150
|
};
|
|
150
151
|
var IPSSectionResourceHelper = class {
|
|
151
152
|
static getResourceFilterForSection(section) {
|
|
152
153
|
return IPSSectionResourceFilters[section];
|
|
153
154
|
}
|
|
155
|
+
static getSectionResources(section, resources) {
|
|
156
|
+
const filter = IPSSectionResourceFilters[section];
|
|
157
|
+
if (!filter) return [];
|
|
158
|
+
return resources.filter(filter);
|
|
159
|
+
}
|
|
154
160
|
static getSummaryCompositionFilterForSection(section) {
|
|
155
161
|
return IPSSectionSummaryCompositionFilter[section];
|
|
156
162
|
}
|
|
@@ -330,7 +336,7 @@ var TemplateUtilities = class {
|
|
|
330
336
|
* @returns Formatted date string (date only, no time component)
|
|
331
337
|
*/
|
|
332
338
|
renderDate(date) {
|
|
333
|
-
return this.formatDateTime(date,
|
|
339
|
+
return this.formatDateTime(date, "UTC", true);
|
|
334
340
|
}
|
|
335
341
|
/**
|
|
336
342
|
* Renders a recorded date
|
|
@@ -854,7 +860,9 @@ var TemplateUtilities = class {
|
|
|
854
860
|
if (!dateTime.isValid) {
|
|
855
861
|
return String(dateValue);
|
|
856
862
|
}
|
|
857
|
-
if (
|
|
863
|
+
if (dateOnly) {
|
|
864
|
+
dateTime = dateTime.toUTC();
|
|
865
|
+
} else if (timezone) {
|
|
858
866
|
dateTime = dateTime.toUTC().setZone(timezone);
|
|
859
867
|
}
|
|
860
868
|
const formatOptions = dateOnly ? { year: "numeric", month: "2-digit", day: "2-digit" } : {
|
|
@@ -1680,6 +1688,59 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1680
1688
|
});
|
|
1681
1689
|
return _ImmunizationsTemplate.generateStaticNarrative(resources, timezone);
|
|
1682
1690
|
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Generate HTML narrative for Immunization resources using summary
|
|
1693
|
+
* @param resources - FHIR Composition resources
|
|
1694
|
+
* @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
|
|
1695
|
+
* @returns HTML string for rendering
|
|
1696
|
+
*/
|
|
1697
|
+
generateSummaryNarrative(resources, timezone) {
|
|
1698
|
+
const templateUtilities = new TemplateUtilities(resources);
|
|
1699
|
+
let html = `
|
|
1700
|
+
<div>
|
|
1701
|
+
<table>
|
|
1702
|
+
<thead>
|
|
1703
|
+
<tr>
|
|
1704
|
+
<th>Immunization</th>
|
|
1705
|
+
<th>Status</th>
|
|
1706
|
+
<th>Date</th>
|
|
1707
|
+
</tr>
|
|
1708
|
+
</thead>
|
|
1709
|
+
<tbody>`;
|
|
1710
|
+
for (const resourceItem of resources) {
|
|
1711
|
+
for (const rowData of resourceItem.section ?? []) {
|
|
1712
|
+
const data = {};
|
|
1713
|
+
for (const columnData of rowData.section ?? []) {
|
|
1714
|
+
switch (columnData.title) {
|
|
1715
|
+
case "Immunization Name":
|
|
1716
|
+
data["immunization"] = columnData.text?.div ?? "";
|
|
1717
|
+
break;
|
|
1718
|
+
case "Status":
|
|
1719
|
+
data["status"] = columnData.text?.div ?? "";
|
|
1720
|
+
break;
|
|
1721
|
+
case "occurrenceDateTime":
|
|
1722
|
+
data["occurrenceDateTime"] = columnData.text?.div ?? "";
|
|
1723
|
+
break;
|
|
1724
|
+
default:
|
|
1725
|
+
break;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
if (data["status"] === "completed") {
|
|
1729
|
+
html += `
|
|
1730
|
+
<tr>
|
|
1731
|
+
<td>${data["immunization"] ?? "-"}</td>
|
|
1732
|
+
<td>${data["status"] ?? "-"}</td>
|
|
1733
|
+
<td>${templateUtilities.renderTime(data["occurrenceDateTime"], timezone) ?? "-"}</td>
|
|
1734
|
+
</tr>`;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
html += `
|
|
1739
|
+
</tbody>
|
|
1740
|
+
</table>
|
|
1741
|
+
</div>`;
|
|
1742
|
+
return html;
|
|
1743
|
+
}
|
|
1683
1744
|
/**
|
|
1684
1745
|
* Internal static implementation that actually generates the narrative
|
|
1685
1746
|
* @param resources - FHIR resources array containing Immunization resources
|
package/dist/index.js
CHANGED
|
@@ -117,12 +117,18 @@ var IPSSectionResourceFilters = {
|
|
|
117
117
|
var IPSSectionSummaryCompositionFilter = {
|
|
118
118
|
["AllergyIntoleranceSection" /* ALLERGIES */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "allergy_summary_document"),
|
|
119
119
|
["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "vital_summary_document"),
|
|
120
|
-
["PlanOfCareSection" /* CARE_PLAN */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "careplan_summary_document")
|
|
120
|
+
["PlanOfCareSection" /* CARE_PLAN */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "careplan_summary_document"),
|
|
121
|
+
["ImmunizationSection" /* IMMUNIZATIONS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => c.system === "https://fhir.icanbwell.com/4_0_0/CodeSystem/composition/" && c.code === "immunization_summary_document")
|
|
121
122
|
};
|
|
122
123
|
var IPSSectionResourceHelper = class {
|
|
123
124
|
static getResourceFilterForSection(section) {
|
|
124
125
|
return IPSSectionResourceFilters[section];
|
|
125
126
|
}
|
|
127
|
+
static getSectionResources(section, resources) {
|
|
128
|
+
const filter = IPSSectionResourceFilters[section];
|
|
129
|
+
if (!filter) return [];
|
|
130
|
+
return resources.filter(filter);
|
|
131
|
+
}
|
|
126
132
|
static getSummaryCompositionFilterForSection(section) {
|
|
127
133
|
return IPSSectionSummaryCompositionFilter[section];
|
|
128
134
|
}
|
|
@@ -302,7 +308,7 @@ var TemplateUtilities = class {
|
|
|
302
308
|
* @returns Formatted date string (date only, no time component)
|
|
303
309
|
*/
|
|
304
310
|
renderDate(date) {
|
|
305
|
-
return this.formatDateTime(date,
|
|
311
|
+
return this.formatDateTime(date, "UTC", true);
|
|
306
312
|
}
|
|
307
313
|
/**
|
|
308
314
|
* Renders a recorded date
|
|
@@ -826,7 +832,9 @@ var TemplateUtilities = class {
|
|
|
826
832
|
if (!dateTime.isValid) {
|
|
827
833
|
return String(dateValue);
|
|
828
834
|
}
|
|
829
|
-
if (
|
|
835
|
+
if (dateOnly) {
|
|
836
|
+
dateTime = dateTime.toUTC();
|
|
837
|
+
} else if (timezone) {
|
|
830
838
|
dateTime = dateTime.toUTC().setZone(timezone);
|
|
831
839
|
}
|
|
832
840
|
const formatOptions = dateOnly ? { year: "numeric", month: "2-digit", day: "2-digit" } : {
|
|
@@ -1652,6 +1660,59 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
|
|
|
1652
1660
|
});
|
|
1653
1661
|
return _ImmunizationsTemplate.generateStaticNarrative(resources, timezone);
|
|
1654
1662
|
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Generate HTML narrative for Immunization resources using summary
|
|
1665
|
+
* @param resources - FHIR Composition resources
|
|
1666
|
+
* @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
|
|
1667
|
+
* @returns HTML string for rendering
|
|
1668
|
+
*/
|
|
1669
|
+
generateSummaryNarrative(resources, timezone) {
|
|
1670
|
+
const templateUtilities = new TemplateUtilities(resources);
|
|
1671
|
+
let html = `
|
|
1672
|
+
<div>
|
|
1673
|
+
<table>
|
|
1674
|
+
<thead>
|
|
1675
|
+
<tr>
|
|
1676
|
+
<th>Immunization</th>
|
|
1677
|
+
<th>Status</th>
|
|
1678
|
+
<th>Date</th>
|
|
1679
|
+
</tr>
|
|
1680
|
+
</thead>
|
|
1681
|
+
<tbody>`;
|
|
1682
|
+
for (const resourceItem of resources) {
|
|
1683
|
+
for (const rowData of resourceItem.section ?? []) {
|
|
1684
|
+
const data = {};
|
|
1685
|
+
for (const columnData of rowData.section ?? []) {
|
|
1686
|
+
switch (columnData.title) {
|
|
1687
|
+
case "Immunization Name":
|
|
1688
|
+
data["immunization"] = columnData.text?.div ?? "";
|
|
1689
|
+
break;
|
|
1690
|
+
case "Status":
|
|
1691
|
+
data["status"] = columnData.text?.div ?? "";
|
|
1692
|
+
break;
|
|
1693
|
+
case "occurrenceDateTime":
|
|
1694
|
+
data["occurrenceDateTime"] = columnData.text?.div ?? "";
|
|
1695
|
+
break;
|
|
1696
|
+
default:
|
|
1697
|
+
break;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
if (data["status"] === "completed") {
|
|
1701
|
+
html += `
|
|
1702
|
+
<tr>
|
|
1703
|
+
<td>${data["immunization"] ?? "-"}</td>
|
|
1704
|
+
<td>${data["status"] ?? "-"}</td>
|
|
1705
|
+
<td>${templateUtilities.renderTime(data["occurrenceDateTime"], timezone) ?? "-"}</td>
|
|
1706
|
+
</tr>`;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
html += `
|
|
1711
|
+
</tbody>
|
|
1712
|
+
</table>
|
|
1713
|
+
</div>`;
|
|
1714
|
+
return html;
|
|
1715
|
+
}
|
|
1655
1716
|
/**
|
|
1656
1717
|
* Internal static implementation that actually generates the narrative
|
|
1657
1718
|
* @param resources - FHIR resources array containing Immunization resources
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imranq2/fhirpatientsummary",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.22",
|
|
4
4
|
"description": "A template for creating npm packages using TypeScript and VSCode",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"prebuild": "npm run clean:dist",
|
|
29
29
|
"pretest": "npm run clean:coverage",
|
|
30
30
|
"cm": "cz",
|
|
31
|
-
"lint": "eslint ./src/ --ext .ts --fix",
|
|
31
|
+
"lint": "eslint ./src/ ./tests/ --ext .ts --fix",
|
|
32
32
|
"prepare": "husky",
|
|
33
33
|
"semantic-release": "semantic-release",
|
|
34
34
|
"test:watch": "jest --watch",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"typecheck": "tsc --noEmit",
|
|
37
37
|
"check:cjs-import": "node tests/build/cjs-import-check.cjs",
|
|
38
38
|
"check:esm-import": "node --experimental-vm-modules tests/build/esm-import-check.mjs",
|
|
39
|
-
"check:ts-import": "ts-node --project tsconfig.json tests/build/ts-import-check.ts"
|
|
39
|
+
"check:ts-import": "ts-node --project tsconfig.json tests/build/ts-import-check.ts",
|
|
40
|
+
"split:bundle": "node tests/full_record/split_bundle.cjs"
|
|
40
41
|
},
|
|
41
42
|
"repository": {
|
|
42
43
|
"type": "git",
|
|
@@ -68,34 +69,34 @@
|
|
|
68
69
|
"homepage": "https://github.com/icanbwell/fhir-patient-summary#readme",
|
|
69
70
|
"dependencies": {
|
|
70
71
|
"html-minifier-terser": "^7.2.0",
|
|
71
|
-
"luxon": "^3.
|
|
72
|
-
"turndown": "^7.2.
|
|
72
|
+
"luxon": "^3.7.2",
|
|
73
|
+
"turndown": "^7.2.2"
|
|
73
74
|
},
|
|
74
75
|
"devDependencies": {
|
|
75
|
-
"@eslint/js": "^9.
|
|
76
|
+
"@eslint/js": "^9.39.1",
|
|
76
77
|
"@types/html-minifier-terser": "^7.0.2",
|
|
77
78
|
"@types/jest": "^30.0.0",
|
|
78
79
|
"@types/js-beautify": "^1.14.3",
|
|
79
|
-
"@types/luxon": "^3.
|
|
80
|
-
"@types/node": "^24.
|
|
81
|
-
"@types/turndown": "^5.0.
|
|
80
|
+
"@types/luxon": "^3.7.1",
|
|
81
|
+
"@types/node": "^24.10.1",
|
|
82
|
+
"@types/turndown": "^5.0.6",
|
|
82
83
|
"commitizen": "^4.3.1",
|
|
83
|
-
"conventional-changelog-conventionalcommits": "^
|
|
84
|
-
"eslint": "^9.
|
|
85
|
-
"eslint-config-prettier": "^10.1.
|
|
84
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
85
|
+
"eslint": "^9.39.1",
|
|
86
|
+
"eslint-config-prettier": "^10.1.8",
|
|
86
87
|
"eslint-plugin-node": "^11.1.0",
|
|
87
|
-
"eslint-plugin-prettier": "^5.5.
|
|
88
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
88
89
|
"husky": "^9.1.7",
|
|
89
|
-
"jest": "^30.
|
|
90
|
+
"jest": "^30.2.0",
|
|
90
91
|
"js-beautify": "^1.15.4",
|
|
91
|
-
"lint-staged": "^16.
|
|
92
|
-
"prettier": "^3.
|
|
93
|
-
"semantic-release": "^
|
|
94
|
-
"ts-jest": "^29.4.
|
|
92
|
+
"lint-staged": "^16.2.7",
|
|
93
|
+
"prettier": "^3.7.4",
|
|
94
|
+
"semantic-release": "^25.0.2",
|
|
95
|
+
"ts-jest": "^29.4.6",
|
|
95
96
|
"ts-node": "^10.9.2",
|
|
96
|
-
"tsup": "
|
|
97
|
-
"typescript": "^5.
|
|
98
|
-
"typescript-eslint": "^8.
|
|
97
|
+
"tsup": "8.5.1",
|
|
98
|
+
"typescript": "^5.9.3",
|
|
99
|
+
"typescript-eslint": "^8.48.1"
|
|
99
100
|
},
|
|
100
101
|
"lint-staged": {
|
|
101
102
|
"src/**/*.{ts,js}": "eslint --cache --cache-location .eslintcache --fix",
|