fhir-data-utils-ts 0.2.4 → 0.3.1

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.
Files changed (285) hide show
  1. package/.codex/skills/govern-fhir-data-utilities/SKILL.md +58 -0
  2. package/.codex/skills/govern-fhir-data-utilities/agents/openai.yaml +4 -0
  3. package/.codex/skills/govern-fhir-observation-components/SKILL.md +18 -0
  4. package/CHANGELOG.md +30 -0
  5. package/README.md +39 -0
  6. package/dist/builders/immunization-graph.d.ts +36 -0
  7. package/dist/builders/immunization-graph.js +115 -0
  8. package/dist/builders/immunization-reminders.d.ts +35 -0
  9. package/dist/builders/immunization-reminders.js +104 -0
  10. package/dist/builders/index.d.ts +2 -0
  11. package/dist/builders/index.js +2 -0
  12. package/dist/claim-helpers/claim-list-helpers.d.ts +21 -0
  13. package/dist/claim-helpers/claim-list-helpers.js +54 -0
  14. package/dist/claim-helpers/claims-helpers-allergy-intolerance.d.ts +18 -0
  15. package/dist/claim-helpers/claims-helpers-allergy-intolerance.js +65 -0
  16. package/dist/claim-helpers/claims-helpers-appointment-response.d.ts +8 -0
  17. package/dist/claim-helpers/claims-helpers-appointment-response.js +20 -0
  18. package/dist/claim-helpers/claims-helpers-appointment.d.ts +10 -0
  19. package/dist/claim-helpers/claims-helpers-appointment.js +26 -0
  20. package/dist/claim-helpers/claims-helpers-care-plan.d.ts +8 -0
  21. package/dist/claim-helpers/claims-helpers-care-plan.js +20 -0
  22. package/dist/claim-helpers/claims-helpers-clinical-impression.d.ts +10 -0
  23. package/dist/claim-helpers/claims-helpers-clinical-impression.js +26 -0
  24. package/dist/claim-helpers/claims-helpers-communication.d.ts +19 -0
  25. package/dist/claim-helpers/claims-helpers-communication.js +63 -0
  26. package/dist/claim-helpers/claims-helpers-composition.d.ts +12 -0
  27. package/dist/claim-helpers/claims-helpers-composition.js +32 -0
  28. package/dist/claim-helpers/claims-helpers-condition.d.ts +18 -0
  29. package/dist/claim-helpers/claims-helpers-condition.js +65 -0
  30. package/dist/claim-helpers/claims-helpers-coverage.d.ts +10 -0
  31. package/dist/claim-helpers/claims-helpers-coverage.js +26 -0
  32. package/dist/claim-helpers/claims-helpers-device-use-statement.d.ts +8 -0
  33. package/dist/claim-helpers/claims-helpers-device-use-statement.js +20 -0
  34. package/dist/claim-helpers/claims-helpers-device.d.ts +8 -0
  35. package/dist/claim-helpers/claims-helpers-device.js +20 -0
  36. package/dist/claim-helpers/claims-helpers-diagnostic-report.d.ts +16 -0
  37. package/dist/claim-helpers/claims-helpers-diagnostic-report.js +47 -0
  38. package/dist/claim-helpers/claims-helpers-document-reference.d.ts +8 -0
  39. package/dist/claim-helpers/claims-helpers-document-reference.js +20 -0
  40. package/dist/claim-helpers/claims-helpers-encounter.d.ts +10 -0
  41. package/dist/claim-helpers/claims-helpers-encounter.js +26 -0
  42. package/dist/claim-helpers/claims-helpers-flag.d.ts +8 -0
  43. package/dist/claim-helpers/claims-helpers-flag.js +20 -0
  44. package/dist/claim-helpers/claims-helpers-immunization.d.ts +8 -0
  45. package/dist/claim-helpers/claims-helpers-immunization.js +20 -0
  46. package/dist/claim-helpers/claims-helpers-location.d.ts +10 -0
  47. package/dist/claim-helpers/claims-helpers-location.js +26 -0
  48. package/dist/claim-helpers/claims-helpers-medication-statement.d.ts +96 -0
  49. package/dist/claim-helpers/claims-helpers-medication-statement.js +278 -0
  50. package/dist/claim-helpers/claims-helpers-observation.d.ts +8 -0
  51. package/dist/claim-helpers/claims-helpers-observation.js +20 -0
  52. package/dist/claim-helpers/claims-helpers-organization.d.ts +12 -0
  53. package/dist/claim-helpers/claims-helpers-organization.js +32 -0
  54. package/dist/claim-helpers/claims-helpers-procedure.d.ts +8 -0
  55. package/dist/claim-helpers/claims-helpers-procedure.js +20 -0
  56. package/dist/claim-helpers/claims-helpers-related-person.d.ts +22 -0
  57. package/dist/claim-helpers/claims-helpers-related-person.js +53 -0
  58. package/dist/claim-helpers/index.d.ts +23 -0
  59. package/dist/claim-helpers/index.js +23 -0
  60. package/dist/claims/allergy-intolerance-claims.d.ts +153 -0
  61. package/dist/claims/allergy-intolerance-claims.js +194 -0
  62. package/dist/claims/appointment-claims.d.ts +226 -0
  63. package/dist/claims/appointment-claims.js +218 -0
  64. package/dist/claims/appointment-response-claims.d.ts +63 -0
  65. package/dist/claims/appointment-response-claims.js +58 -0
  66. package/dist/claims/care-plan-claims.d.ts +37 -0
  67. package/dist/claims/care-plan-claims.js +59 -0
  68. package/dist/claims/claim-types.d.ts +9 -0
  69. package/dist/claims/claim-types.js +3 -0
  70. package/dist/claims/clinical-impression-claims.d.ts +17 -0
  71. package/dist/claims/clinical-impression-claims.js +30 -0
  72. package/dist/claims/communication-claims.d.ts +55 -0
  73. package/dist/claims/communication-claims.js +57 -0
  74. package/dist/claims/composition-claims.d.ts +27 -0
  75. package/dist/claims/composition-claims.js +27 -0
  76. package/dist/claims/condition-claims.d.ts +79 -0
  77. package/dist/claims/condition-claims.js +104 -0
  78. package/dist/claims/consent-claims.d.ts +195 -0
  79. package/dist/claims/consent-claims.js +74 -0
  80. package/dist/claims/coverage-claims.d.ts +16 -0
  81. package/dist/claims/coverage-claims.js +28 -0
  82. package/dist/claims/device-claims.d.ts +20 -0
  83. package/dist/claims/device-claims.js +36 -0
  84. package/dist/claims/device-use-statement-claims.d.ts +17 -0
  85. package/dist/claims/device-use-statement-claims.js +28 -0
  86. package/dist/claims/diagnostic-report-claims.d.ts +109 -0
  87. package/dist/claims/diagnostic-report-claims.js +120 -0
  88. package/dist/claims/document-reference-claims.d.ts +39 -0
  89. package/dist/claims/document-reference-claims.js +96 -0
  90. package/dist/claims/encounter-claims.d.ts +18 -0
  91. package/dist/claims/encounter-claims.js +32 -0
  92. package/dist/claims/flag-claims.d.ts +19 -0
  93. package/dist/claims/flag-claims.js +33 -0
  94. package/dist/claims/immunization-claims.d.ts +31 -0
  95. package/dist/claims/immunization-claims.js +54 -0
  96. package/dist/claims/immunization-recommendation-claims.d.ts +19 -0
  97. package/dist/claims/immunization-recommendation-claims.js +26 -0
  98. package/dist/claims/index.d.ts +29 -0
  99. package/dist/claims/index.js +29 -0
  100. package/dist/claims/invoice-claims.d.ts +277 -0
  101. package/dist/claims/invoice-claims.js +357 -0
  102. package/dist/claims/location-claims.d.ts +22 -0
  103. package/dist/claims/location-claims.js +34 -0
  104. package/dist/claims/medication-claims.d.ts +15 -0
  105. package/dist/claims/medication-claims.js +23 -0
  106. package/dist/claims/medication-statement-claims.d.ts +539 -0
  107. package/dist/claims/medication-statement-claims.js +469 -0
  108. package/dist/claims/organization-claims.d.ts +18 -0
  109. package/dist/claims/organization-claims.js +27 -0
  110. package/dist/claims/practitioner-role-claims.d.ts +18 -0
  111. package/dist/claims/practitioner-role-claims.js +33 -0
  112. package/dist/claims/procedure-claims.d.ts +24 -0
  113. package/dist/claims/procedure-claims.js +44 -0
  114. package/dist/claims/related-person-claims.d.ts +30 -0
  115. package/dist/claims/related-person-claims.js +44 -0
  116. package/dist/claims/research-subject-claims.d.ts +4 -0
  117. package/dist/claims/research-subject-claims.js +4 -0
  118. package/dist/claims/task-claims.d.ts +61 -0
  119. package/dist/claims/task-claims.js +64 -0
  120. package/dist/clinical-terminology.d.ts +73 -0
  121. package/dist/clinical-terminology.js +77 -0
  122. package/dist/constants/clinical-statuses.d.ts +102 -0
  123. package/dist/constants/clinical-statuses.js +93 -0
  124. package/dist/constants/fhir-code-systems.d.ts +15 -0
  125. package/dist/constants/fhir-code-systems.js +15 -0
  126. package/dist/constants/fhir-resource-types.d.ts +162 -0
  127. package/dist/constants/fhir-resource-types.js +70 -0
  128. package/dist/constants/fhir-versions.d.ts +10 -0
  129. package/dist/constants/fhir-versions.js +10 -0
  130. package/dist/constants/index.d.ts +4 -0
  131. package/dist/constants/index.js +4 -0
  132. package/dist/converters/convert-allergy-intolerance.d.ts +3 -0
  133. package/dist/converters/convert-allergy-intolerance.js +85 -0
  134. package/dist/converters/convert-appointment-response.d.ts +3 -0
  135. package/dist/converters/convert-appointment-response.js +32 -0
  136. package/dist/converters/convert-appointment.d.ts +3 -0
  137. package/dist/converters/convert-appointment.js +61 -0
  138. package/dist/converters/convert-care-plan.d.ts +3 -0
  139. package/dist/converters/convert-care-plan.js +93 -0
  140. package/dist/converters/convert-clinical-impression.d.ts +3 -0
  141. package/dist/converters/convert-clinical-impression.js +42 -0
  142. package/dist/converters/convert-composition.d.ts +3 -0
  143. package/dist/converters/convert-composition.js +70 -0
  144. package/dist/converters/convert-condition.d.ts +3 -0
  145. package/dist/converters/convert-condition.js +51 -0
  146. package/dist/converters/convert-consent.d.ts +9 -0
  147. package/dist/converters/convert-consent.js +174 -0
  148. package/dist/converters/convert-coverage.d.ts +3 -0
  149. package/dist/converters/convert-coverage.js +51 -0
  150. package/dist/converters/convert-device-use-statement.d.ts +3 -0
  151. package/dist/converters/convert-device-use-statement.js +36 -0
  152. package/dist/converters/convert-device.d.ts +3 -0
  153. package/dist/converters/convert-device.js +48 -0
  154. package/dist/converters/convert-diagnostic-report.d.ts +3 -0
  155. package/dist/converters/convert-diagnostic-report.js +63 -0
  156. package/dist/converters/convert-document-reference.d.ts +3 -0
  157. package/dist/converters/convert-document-reference.js +54 -0
  158. package/dist/converters/convert-encounter.d.ts +3 -0
  159. package/dist/converters/convert-encounter.js +68 -0
  160. package/dist/converters/convert-flag.d.ts +3 -0
  161. package/dist/converters/convert-flag.js +42 -0
  162. package/dist/converters/convert-immunization.d.ts +3 -0
  163. package/dist/converters/convert-immunization.js +80 -0
  164. package/dist/converters/convert-location.d.ts +3 -0
  165. package/dist/converters/convert-location.js +44 -0
  166. package/dist/converters/convert-medication-statement.d.ts +3 -0
  167. package/dist/converters/convert-medication-statement.js +130 -0
  168. package/dist/converters/convert-observation.d.ts +33 -0
  169. package/dist/converters/convert-observation.js +246 -0
  170. package/dist/converters/convert-organization.d.ts +3 -0
  171. package/dist/converters/convert-organization.js +39 -0
  172. package/dist/converters/convert-practitioner-role.d.ts +3 -0
  173. package/dist/converters/convert-practitioner-role.js +62 -0
  174. package/dist/converters/convert-procedure.d.ts +3 -0
  175. package/dist/converters/convert-procedure.js +64 -0
  176. package/dist/converters/convert-related-person.d.ts +3 -0
  177. package/dist/converters/convert-related-person.js +31 -0
  178. package/dist/converters/convert-shared.d.ts +33 -0
  179. package/dist/converters/convert-shared.js +181 -0
  180. package/dist/converters/index.d.ts +24 -0
  181. package/dist/converters/index.js +24 -0
  182. package/dist/fhir-bundle.d.ts +9 -0
  183. package/dist/fhir-bundle.js +43 -0
  184. package/dist/fhir-search-parameters.d.ts +18 -0
  185. package/dist/fhir-search-parameters.js +52 -0
  186. package/dist/fhir-tokens.d.ts +11 -0
  187. package/dist/fhir-tokens.js +26 -0
  188. package/dist/fhir-types.d.ts +77 -0
  189. package/dist/fhir-types.js +1 -0
  190. package/dist/fhir-values.d.ts +13 -0
  191. package/dist/fhir-values.js +53 -0
  192. package/dist/group-r5.d.ts +121 -0
  193. package/dist/group-r5.js +301 -0
  194. package/dist/imaging-types.d.ts +30 -0
  195. package/dist/imaging-types.js +1 -0
  196. package/dist/immunization-flat-claims.d.ts +2 -0
  197. package/dist/immunization-flat-claims.js +2 -0
  198. package/dist/immunization-reminder-plan.d.ts +2 -0
  199. package/dist/immunization-reminder-plan.js +2 -0
  200. package/dist/index.d.ts +19 -0
  201. package/dist/index.js +19 -0
  202. package/dist/observation-claims.d.ts +170 -0
  203. package/dist/observation-claims.js +184 -0
  204. package/dist/related-person.d.ts +16 -0
  205. package/dist/related-person.js +14 -0
  206. package/dist/research-study-r5.d.ts +163 -0
  207. package/dist/research-study-r5.js +490 -0
  208. package/dist/search-models/index.d.ts +7 -0
  209. package/dist/search-models/index.js +7 -0
  210. package/dist/search-models/params/AdverseEvent.params.model.d.ts +14 -0
  211. package/dist/search-models/params/AdverseEvent.params.model.js +16 -0
  212. package/dist/search-models/params/AllergyIntolerance.params.model.d.ts +24 -0
  213. package/dist/search-models/params/AllergyIntolerance.params.model.js +27 -0
  214. package/dist/search-models/params/Appointment.params.model.d.ts +12 -0
  215. package/dist/search-models/params/Appointment.params.model.js +14 -0
  216. package/dist/search-models/params/ClinicalImpression.params.model.d.ts +14 -0
  217. package/dist/search-models/params/ClinicalImpression.params.model.js +15 -0
  218. package/dist/search-models/params/Condition.params.model.d.ts +16 -0
  219. package/dist/search-models/params/Condition.params.model.js +17 -0
  220. package/dist/search-models/params/DetectedIssue.params.model.d.ts +9 -0
  221. package/dist/search-models/params/DetectedIssue.params.model.js +11 -0
  222. package/dist/search-models/params/DiagnosticReport.params.model.d.ts +13 -0
  223. package/dist/search-models/params/DiagnosticReport.params.model.js +14 -0
  224. package/dist/search-models/params/Encounter.params.model.d.ts +15 -0
  225. package/dist/search-models/params/Encounter.params.model.js +17 -0
  226. package/dist/search-models/params/Immunization.params.model.d.ts +14 -0
  227. package/dist/search-models/params/Immunization.params.model.js +16 -0
  228. package/dist/search-models/params/Medication.params.model.d.ts +35 -0
  229. package/dist/search-models/params/Medication.params.model.js +45 -0
  230. package/dist/search-models/params/Observation.params.model.d.ts +326 -0
  231. package/dist/search-models/params/Observation.params.model.js +244 -0
  232. package/dist/search-models/params/Procedure.params.model.d.ts +15 -0
  233. package/dist/search-models/params/Procedure.params.model.js +17 -0
  234. package/dist/search-models/params/Search.params.model.d.ts +75 -0
  235. package/dist/search-models/params/Search.params.model.js +69 -0
  236. package/dist/search-models/params/ServiceRequest.params.model.d.ts +14 -0
  237. package/dist/search-models/params/ServiceRequest.params.model.js +16 -0
  238. package/dist/search-models/params/Specimen.params.model.d.ts +10 -0
  239. package/dist/search-models/params/Specimen.params.model.js +12 -0
  240. package/dist/search-models/params/index.d.ts +15 -0
  241. package/dist/search-models/params/index.js +15 -0
  242. package/dist/search-models/templates/AdverseEvent.template.model.d.ts +16 -0
  243. package/dist/search-models/templates/AdverseEvent.template.model.js +2 -0
  244. package/dist/search-models/templates/AllergyIntolerance.template.model.d.ts +24 -0
  245. package/dist/search-models/templates/AllergyIntolerance.template.model.js +1 -0
  246. package/dist/search-models/templates/Appointment.template.model.d.ts +13 -0
  247. package/dist/search-models/templates/Appointment.template.model.js +1 -0
  248. package/dist/search-models/templates/ClinicalImpression.template.model.d.ts +16 -0
  249. package/dist/search-models/templates/ClinicalImpression.template.model.js +1 -0
  250. package/dist/search-models/templates/Condition.template.model.d.ts +18 -0
  251. package/dist/search-models/templates/Condition.template.model.js +1 -0
  252. package/dist/search-models/templates/DetectedIssue.template.model.d.ts +11 -0
  253. package/dist/search-models/templates/DetectedIssue.template.model.js +1 -0
  254. package/dist/search-models/templates/DiagnosticReport.template.model.d.ts +15 -0
  255. package/dist/search-models/templates/DiagnosticReport.template.model.js +1 -0
  256. package/dist/search-models/templates/Encounter.template.model.d.ts +17 -0
  257. package/dist/search-models/templates/Encounter.template.model.js +1 -0
  258. package/dist/search-models/templates/Immunization.template.model.d.ts +18 -0
  259. package/dist/search-models/templates/Immunization.template.model.js +2 -0
  260. package/dist/search-models/templates/Medication.template.model.d.ts +37 -0
  261. package/dist/search-models/templates/Medication.template.model.js +1 -0
  262. package/dist/search-models/templates/Observation.template.model.d.ts +18 -0
  263. package/dist/search-models/templates/Observation.template.model.js +1 -0
  264. package/dist/search-models/templates/Procedure.template.model.d.ts +17 -0
  265. package/dist/search-models/templates/Procedure.template.model.js +1 -0
  266. package/dist/search-models/templates/ServiceRequest.template.model.d.ts +16 -0
  267. package/dist/search-models/templates/ServiceRequest.template.model.js +1 -0
  268. package/dist/search-models/templates/Specimen.template.model.d.ts +12 -0
  269. package/dist/search-models/templates/Specimen.template.model.js +1 -0
  270. package/dist/search-models/templates/index.d.ts +14 -0
  271. package/dist/search-models/templates/index.js +14 -0
  272. package/dist/terminology-models/AtcModel.d.ts +15 -0
  273. package/dist/terminology-models/AtcModel.js +2 -0
  274. package/dist/terminology-models/CommonModels.d.ts +70 -0
  275. package/dist/terminology-models/CommonModels.js +55 -0
  276. package/dist/terminology-models/FhirModels.d.ts +60 -0
  277. package/dist/terminology-models/FhirModels.js +34 -0
  278. package/dist/terminology-models/LoincModels.d.ts +24 -0
  279. package/dist/terminology-models/LoincModels.js +2 -0
  280. package/dist/terminology-models/SnomedModels.d.ts +13 -0
  281. package/dist/terminology-models/SnomedModels.js +2 -0
  282. package/dist/terminology-models/index.d.ts +6 -0
  283. package/dist/terminology-models/index.js +6 -0
  284. package/docs/UHC_FHIR_UTILS_MIGRATION.md +51 -8
  285. package/package.json +83 -2
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: govern-fhir-data-utilities
3
+ description: Complete or audit migrations, claim catalogs, converters, builders, tests and releases in fhir-data-utils-ts. Use for shared FHIR types or utilities copied from frozen gdc-common-utils, former UHC utilities, SOS, Vet or UHC packages; raw flat-claim literals; duplicate root and family modules; Observation components; Immunization graphs; Group or ResearchStudy projections; package exports; coverage gates; or downstream promotion.
4
+ ---
5
+
6
+ # Govern FHIR Data Utilities
7
+
8
+ ## Keep ownership explicit
9
+
10
+ 1. Read `docs/UHC_FHIR_UTILS_MIGRATION.md` and inventory every relevant source
11
+ family before declaring a migration complete.
12
+ 2. Treat `gdc-*` repositories as read-only evidence unless the user explicitly
13
+ changes that scope. Never patch them as part of this migration.
14
+ 3. Keep neutral FHIR data semantics here. Keep HTTP, SMART, DIDComm, storage,
15
+ authorization and product policy in their owning services or sector packages.
16
+ 4. Define every flat key once in its owning named catalog. Import that symbol in
17
+ converters, builders, tests and examples; never repeat a claim-path literal.
18
+
19
+ ## Separate catalogs, adapters and builders
20
+
21
+ - Put claim names and specs under `src/claims/`.
22
+ - Put native FHIR R4/R5 projection at `src/converters/`; persistence remains
23
+ flat claims and native FHIR exists only at an explicit adapter boundary.
24
+ - Put multi-resource authoring under `src/builders/`. A root historical module
25
+ may remain only as a deprecated re-export shim so implementation is unique.
26
+ - Preserve correlations by creating one claims-first row per member, party or
27
+ component when parallel arrays would lose identity.
28
+ - Reconstruct native arrays such as `Observation.component[]` only during FHIR
29
+ projection. Do not invent resource-specific scalar aliases for indexing.
30
+ - Keep Group membership and ResearchStudy associated parties descriptive;
31
+ neither is a Consent, SMART scope or authorization grant.
32
+
33
+ ## Change with executable contracts
34
+
35
+ 1. Use Node 24 and run `npm ci` before trusting failures.
36
+ 2. Begin every new or modified test file with the repository flow-contract
37
+ comment.
38
+ 3. Write and run the smallest failing test first. Cover success, malformed
39
+ input, lossless round trip, catalog ownership and packed public exports.
40
+ 4. Add data-rich converter fixtures that exercise meaningful optional fields;
41
+ a single happy-path assertion is not adequate migration evidence.
42
+ 5. Run `npm run check`. Preserve the built-in coverage floors for converters,
43
+ builders and core FHIR utilities; raise them when practical, never lower them
44
+ to make a branch green.
45
+ 6. Run `npm pack --dry-run`, then install the produced tarball in an isolated
46
+ temporary consumer and resolve every documented subpath.
47
+
48
+ ## Release without partial promotion
49
+
50
+ 1. Update JSDoc, tests, README, migration inventory, changelog and this skill in
51
+ the same behavior branch.
52
+ 2. Use one patch release for one branch closure. Commit and push the branch,
53
+ create an explicit merge commit, push `main`, and verify matching remote refs
54
+ and a clean worktree.
55
+ 3. Publish this lowest shared package before changing consumers. Verify the
56
+ exact registry version exists before pinning it downstream.
57
+ 4. Never commit `file:`, Git, workspace or vendored tarball dependencies.
58
+ 5. Report local green, merged, published and deployed as separate states.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Govern FHIR Data Utilities"
3
+ short_description: "Keep FHIR catalogs, builders and releases complete"
4
+ default_prompt: "Use $govern-fhir-data-utilities to migrate or change shared FHIR data contracts safely."
@@ -36,6 +36,10 @@ description: Implement or audit neutral FHIR Observation claim catalogs, vital-s
36
36
  composite observations.
37
37
  - Reconstruct native `Observation.component[]` only at the explicit R4/R5
38
38
  adapter boundary by resolving the primary entry's governed member graph.
39
+ - Use `observationFhirR4ToFlatGraph` for native component imports and
40
+ `observationFlatGraphToFhirR4` for export. The scalar
41
+ `observationFhirR4ToFlat` adapter must fail with
42
+ `observation_component_graph_required` when `component[]` is present.
39
43
 
40
44
  ## Reuse governed names
41
45
 
@@ -62,6 +66,20 @@ description: Implement or audit neutral FHIR Observation claim catalogs, vital-s
62
66
  catalog and against child-owned containment markers.
63
67
  5. Run Node 24, `npm ci`, `npm run check` and `npm pack --dry-run`.
64
68
 
69
+ ## Audit migrations completely
70
+
71
+ - Inventory the old UHC package, `gdc-common-utils-ts`, `sos-data-utils-ts`,
72
+ `vet-data-utils-ts`, and the UHC/Vet/SOS SDKs before calling a migration
73
+ complete.
74
+ - Move only neutral FHIR data types, claim catalogs, conversion rules and pure
75
+ helpers here. Keep transport clients and sector authorization/policy in
76
+ their owning package.
77
+ - Record every migrated, retired or intentionally retained family in
78
+ `docs/UHC_FHIR_UTILS_MIGRATION.md`; an unmentioned file is an incomplete
79
+ audit.
80
+ - Expose each supported family through a stable package subpath and prove the
81
+ packed artifact, not only root source imports.
82
+
65
83
  ## Promote consumers
66
84
 
67
85
  Release bottom-up. Publish this package first, install its exact registry
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1 - 2026-09-21
4
+
5
+ - Separate canonical claim catalogs from graph builders and move Immunization
6
+ graph/reminder implementations under the stable `builders` subpaths, leaving
7
+ their historical root paths as deprecated compatibility re-exports.
8
+ - Add missing Medication and ImmunizationRecommendation catalogs, Group and
9
+ ResearchStudy named claim constants, legacy-read aliases and missing neutral
10
+ FHIR resource type constants; remove duplicated flat-claim literals from
11
+ builders and converters.
12
+ - Correct impossible calendar-date acceptance, empty list persistence and
13
+ nested `meta.claims` leakage through generic fallback flattening.
14
+ - Expand executable contracts to the complete converter/helper matrix, rich
15
+ optional resource fields, FHIR primitives/search/Bundle behavior,
16
+ Immunization graphs and Group/ResearchStudy row boundaries.
17
+ - Enforce coverage and packed-subpath gates as part of the release contract.
18
+
19
+ ## 0.3.0 - 2026-09-21
20
+
21
+ - Consolidate the complete product-neutral claim catalogs, claim helpers and
22
+ R4/R5 converters previously exposed from `gdc-common-utils-ts`, without
23
+ modifying that frozen source repository.
24
+ - Recover strict FHIR primitives, value/search/token utilities, Bundle readers,
25
+ resource search/template types, terminology model types, RelatedPerson and
26
+ telecom helpers, and DICOMDIR structural types from the retired UHC package.
27
+ - Move cross-sector terminology, Immunization graph/reminder, Group R5 and
28
+ ResearchStudy R5 contracts that existed only in SOS or Vet data packages.
29
+ - Require component Observations to use independently indexable graph entries;
30
+ deprecated JSON-array component claims remain read-only compatibility input.
31
+ - Add stable package subpaths for every migrated contract family.
32
+
3
33
  ## 0.2.4 - 2026-09-21
4
34
 
5
35
  - Restore the canonical composite-Observation resource graph: the primary
package/README.md CHANGED
@@ -29,6 +29,32 @@ through `<ResourceType>.contained-reference-list`; children do not carry
29
29
  as `<ResourceType>.language`, `.narrative-status` and `.xhtml`. Native FHIR is
30
30
  materialized only by an explicit R4/R5/R6 import or export adapter.
31
31
 
32
+ ## Public contract
33
+
34
+ The root export and stable subpaths provide:
35
+
36
+ - strict version-neutral FHIR datatypes, value/token helpers, Bundle traversal
37
+ and typed search parsing/building;
38
+ - complete flat-claim catalogs and claim helpers for the resource families
39
+ formerly scattered through `gdc-common-utils-ts`;
40
+ - explicit R4/R5 conversion adapters, including Consent and PractitionerRole;
41
+ - the recovered UHC resource search/template types, terminology model types,
42
+ RelatedPerson/telecom helpers and type-only DICOMDIR tree contract;
43
+ - cross-sector terminology, Immunization graphs/reminders, and FHIR R5 Group
44
+ and ResearchStudy contracts previously located only in SOS or Vet packages.
45
+
46
+ Claim catalogs and graph builders are deliberately different surfaces.
47
+ `fhir-data-utils-ts/claims` owns canonical storage names and their specs;
48
+ `fhir-data-utils-ts/builders` authors correlated multi-resource graphs using
49
+ those catalogs. The old `/immunization-flat-claims` and
50
+ `/immunization-reminder-plan` paths are deprecated compatibility re-exports;
51
+ new code imports `/builders` or `/builders/immunization`.
52
+
53
+ No consumer should copy claim paths or rebuild these structures with literals.
54
+ Use `fhir-data-utils-ts/claims`, `/converters`, `/fhir-bundle`,
55
+ `/fhir-search-parameters`, `/clinical-terminology`, `/group-r5` or
56
+ `/research-study-r5` as appropriate.
57
+
32
58
  ## Observation components
33
59
 
34
60
  Composite observations use a claims-first resource graph. The primary
@@ -44,6 +70,12 @@ aliases are read-only compatibility inputs. Current writers emit none of them.
44
70
  Components never use `is-contained`, `contained-parent-reference` or the
45
71
  generic contained-resource link.
46
72
 
73
+ This is why blood pressure does not have writable `bp-*` claims. Systolic and
74
+ diastolic are independently indexed reduced Observation rows linked by the
75
+ parent's `Observation.has-member`; the R4/R5 adapter alone reconstructs native
76
+ `component[]`. The same representation works for future assessment scales
77
+ without inventing a new flat-claim family for each scale.
78
+
47
79
  `buildVitalSignObservation` owns the graph, canonical displays and optional
48
80
  `Observation.user-selected` provenance flag. Consumers submit its `entries`
49
81
  without reconstructing component claims or relationships.
@@ -70,3 +102,10 @@ DataConv, Vet and UHC share one neutral review contract from
70
102
  The package exports builders, traversal/confirmation helpers and
71
103
  `CODING_REVIEW_EXAMPLES`. Tests and consumers reuse them instead of duplicating
72
104
  claim strings, terminology identifiers, codes or UUIDs.
105
+
106
+ ## Verification gate
107
+
108
+ `npm run check` runs strict type checking, all contract tests and built-in
109
+ coverage over converters, builders and core FHIR utilities. The package also
110
+ tests every stable export subpath. Release validation additionally inspects the
111
+ packed artifact and installs it in an isolated consumer before publication.
@@ -0,0 +1,36 @@
1
+ import { type FlatClaimResourceEntry } from '../flat-claim-resource-graph.js';
2
+ import { type ImmunizationReminderChannel } from './immunization-reminders.js';
3
+ export type ImmunizationCoding = Readonly<{
4
+ system: string;
5
+ code: string;
6
+ display?: string;
7
+ text?: string;
8
+ }>;
9
+ export type ImmunizationFlatInput = Readonly<{
10
+ entryId: string;
11
+ identifier?: string;
12
+ subjectReference: string;
13
+ administrationDate: string;
14
+ vaccineCode: ImmunizationCoding;
15
+ performerReference?: string;
16
+ targetDiseases?: readonly ImmunizationCoding[];
17
+ nextDoseDate?: string;
18
+ /** FHIR dateTime when the recommendation was created; required with nextDoseDate. */
19
+ recommendationDate?: string;
20
+ reminderChannels?: readonly ImmunizationReminderChannel[];
21
+ medication?: Readonly<{
22
+ entryId: string;
23
+ productName: string;
24
+ identifiers?: readonly Readonly<{
25
+ system: string;
26
+ value: string;
27
+ }>[];
28
+ manufacturer?: string;
29
+ lotNumber?: string;
30
+ expirationDate?: string;
31
+ barcode?: string;
32
+ }>;
33
+ attachments?: readonly FlatClaimResourceEntry[];
34
+ }>;
35
+ /** Builds the shared claims-first human/animal immunization resource graph. */
36
+ export declare function buildImmunizationFlatGraph(input: ImmunizationFlatInput): readonly FlatClaimResourceEntry[];
@@ -0,0 +1,115 @@
1
+ // Copyright 2026 ConnectHealth.info (Connecting Solution & Applications Ltd.) under the Apache License, Version 2.0.
2
+ import { buildFlatClaimResourceEntry, linkFlatClaimResourceEntries, } from '../flat-claim-resource-graph.js';
3
+ import { buildImmunizationReminderTasks, ImmunizationReminderChannels, } from './immunization-reminders.js';
4
+ import { ImmunizationClaim } from '../claims/immunization-claims.js';
5
+ import { ImmunizationRecommendationClaim, ImmunizationRecommendationCodes, } from '../claims/immunization-recommendation-claims.js';
6
+ import { MedicationClaim } from '../claims/medication-claims.js';
7
+ import { ResourceTypesFhirR4 } from '../constants/fhir-resource-types.js';
8
+ /** Builds the shared claims-first human/animal immunization resource graph. */
9
+ export function buildImmunizationFlatGraph(input) {
10
+ const vaccineCode = codingToken(input.vaccineCode);
11
+ const claims = {
12
+ [ImmunizationClaim.Status]: 'completed',
13
+ [ImmunizationClaim.Patient]: required(input.subjectReference, 'immunization_subject_required'),
14
+ [ImmunizationClaim.Date]: isoDate(input.administrationDate, 'immunization_date_invalid'),
15
+ [ImmunizationClaim.VaccineCode]: vaccineCode,
16
+ };
17
+ if (input.identifier)
18
+ claims[ImmunizationClaim.Identifier] = required(input.identifier, 'immunization_identifier_invalid');
19
+ if (input.vaccineCode.display?.trim())
20
+ claims[ImmunizationClaim.VaccineCodeDisplay] = input.vaccineCode.display.trim();
21
+ if (input.vaccineCode.text?.trim())
22
+ claims[ImmunizationClaim.VaccineCodeText] = input.vaccineCode.text.trim();
23
+ if (input.performerReference)
24
+ claims[ImmunizationClaim.Performer] = required(input.performerReference, 'immunization_performer_invalid');
25
+ if (input.targetDiseases?.length) {
26
+ claims[ImmunizationClaim.TargetDisease] = input.targetDiseases.map(codingToken).join(',');
27
+ claims[ImmunizationClaim.TargetDiseaseDisplay] = input.targetDiseases.map(value => value.display?.trim() ?? '').join(',');
28
+ claims[ImmunizationClaim.TargetDiseaseText] = input.targetDiseases.map(value => value.text?.trim() ?? '').join(',');
29
+ }
30
+ const immunization = buildFlatClaimResourceEntry({ entryId: input.entryId, resourceType: ResourceTypesFhirR4.Immunization, claims });
31
+ const children = [];
32
+ if (input.medication)
33
+ children.push(buildMedicationEntry(input.medication));
34
+ if (input.nextDoseDate) {
35
+ const recommendationId = `${input.entryId}-recommendation`;
36
+ const recommendation = buildFlatClaimResourceEntry({
37
+ entryId: recommendationId,
38
+ resourceType: ResourceTypesFhirR4.ImmunizationRecommendation,
39
+ claims: {
40
+ [ImmunizationRecommendationClaim.Patient]: input.subjectReference,
41
+ [ImmunizationRecommendationClaim.Date]: isoDate(required(input.recommendationDate, 'immunization_recommendation_date_required'), 'immunization_recommendation_date_invalid'),
42
+ [ImmunizationRecommendationClaim.VaccineCode]: vaccineCode,
43
+ [ImmunizationRecommendationClaim.ForecastStatus]: ImmunizationRecommendationCodes.ForecastDue,
44
+ [ImmunizationRecommendationClaim.DateCriterionCode]: ImmunizationRecommendationCodes.RecommendedDate,
45
+ [ImmunizationRecommendationClaim.DateCriterionValue]: isoDate(input.nextDoseDate, 'immunization_next_dose_date_invalid'),
46
+ [ImmunizationRecommendationClaim.SupportingImmunization]: `${ResourceTypesFhirR4.Immunization}/${input.entryId}`,
47
+ },
48
+ });
49
+ const tasks = buildImmunizationReminderTasks({
50
+ entryIdPrefix: recommendationId,
51
+ recommendationReference: recommendation.reference,
52
+ subjectReference: input.subjectReference,
53
+ coverageEndDate: input.nextDoseDate,
54
+ channelCandidates: input.reminderChannels ?? ImmunizationReminderChannels,
55
+ });
56
+ children.push(recommendation, ...tasks);
57
+ }
58
+ for (const attachment of input.attachments ?? []) {
59
+ if (attachment.resourceType !== ResourceTypesFhirR4.DocumentReference)
60
+ throw new TypeError('immunization_attachment_invalid');
61
+ children.push(attachment);
62
+ }
63
+ const graph = [immunization, ...children];
64
+ const linkedToImmunization = children.length
65
+ ? linkFlatClaimResourceEntries(graph, {
66
+ parentEntryId: input.entryId,
67
+ childEntryIds: children.filter(entry => entry.resourceType !== ResourceTypesFhirR4.Task).map(entry => entry.entryId),
68
+ })
69
+ : graph;
70
+ const recommendation = linkedToImmunization.find(entry => entry.resourceType === ResourceTypesFhirR4.ImmunizationRecommendation);
71
+ const tasks = linkedToImmunization.filter(entry => entry.resourceType === ResourceTypesFhirR4.Task);
72
+ return recommendation && tasks.length
73
+ ? linkFlatClaimResourceEntries(linkedToImmunization, {
74
+ parentEntryId: recommendation.entryId,
75
+ childEntryIds: tasks.map(entry => entry.entryId),
76
+ })
77
+ : linkedToImmunization;
78
+ }
79
+ function buildMedicationEntry(input) {
80
+ const claims = {
81
+ [MedicationClaim.Code]: required(input.productName, 'medication_product_required'),
82
+ [MedicationClaim.CodeText]: required(input.productName, 'medication_product_required'),
83
+ };
84
+ if (input.identifiers?.length)
85
+ claims[MedicationClaim.Identifier] = input.identifiers
86
+ .map(({ system, value }) => `${required(system, 'medication_identifier_invalid')}|${required(value, 'medication_identifier_invalid')}`)
87
+ .join(',');
88
+ if (input.manufacturer?.trim())
89
+ claims[MedicationClaim.Manufacturer] = input.manufacturer.trim();
90
+ if (input.lotNumber?.trim())
91
+ claims[MedicationClaim.LotNumber] = input.lotNumber.trim();
92
+ if (input.expirationDate)
93
+ claims[MedicationClaim.ExpirationDate] = isoDate(input.expirationDate, 'medication_expiration_date_invalid');
94
+ if (input.barcode?.trim())
95
+ claims[MedicationClaim.SerialNumber] = input.barcode.trim();
96
+ return buildFlatClaimResourceEntry({ entryId: input.entryId, resourceType: ResourceTypesFhirR4.Medication, claims });
97
+ }
98
+ function codingToken(value) {
99
+ return `${required(value.system, 'immunization_coding_system_required')}|${required(value.code, 'immunization_coding_code_required')}`;
100
+ }
101
+ function isoDate(value, error) {
102
+ const normalized = required(value, error);
103
+ const match = /^(\d{4})-(\d{2})-(\d{2})(?:T.*)?$/.exec(normalized);
104
+ if (!match || Number.isNaN(Date.parse(normalized)))
105
+ throw new TypeError(error);
106
+ const calendarDate = new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])));
107
+ if (calendarDate.toISOString().slice(0, 10) !== `${match[1]}-${match[2]}-${match[3]}`)
108
+ throw new TypeError(error);
109
+ return normalized;
110
+ }
111
+ function required(value, error) {
112
+ if (typeof value !== 'string' || !value.trim())
113
+ throw new TypeError(error);
114
+ return value.trim();
115
+ }
@@ -0,0 +1,35 @@
1
+ import { type FlatClaimResourceEntry } from '../flat-claim-resource-graph.js';
2
+ export declare const ImmunizationReminderTaskValues: Readonly<{
3
+ readonly Status: "requested";
4
+ readonly Intent: "order";
5
+ readonly Code: "immunization-reminder";
6
+ readonly TriggerType: "scheduled";
7
+ }>;
8
+ export declare const ImmunizationReminderChannels: readonly ["push", "email", "sms", "whatsapp", "telephone"];
9
+ export type ImmunizationReminderChannel = (typeof ImmunizationReminderChannels)[number];
10
+ export type ImmunizationReminderPlanInput = Readonly<{
11
+ entryIdPrefix: string;
12
+ recommendationReference: string;
13
+ subjectReference: string;
14
+ coverageEndDate: string;
15
+ /** Ordered delivery candidates; dispatch must filter them by current preferences and Consent. */
16
+ channelCandidates: readonly ImmunizationReminderChannel[];
17
+ }>;
18
+ export type ImmunizationReminderDispatchState = Readonly<{
19
+ channelCandidates: readonly ImmunizationReminderChannel[];
20
+ attemptedChannels: readonly ImmunizationReminderChannel[];
21
+ enabledPreferences: readonly ImmunizationReminderChannel[];
22
+ consentedChannels: readonly ImmunizationReminderChannel[];
23
+ acknowledged: boolean;
24
+ }>;
25
+ /**
26
+ * Builds the three notification Tasks attached to an ImmunizationRecommendation.
27
+ * Task creation is automatic; actual delivery is a separate runtime decision
28
+ * that rechecks channel preference, Consent and prior acknowledgement.
29
+ */
30
+ export declare function buildImmunizationReminderTasks(input: ImmunizationReminderPlanInput): readonly FlatClaimResourceEntry[];
31
+ /**
32
+ * Selects one next delivery channel without bypassing the subject's current
33
+ * preferences or Consent. Acknowledgement ends escalation immediately.
34
+ */
35
+ export declare function selectNextImmunizationReminderChannel(state: ImmunizationReminderDispatchState): ImmunizationReminderChannel | undefined;
@@ -0,0 +1,104 @@
1
+ // Copyright 2026 ConnectHealth.info (Connecting Solution & Applications Ltd.) under the Apache License, Version 2.0.
2
+ import { buildFlatClaimResourceEntry } from '../flat-claim-resource-graph.js';
3
+ import { TaskClaim } from '../claims/task-claims.js';
4
+ import { ResourceTypesFhirR4 } from '../constants/fhir-resource-types.js';
5
+ export const ImmunizationReminderTaskValues = Object.freeze({
6
+ Status: 'requested',
7
+ Intent: 'order',
8
+ Code: 'immunization-reminder',
9
+ TriggerType: 'scheduled',
10
+ });
11
+ export const ImmunizationReminderChannels = Object.freeze([
12
+ 'push',
13
+ 'email',
14
+ 'sms',
15
+ 'whatsapp',
16
+ 'telephone',
17
+ ]);
18
+ const OFFSETS = Object.freeze([
19
+ Object.freeze({ suffix: '1m', subtract: subtractOneCalendarMonth }),
20
+ Object.freeze({ suffix: '1w', subtract: (date) => subtractUtcDays(date, 7) }),
21
+ Object.freeze({ suffix: '1d', subtract: (date) => subtractUtcDays(date, 1) }),
22
+ ]);
23
+ /**
24
+ * Builds the three notification Tasks attached to an ImmunizationRecommendation.
25
+ * Task creation is automatic; actual delivery is a separate runtime decision
26
+ * that rechecks channel preference, Consent and prior acknowledgement.
27
+ */
28
+ export function buildImmunizationReminderTasks(input) {
29
+ const prefix = required(input.entryIdPrefix, 'immunization_reminder_entry_id_required');
30
+ const recommendation = required(input.recommendationReference, 'immunization_recommendation_reference_required');
31
+ const subject = required(input.subjectReference, 'immunization_reminder_subject_required');
32
+ const coverageEnd = parseIsoDate(input.coverageEndDate);
33
+ const channels = [...new Set(input.channelCandidates)].filter((channel) => ImmunizationReminderChannels.includes(channel));
34
+ if (channels.length === 0)
35
+ throw new TypeError('immunization_reminder_channels_required');
36
+ return Object.freeze(OFFSETS.map(({ suffix, subtract }) => {
37
+ const entryId = `${prefix}-reminder-${suffix}`;
38
+ return buildFlatClaimResourceEntry({
39
+ entryId,
40
+ resourceType: ResourceTypesFhirR4.Task,
41
+ claims: {
42
+ [TaskClaim.Identifier]: `urn:uuid:${entryId}`,
43
+ [TaskClaim.GroupIdentifier]: recommendation,
44
+ [TaskClaim.Status]: ImmunizationReminderTaskValues.Status,
45
+ [TaskClaim.Intent]: ImmunizationReminderTaskValues.Intent,
46
+ [TaskClaim.Code]: ImmunizationReminderTaskValues.Code,
47
+ [TaskClaim.For]: subject,
48
+ [TaskClaim.Focus]: recommendation,
49
+ [TaskClaim.BasedOn]: recommendation,
50
+ [TaskClaim.ScheduledAt]: formatIsoDate(subtract(coverageEnd)),
51
+ [TaskClaim.TriggerType]: ImmunizationReminderTaskValues.TriggerType,
52
+ [TaskClaim.Channel]: channels.join(','),
53
+ [TaskClaim.Attempt]: '0',
54
+ [TaskClaim.MaxAttempts]: String(channels.length),
55
+ [TaskClaim.Confirmed]: 'false',
56
+ },
57
+ });
58
+ }));
59
+ }
60
+ /**
61
+ * Selects one next delivery channel without bypassing the subject's current
62
+ * preferences or Consent. Acknowledgement ends escalation immediately.
63
+ */
64
+ export function selectNextImmunizationReminderChannel(state) {
65
+ if (state.acknowledged)
66
+ return undefined;
67
+ const attempted = new Set(state.attemptedChannels);
68
+ const preferred = new Set(state.enabledPreferences);
69
+ const consented = new Set(state.consentedChannels);
70
+ return state.channelCandidates.find((channel) => ImmunizationReminderChannels.includes(channel)
71
+ && !attempted.has(channel)
72
+ && preferred.has(channel)
73
+ && consented.has(channel));
74
+ }
75
+ function parseIsoDate(value) {
76
+ const normalized = required(value, 'immunization_coverage_end_date_invalid');
77
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(normalized);
78
+ if (!match)
79
+ throw new TypeError('immunization_coverage_end_date_invalid');
80
+ const date = new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])));
81
+ if (formatIsoDate(date) !== normalized)
82
+ throw new TypeError('immunization_coverage_end_date_invalid');
83
+ return date;
84
+ }
85
+ function subtractOneCalendarMonth(date) {
86
+ const year = date.getUTCFullYear();
87
+ const month = date.getUTCMonth();
88
+ const targetMonth = month === 0 ? 11 : month - 1;
89
+ const targetYear = month === 0 ? year - 1 : year;
90
+ const lastDay = new Date(Date.UTC(targetYear, targetMonth + 1, 0)).getUTCDate();
91
+ return new Date(Date.UTC(targetYear, targetMonth, Math.min(date.getUTCDate(), lastDay)));
92
+ }
93
+ function subtractUtcDays(date, days) {
94
+ return new Date(date.getTime() - days * 86_400_000);
95
+ }
96
+ function formatIsoDate(date) {
97
+ return date.toISOString().slice(0, 10);
98
+ }
99
+ function required(value, error) {
100
+ const normalized = String(value ?? '').trim();
101
+ if (!normalized)
102
+ throw new TypeError(error);
103
+ return normalized;
104
+ }
@@ -0,0 +1,2 @@
1
+ export * from './immunization-graph.js';
2
+ export * from './immunization-reminders.js';
@@ -0,0 +1,2 @@
1
+ export * from './immunization-graph.js';
2
+ export * from './immunization-reminders.js';
@@ -0,0 +1,21 @@
1
+ export type GenericInteroperableClaims = Record<string, unknown>;
2
+ export declare function splitClaimCsv(value: unknown): string[];
3
+ export declare function normalizeClaimTokens(values: readonly string[]): string[];
4
+ export declare function normalizeClaimInput(values: string | readonly string[]): string[];
5
+ export declare function normalizeClaimScalar(value: unknown): string;
6
+ /**
7
+ * Returns the tokenized values for a claims field stored as CSV.
8
+ */
9
+ export declare function getClaimValues(claims: GenericInteroperableClaims, claimKey: string): string[];
10
+ /**
11
+ * Replaces a claims CSV field with the provided values.
12
+ */
13
+ export declare function setClaimValues(claims: GenericInteroperableClaims, claimKey: string, values: string | readonly string[]): GenericInteroperableClaims;
14
+ /**
15
+ * Adds one or many values into a claims CSV field while preserving uniqueness.
16
+ */
17
+ export declare function addClaimValues(claims: GenericInteroperableClaims, claimKey: string, values: string | readonly string[]): GenericInteroperableClaims;
18
+ /**
19
+ * Removes one or many values from a claims CSV field while preserving uniqueness.
20
+ */
21
+ export declare function removeClaimValues(claims: GenericInteroperableClaims, claimKey: string, values: string | readonly string[]): GenericInteroperableClaims;
@@ -0,0 +1,54 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ export function splitClaimCsv(value) {
3
+ return String(value || '')
4
+ .split(',')
5
+ .map((item) => item.trim())
6
+ .filter(Boolean);
7
+ }
8
+ export function normalizeClaimTokens(values) {
9
+ return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))];
10
+ }
11
+ export function normalizeClaimInput(values) {
12
+ return Array.isArray(values)
13
+ ? normalizeClaimTokens(values)
14
+ : normalizeClaimTokens(splitClaimCsv(values));
15
+ }
16
+ export function normalizeClaimScalar(value) {
17
+ return String(value || '').trim();
18
+ }
19
+ /**
20
+ * Returns the tokenized values for a claims field stored as CSV.
21
+ */
22
+ export function getClaimValues(claims, claimKey) {
23
+ return normalizeClaimTokens(splitClaimCsv(claims[claimKey]));
24
+ }
25
+ /**
26
+ * Replaces a claims CSV field with the provided values.
27
+ */
28
+ export function setClaimValues(claims, claimKey, values) {
29
+ const nextValues = normalizeClaimInput(values);
30
+ if (nextValues.length === 0) {
31
+ const { [claimKey]: _removed, ...remaining } = claims;
32
+ return remaining;
33
+ }
34
+ return {
35
+ ...claims,
36
+ [claimKey]: nextValues.join(','),
37
+ };
38
+ }
39
+ /**
40
+ * Adds one or many values into a claims CSV field while preserving uniqueness.
41
+ */
42
+ export function addClaimValues(claims, claimKey, values) {
43
+ const current = getClaimValues(claims, claimKey);
44
+ const additions = normalizeClaimInput(values);
45
+ return setClaimValues(claims, claimKey, [...current, ...additions]);
46
+ }
47
+ /**
48
+ * Removes one or many values from a claims CSV field while preserving uniqueness.
49
+ */
50
+ export function removeClaimValues(claims, claimKey, values) {
51
+ const removals = new Set(normalizeClaimInput(values));
52
+ const nextValues = getClaimValues(claims, claimKey).filter((value) => !removals.has(value));
53
+ return setClaimValues(claims, claimKey, nextValues);
54
+ }
@@ -0,0 +1,18 @@
1
+ import { type GenericInteroperableClaims } from './claim-list-helpers.js';
2
+ export type AllergyIntoleranceInteroperableClaims = GenericInteroperableClaims;
3
+ export declare function getAllergyIntoleranceClaimList(claims: AllergyIntoleranceInteroperableClaims, claimKey: string): string[];
4
+ export declare function setAllergyIntoleranceClaimList(claims: AllergyIntoleranceInteroperableClaims, claimKey: string, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
5
+ export declare function addAllergyIntoleranceClaimList(claims: AllergyIntoleranceInteroperableClaims, claimKey: string, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
6
+ export declare function removeAllergyIntoleranceClaimList(claims: AllergyIntoleranceInteroperableClaims, claimKey: string, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
7
+ export declare function getAllergyIntoleranceContainedResourceReferenceList(claims: AllergyIntoleranceInteroperableClaims): string[];
8
+ export declare function setAllergyIntoleranceContainedResourceReferenceList(claims: AllergyIntoleranceInteroperableClaims, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
9
+ export declare function addAllergyIntoleranceContainedResourceReferenceList(claims: AllergyIntoleranceInteroperableClaims, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
10
+ export declare function removeAllergyIntoleranceContainedResourceReferenceList(claims: AllergyIntoleranceInteroperableClaims, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
11
+ /** @deprecated Use `getAllergyIntoleranceContainedResourceReferenceList`. */
12
+ export declare function getAllergyIntoleranceContainedDocumentIdentifierList(claims: AllergyIntoleranceInteroperableClaims): string[];
13
+ /** @deprecated Use `setAllergyIntoleranceContainedResourceReferenceList`. */
14
+ export declare function setAllergyIntoleranceContainedDocumentIdentifierList(claims: AllergyIntoleranceInteroperableClaims, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
15
+ /** @deprecated Use `addAllergyIntoleranceContainedResourceReferenceList`. */
16
+ export declare function addAllergyIntoleranceContainedDocumentIdentifierList(claims: AllergyIntoleranceInteroperableClaims, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
17
+ /** @deprecated Use `removeAllergyIntoleranceContainedResourceReferenceList`. */
18
+ export declare function removeAllergyIntoleranceContainedDocumentIdentifierList(claims: AllergyIntoleranceInteroperableClaims, values: string | readonly string[]): AllergyIntoleranceInteroperableClaims;
@@ -0,0 +1,65 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ import { AllergyIntoleranceClaim } from '../claims/allergy-intolerance-claims.js';
3
+ import { addClaimValues, getClaimValues, removeClaimValues, setClaimValues, } from './claim-list-helpers.js';
4
+ export function getAllergyIntoleranceClaimList(claims, claimKey) {
5
+ return getClaimValues(claims, claimKey);
6
+ }
7
+ export function setAllergyIntoleranceClaimList(claims, claimKey, values) {
8
+ return setClaimValues(claims, claimKey, values);
9
+ }
10
+ export function addAllergyIntoleranceClaimList(claims, claimKey, values) {
11
+ return addClaimValues(claims, claimKey, values);
12
+ }
13
+ export function removeAllergyIntoleranceClaimList(claims, claimKey, values) {
14
+ return removeClaimValues(claims, claimKey, values);
15
+ }
16
+ export function getAllergyIntoleranceContainedResourceReferenceList(claims) {
17
+ return uniqueCsvLists([
18
+ getAllergyIntoleranceClaimList(claims, AllergyIntoleranceClaim.ContainedReferenceList),
19
+ getAllergyIntoleranceClaimList(claims, AllergyIntoleranceClaim.ContainedDocuments),
20
+ getAllergyIntoleranceClaimList(claims, AllergyIntoleranceClaim.AttachmentContentIds),
21
+ ]);
22
+ }
23
+ export function setAllergyIntoleranceContainedResourceReferenceList(claims, values) {
24
+ return setContainedResources(claims, values);
25
+ }
26
+ export function addAllergyIntoleranceContainedResourceReferenceList(claims, values) {
27
+ return setContainedResources(claims, uniqueCsvLists([
28
+ getAllergyIntoleranceContainedResourceReferenceList(claims),
29
+ Array.isArray(values) ? [...values] : getAllergyIntoleranceClaimList({ [AllergyIntoleranceClaim.ContainedReferenceList]: values }, AllergyIntoleranceClaim.ContainedReferenceList),
30
+ ]));
31
+ }
32
+ export function removeAllergyIntoleranceContainedResourceReferenceList(claims, values) {
33
+ const toRemove = new Set((Array.isArray(values) ? values : getAllergyIntoleranceClaimList({ [AllergyIntoleranceClaim.ContainedReferenceList]: values }, AllergyIntoleranceClaim.ContainedReferenceList))
34
+ .map((item) => String(item || '').trim())
35
+ .filter(Boolean));
36
+ return setContainedResources(claims, getAllergyIntoleranceContainedResourceReferenceList(claims).filter((item) => !toRemove.has(item)));
37
+ }
38
+ /** @deprecated Use `getAllergyIntoleranceContainedResourceReferenceList`. */
39
+ export function getAllergyIntoleranceContainedDocumentIdentifierList(claims) {
40
+ return getAllergyIntoleranceContainedResourceReferenceList(claims);
41
+ }
42
+ /** @deprecated Use `setAllergyIntoleranceContainedResourceReferenceList`. */
43
+ export function setAllergyIntoleranceContainedDocumentIdentifierList(claims, values) {
44
+ return setAllergyIntoleranceContainedResourceReferenceList(claims, values);
45
+ }
46
+ /** @deprecated Use `addAllergyIntoleranceContainedResourceReferenceList`. */
47
+ export function addAllergyIntoleranceContainedDocumentIdentifierList(claims, values) {
48
+ return addAllergyIntoleranceContainedResourceReferenceList(claims, values);
49
+ }
50
+ /** @deprecated Use `removeAllergyIntoleranceContainedResourceReferenceList`. */
51
+ export function removeAllergyIntoleranceContainedDocumentIdentifierList(claims, values) {
52
+ return removeAllergyIntoleranceContainedResourceReferenceList(claims, values);
53
+ }
54
+ function setContainedResources(claims, values) {
55
+ const next = setAllergyIntoleranceClaimList(claims, AllergyIntoleranceClaim.ContainedReferenceList, values);
56
+ const cleaned = {
57
+ ...next,
58
+ };
59
+ delete cleaned[AllergyIntoleranceClaim.ContainedDocuments];
60
+ delete cleaned[AllergyIntoleranceClaim.AttachmentContentIds];
61
+ return cleaned;
62
+ }
63
+ function uniqueCsvLists(lists) {
64
+ return [...new Set(lists.flatMap((list) => list.map((item) => String(item || '').trim()).filter(Boolean)))];
65
+ }