@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 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, void 0, true);
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 (timezone && !dateOnly) {
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, void 0, true);
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 (timezone && !dateOnly) {
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.20",
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.6.1",
72
- "turndown": "^7.2.0"
72
+ "luxon": "^3.7.2",
73
+ "turndown": "^7.2.2"
73
74
  },
74
75
  "devDependencies": {
75
- "@eslint/js": "^9.29.0",
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.6.2",
80
- "@types/node": "^24.0.3",
81
- "@types/turndown": "^5.0.5",
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": "^8.0.0",
84
- "eslint": "^9.29.0",
85
- "eslint-config-prettier": "^10.1.5",
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.0",
88
+ "eslint-plugin-prettier": "^5.5.4",
88
89
  "husky": "^9.1.7",
89
- "jest": "^30.0.0",
90
+ "jest": "^30.2.0",
90
91
  "js-beautify": "^1.15.4",
91
- "lint-staged": "^16.1.2",
92
- "prettier": "^3.5.3",
93
- "semantic-release": "^24.2.5",
94
- "ts-jest": "^29.4.0",
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": "^8.5.0",
97
- "typescript": "^5.8.3",
98
- "typescript-eslint": "^8.34.1"
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",