@olaboot/esm-form-engine-lib 4.1.0

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 (628) hide show
  1. package/LICENSE.txt +401 -0
  2. package/README.md +202 -0
  3. package/dist/adapters/control-adapter.d.ts +3 -0
  4. package/dist/adapters/control-adapter.d.ts.map +1 -0
  5. package/dist/adapters/control-adapter.js +17 -0
  6. package/dist/adapters/encounter-datetime-adapter.d.ts +3 -0
  7. package/dist/adapters/encounter-datetime-adapter.d.ts.map +1 -0
  8. package/dist/adapters/encounter-datetime-adapter.js +26 -0
  9. package/dist/adapters/encounter-diagnosis-adapter.d.ts +10 -0
  10. package/dist/adapters/encounter-diagnosis-adapter.d.ts.map +1 -0
  11. package/dist/adapters/encounter-diagnosis-adapter.js +89 -0
  12. package/dist/adapters/encounter-diagnosis-adapter.test.js +217 -0
  13. package/dist/adapters/encounter-location-adapter.d.ts +3 -0
  14. package/dist/adapters/encounter-location-adapter.d.ts.map +1 -0
  15. package/dist/adapters/encounter-location-adapter.js +25 -0
  16. package/dist/adapters/encounter-provider-adapter.d.ts +3 -0
  17. package/dist/adapters/encounter-provider-adapter.d.ts.map +1 -0
  18. package/dist/adapters/encounter-provider-adapter.js +34 -0
  19. package/dist/adapters/encounter-role-adapter.d.ts +3 -0
  20. package/dist/adapters/encounter-role-adapter.d.ts.map +1 -0
  21. package/dist/adapters/encounter-role-adapter.js +40 -0
  22. package/dist/adapters/inline-date-adapter.d.ts +3 -0
  23. package/dist/adapters/inline-date-adapter.d.ts.map +1 -0
  24. package/dist/adapters/inline-date-adapter.js +56 -0
  25. package/dist/adapters/obs-adapter.d.ts +29 -0
  26. package/dist/adapters/obs-adapter.d.ts.map +1 -0
  27. package/dist/adapters/obs-adapter.js +284 -0
  28. package/dist/adapters/obs-adapter.test.js +1443 -0
  29. package/dist/adapters/obs-comment-adapter.d.ts +4 -0
  30. package/dist/adapters/obs-comment-adapter.d.ts.map +1 -0
  31. package/dist/adapters/obs-comment-adapter.js +52 -0
  32. package/dist/adapters/orders-adapter.d.ts +4 -0
  33. package/dist/adapters/orders-adapter.d.ts.map +1 -0
  34. package/dist/adapters/orders-adapter.js +64 -0
  35. package/dist/adapters/patient-identifier-adapter.d.ts +3 -0
  36. package/dist/adapters/patient-identifier-adapter.d.ts.map +1 -0
  37. package/dist/adapters/patient-identifier-adapter.js +40 -0
  38. package/dist/adapters/person-attribute-adapter.d.ts +3 -0
  39. package/dist/adapters/person-attribute-adapter.d.ts.map +1 -0
  40. package/dist/adapters/person-attribute-adapter.js +39 -0
  41. package/dist/adapters/person-attribute-adapter.test.js +146 -0
  42. package/dist/adapters/program-state-adapter.d.ts +3 -0
  43. package/dist/adapters/program-state-adapter.d.ts.map +1 -0
  44. package/dist/adapters/program-state-adapter.js +41 -0
  45. package/dist/adapters/program-state-adapter.test.js +411 -0
  46. package/dist/api/index.d.ts +27 -0
  47. package/dist/api/index.d.ts.map +1 -0
  48. package/dist/api/index.js +170 -0
  49. package/dist/components/error/error-modal.component.d.ts +7 -0
  50. package/dist/components/error/error-modal.component.d.ts.map +1 -0
  51. package/dist/components/error/error-modal.component.js +31 -0
  52. package/dist/components/error/error.scss +4 -0
  53. package/dist/components/extension/extension-parcel.component.d.ts +5 -0
  54. package/dist/components/extension/extension-parcel.component.d.ts.map +1 -0
  55. package/dist/components/extension/extension-parcel.component.js +35 -0
  56. package/dist/components/field-label/field-label.component.d.ts +12 -0
  57. package/dist/components/field-label/field-label.component.d.ts.map +1 -0
  58. package/dist/components/field-label/field-label.component.js +33 -0
  59. package/dist/components/field-label/field-label.scss +15 -0
  60. package/dist/components/group/obs-group.component.d.ts +5 -0
  61. package/dist/components/group/obs-group.component.d.ts.map +1 -0
  62. package/dist/components/group/obs-group.component.js +48 -0
  63. package/dist/components/group/obs-group.scss +16 -0
  64. package/dist/components/inputs/content-switcher/content-switcher.component.d.ts +5 -0
  65. package/dist/components/inputs/content-switcher/content-switcher.component.d.ts.map +1 -0
  66. package/dist/components/inputs/content-switcher/content-switcher.component.js +70 -0
  67. package/dist/components/inputs/content-switcher/content-switcher.scss +55 -0
  68. package/dist/components/inputs/date/date.component.d.ts +5 -0
  69. package/dist/components/inputs/date/date.component.d.ts.map +1 -0
  70. package/dist/components/inputs/date/date.component.js +125 -0
  71. package/dist/components/inputs/date/date.scss +37 -0
  72. package/dist/components/inputs/date/date.test.js +85 -0
  73. package/dist/components/inputs/file/file-thumbnail.component.d.ts +10 -0
  74. package/dist/components/inputs/file/file-thumbnail.component.d.ts.map +1 -0
  75. package/dist/components/inputs/file/file-thumbnail.component.js +51 -0
  76. package/dist/components/inputs/file/file-thumbnail.scss +42 -0
  77. package/dist/components/inputs/file/file.component.d.ts +5 -0
  78. package/dist/components/inputs/file/file.component.d.ts.map +1 -0
  79. package/dist/components/inputs/file/file.component.js +90 -0
  80. package/dist/components/inputs/file/file.scss +21 -0
  81. package/dist/components/inputs/fixed-value/fixed-value.component.d.ts +5 -0
  82. package/dist/components/inputs/fixed-value/fixed-value.component.d.ts.map +1 -0
  83. package/dist/components/inputs/fixed-value/fixed-value.component.js +14 -0
  84. package/dist/components/inputs/markdown/markdown-wrapper.component.d.ts +6 -0
  85. package/dist/components/inputs/markdown/markdown-wrapper.component.d.ts.map +1 -0
  86. package/dist/components/inputs/markdown/markdown-wrapper.component.js +20 -0
  87. package/dist/components/inputs/markdown/markdown.component.d.ts +5 -0
  88. package/dist/components/inputs/markdown/markdown.component.d.ts.map +1 -0
  89. package/dist/components/inputs/markdown/markdown.component.js +26 -0
  90. package/dist/components/inputs/multi-select/multi-select.component.d.ts +5 -0
  91. package/dist/components/inputs/multi-select/multi-select.component.d.ts.map +1 -0
  92. package/dist/components/inputs/multi-select/multi-select.component.js +134 -0
  93. package/dist/components/inputs/multi-select/multi-select.scss +25 -0
  94. package/dist/components/inputs/multi-select/multi-select.test.js +106 -0
  95. package/dist/components/inputs/number/number.component.d.ts +5 -0
  96. package/dist/components/inputs/number/number.component.d.ts.map +1 -0
  97. package/dist/components/inputs/number/number.component.js +77 -0
  98. package/dist/components/inputs/number/number.scss +15 -0
  99. package/dist/components/inputs/number/number.test.js +98 -0
  100. package/dist/components/inputs/radio/radio.component.d.ts +5 -0
  101. package/dist/components/inputs/radio/radio.component.d.ts.map +1 -0
  102. package/dist/components/inputs/radio/radio.component.js +69 -0
  103. package/dist/components/inputs/radio/radio.scss +36 -0
  104. package/dist/components/inputs/radio/radio.test.js +190 -0
  105. package/dist/components/inputs/select/dropdown.component.d.ts +5 -0
  106. package/dist/components/inputs/select/dropdown.component.d.ts.map +1 -0
  107. package/dist/components/inputs/select/dropdown.component.js +82 -0
  108. package/dist/components/inputs/select/dropdown.scss +11 -0
  109. package/dist/components/inputs/select/dropdown.test.js +157 -0
  110. package/dist/components/inputs/text/text.component.d.ts +5 -0
  111. package/dist/components/inputs/text/text.component.d.ts.map +1 -0
  112. package/dist/components/inputs/text/text.component.js +62 -0
  113. package/dist/components/inputs/text/text.scss +15 -0
  114. package/dist/components/inputs/text/text.test.js +184 -0
  115. package/dist/components/inputs/text-area/text-area.component.d.ts +5 -0
  116. package/dist/components/inputs/text-area/text-area.component.d.ts.map +1 -0
  117. package/dist/components/inputs/text-area/text-area.component.js +60 -0
  118. package/dist/components/inputs/text-area/text-area.scss +11 -0
  119. package/dist/components/inputs/toggle/toggle.component.d.ts +5 -0
  120. package/dist/components/inputs/toggle/toggle.component.d.ts.map +1 -0
  121. package/dist/components/inputs/toggle/toggle.component.js +57 -0
  122. package/dist/components/inputs/toggle/toggle.scss +12 -0
  123. package/dist/components/inputs/ui-select-extended/ui-select-extended.component.d.ts +5 -0
  124. package/dist/components/inputs/ui-select-extended/ui-select-extended.component.d.ts.map +1 -0
  125. package/dist/components/inputs/ui-select-extended/ui-select-extended.component.js +203 -0
  126. package/dist/components/inputs/ui-select-extended/ui-select-extended.scss +19 -0
  127. package/dist/components/inputs/ui-select-extended/ui-select-extended.test.js +250 -0
  128. package/dist/components/inputs/unspecified/unspecified.component.d.ts +11 -0
  129. package/dist/components/inputs/unspecified/unspecified.component.d.ts.map +1 -0
  130. package/dist/components/inputs/unspecified/unspecified.component.js +65 -0
  131. package/dist/components/inputs/unspecified/unspecified.scss +7 -0
  132. package/dist/components/inputs/unspecified/unspecified.test.js +152 -0
  133. package/dist/components/inputs/workspace-launcher/workspace-launcher.component.d.ts +5 -0
  134. package/dist/components/inputs/workspace-launcher/workspace-launcher.component.d.ts.map +1 -0
  135. package/dist/components/inputs/workspace-launcher/workspace-launcher.component.js +64 -0
  136. package/dist/components/inputs/workspace-launcher/workspace-launcher.scss +21 -0
  137. package/dist/components/inputs/workspace-launcher/workspace-launcher.test.js +174 -0
  138. package/dist/components/label/label.component.d.ts +8 -0
  139. package/dist/components/label/label.component.d.ts.map +1 -0
  140. package/dist/components/label/label.component.js +15 -0
  141. package/dist/components/label/label.scss +15 -0
  142. package/dist/components/loaders/loader.component.d.ts +4 -0
  143. package/dist/components/loaders/loader.component.d.ts.map +1 -0
  144. package/dist/components/loaders/loader.component.js +14 -0
  145. package/dist/components/loaders/loader.scss +20 -0
  146. package/dist/components/patient-banner/patient-banner.component.d.ts +7 -0
  147. package/dist/components/patient-banner/patient-banner.component.d.ts.map +1 -0
  148. package/dist/components/patient-banner/patient-banner.component.js +16 -0
  149. package/dist/components/patient-banner/patient-banner.scss +12 -0
  150. package/dist/components/previous-value-review/previous-value-review.component.d.ts +12 -0
  151. package/dist/components/previous-value-review/previous-value-review.component.d.ts.map +1 -0
  152. package/dist/components/previous-value-review/previous-value-review.component.js +29 -0
  153. package/dist/components/previous-value-review/previous-value-review.scss +36 -0
  154. package/dist/components/processor-factory/form-processor-factory.component.d.ts +10 -0
  155. package/dist/components/processor-factory/form-processor-factory.component.d.ts.map +1 -0
  156. package/dist/components/processor-factory/form-processor-factory.component.js +114 -0
  157. package/dist/components/renderer/custom-hooks-renderer.component.d.ts +13 -0
  158. package/dist/components/renderer/custom-hooks-renderer.component.d.ts.map +1 -0
  159. package/dist/components/renderer/custom-hooks-renderer.component.js +13 -0
  160. package/dist/components/renderer/field/fieldLogic.d.ts +16 -0
  161. package/dist/components/renderer/field/fieldLogic.d.ts.map +1 -0
  162. package/dist/components/renderer/field/fieldLogic.js +238 -0
  163. package/dist/components/renderer/field/fieldLogic.test.js +140 -0
  164. package/dist/components/renderer/field/fieldRenderUtils.d.ts +9 -0
  165. package/dist/components/renderer/field/fieldRenderUtils.d.ts.map +1 -0
  166. package/dist/components/renderer/field/fieldRenderUtils.js +8 -0
  167. package/dist/components/renderer/field/fieldRenderUtils.test.js +51 -0
  168. package/dist/components/renderer/field/form-field-renderer.component.d.ts +19 -0
  169. package/dist/components/renderer/field/form-field-renderer.component.d.ts.map +1 -0
  170. package/dist/components/renderer/field/form-field-renderer.component.js +214 -0
  171. package/dist/components/renderer/field/form-field-renderer.scss +5 -0
  172. package/dist/components/renderer/form/form-renderer.component.d.ts +10 -0
  173. package/dist/components/renderer/form/form-renderer.component.d.ts.map +1 -0
  174. package/dist/components/renderer/form/form-renderer.component.js +102 -0
  175. package/dist/components/renderer/form/state.d.ts +41 -0
  176. package/dist/components/renderer/form/state.d.ts.map +1 -0
  177. package/dist/components/renderer/form/state.js +69 -0
  178. package/dist/components/renderer/page/page.renderer.component.d.ts +9 -0
  179. package/dist/components/renderer/page/page.renderer.component.d.ts.map +1 -0
  180. package/dist/components/renderer/page/page.renderer.component.js +85 -0
  181. package/dist/components/renderer/page/page.renderer.scss +74 -0
  182. package/dist/components/renderer/section/section-renderer.component.d.ts +6 -0
  183. package/dist/components/renderer/section/section-renderer.component.d.ts.map +1 -0
  184. package/dist/components/renderer/section/section-renderer.component.js +20 -0
  185. package/dist/components/renderer/section/section-renderer.scss +19 -0
  186. package/dist/components/repeat/helpers.d.ts +6 -0
  187. package/dist/components/repeat/helpers.d.ts.map +1 -0
  188. package/dist/components/repeat/helpers.js +64 -0
  189. package/dist/components/repeat/helpers.test.js +25 -0
  190. package/dist/components/repeat/repeat-controls.component.d.ts +12 -0
  191. package/dist/components/repeat/repeat-controls.component.d.ts.map +1 -0
  192. package/dist/components/repeat/repeat-controls.component.js +22 -0
  193. package/dist/components/repeat/repeat-controls.scss +7 -0
  194. package/dist/components/repeat/repeat.component.d.ts +5 -0
  195. package/dist/components/repeat/repeat.component.d.ts.map +1 -0
  196. package/dist/components/repeat/repeat.component.js +185 -0
  197. package/dist/components/repeat/repeat.scss +30 -0
  198. package/dist/components/repeat/repeat.test.js +25 -0
  199. package/dist/components/sidebar/page-observer.d.ts +20 -0
  200. package/dist/components/sidebar/page-observer.d.ts.map +1 -0
  201. package/dist/components/sidebar/page-observer.js +60 -0
  202. package/dist/components/sidebar/sidebar.component.d.ts +14 -0
  203. package/dist/components/sidebar/sidebar.component.d.ts.map +1 -0
  204. package/dist/components/sidebar/sidebar.component.js +77 -0
  205. package/dist/components/sidebar/sidebar.scss +114 -0
  206. package/dist/components/sidebar/useCurrentActivePage.d.ts +34 -0
  207. package/dist/components/sidebar/useCurrentActivePage.d.ts.map +1 -0
  208. package/dist/components/sidebar/useCurrentActivePage.js +114 -0
  209. package/dist/components/sidebar/useCurrentActivePage.test.js +208 -0
  210. package/dist/components/sidebar/usePageObserver.d.ts +11 -0
  211. package/dist/components/sidebar/usePageObserver.d.ts.map +1 -0
  212. package/dist/components/sidebar/usePageObserver.js +42 -0
  213. package/dist/components/value/value.component.d.ts +6 -0
  214. package/dist/components/value/value.component.d.ts.map +1 -0
  215. package/dist/components/value/value.component.js +24 -0
  216. package/dist/components/value/value.scss +17 -0
  217. package/dist/components/value/view/field-value-view.component.d.ts +10 -0
  218. package/dist/components/value/view/field-value-view.component.d.ts.map +1 -0
  219. package/dist/components/value/view/field-value-view.component.js +29 -0
  220. package/dist/components/value/view/field-value-view.scss +31 -0
  221. package/dist/constants.d.ts +9 -0
  222. package/dist/constants.d.ts.map +1 -0
  223. package/dist/constants.js +13 -0
  224. package/dist/datasources/concept-data-source.d.ts +6 -0
  225. package/dist/datasources/concept-data-source.d.ts.map +1 -0
  226. package/dist/datasources/concept-data-source.js +35 -0
  227. package/dist/datasources/data-source.d.ts +10 -0
  228. package/dist/datasources/data-source.d.ts.map +1 -0
  229. package/dist/datasources/data-source.js +41 -0
  230. package/dist/datasources/encounter-role-datasource.d.ts +6 -0
  231. package/dist/datasources/encounter-role-datasource.d.ts.map +1 -0
  232. package/dist/datasources/encounter-role-datasource.js +13 -0
  233. package/dist/datasources/historical-data-source.d.ts +6 -0
  234. package/dist/datasources/historical-data-source.d.ts.map +1 -0
  235. package/dist/datasources/historical-data-source.js +24 -0
  236. package/dist/datasources/location-data-source.d.ts +6 -0
  237. package/dist/datasources/location-data-source.d.ts.map +1 -0
  238. package/dist/datasources/location-data-source.js +24 -0
  239. package/dist/datasources/provider-datasource.d.ts +6 -0
  240. package/dist/datasources/provider-datasource.d.ts.map +1 -0
  241. package/dist/datasources/provider-datasource.js +13 -0
  242. package/dist/datasources/select-concept-answers-datasource.d.ts +9 -0
  243. package/dist/datasources/select-concept-answers-datasource.d.ts.map +1 -0
  244. package/dist/datasources/select-concept-answers-datasource.js +19 -0
  245. package/dist/declarations.d.js +0 -0
  246. package/dist/external-function-context.d.ts +7 -0
  247. package/dist/external-function-context.d.ts.map +1 -0
  248. package/dist/external-function-context.js +2 -0
  249. package/dist/form-engine.component.d.ts +23 -0
  250. package/dist/form-engine.component.d.ts.map +1 -0
  251. package/dist/form-engine.component.js +174 -0
  252. package/dist/form-engine.scss +148 -0
  253. package/dist/form-engine.test.js +1253 -0
  254. package/dist/globals.d.ts +3 -0
  255. package/dist/globals.d.ts.map +1 -0
  256. package/dist/globals.js +2 -0
  257. package/dist/hooks/useConcepts.d.ts +23 -0
  258. package/dist/hooks/useConcepts.d.ts.map +1 -0
  259. package/dist/hooks/useConcepts.js +31 -0
  260. package/dist/hooks/useDataSourceDependentValue.d.ts +4 -0
  261. package/dist/hooks/useDataSourceDependentValue.d.ts.map +1 -0
  262. package/dist/hooks/useDataSourceDependentValue.js +14 -0
  263. package/dist/hooks/useEncounter.d.ts +7 -0
  264. package/dist/hooks/useEncounter.d.ts.map +1 -0
  265. package/dist/hooks/useEncounter.js +38 -0
  266. package/dist/hooks/useEncounterRole.d.ts +7 -0
  267. package/dist/hooks/useEncounterRole.d.ts.map +1 -0
  268. package/dist/hooks/useEncounterRole.js +18 -0
  269. package/dist/hooks/useEvaluateFormFieldExpressions.d.ts +7 -0
  270. package/dist/hooks/useEvaluateFormFieldExpressions.d.ts.map +1 -0
  271. package/dist/hooks/useEvaluateFormFieldExpressions.js +112 -0
  272. package/dist/hooks/useExternalFormAction.d.ts +43 -0
  273. package/dist/hooks/useExternalFormAction.d.ts.map +1 -0
  274. package/dist/hooks/useExternalFormAction.js +71 -0
  275. package/dist/hooks/useFormCollapse.d.ts +6 -0
  276. package/dist/hooks/useFormCollapse.d.ts.map +1 -0
  277. package/dist/hooks/useFormCollapse.js +35 -0
  278. package/dist/hooks/useFormFieldValidators.d.ts +3 -0
  279. package/dist/hooks/useFormFieldValidators.d.ts.map +1 -0
  280. package/dist/hooks/useFormFieldValidators.js +20 -0
  281. package/dist/hooks/useFormFieldValueAdapters.d.ts +3 -0
  282. package/dist/hooks/useFormFieldValueAdapters.d.ts.map +1 -0
  283. package/dist/hooks/useFormFieldValueAdapters.js +21 -0
  284. package/dist/hooks/useFormFields.d.ts +6 -0
  285. package/dist/hooks/useFormFields.d.ts.map +1 -0
  286. package/dist/hooks/useFormFields.js +62 -0
  287. package/dist/hooks/useFormFieldsMeta.d.ts +4 -0
  288. package/dist/hooks/useFormFieldsMeta.d.ts.map +1 -0
  289. package/dist/hooks/useFormFieldsMeta.js +42 -0
  290. package/dist/hooks/useFormJson.d.ts +19 -0
  291. package/dist/hooks/useFormJson.d.ts.map +1 -0
  292. package/dist/hooks/useFormJson.js +198 -0
  293. package/dist/hooks/useFormJson.test.js +194 -0
  294. package/dist/hooks/useFormStateHelpers.d.ts +15 -0
  295. package/dist/hooks/useFormStateHelpers.d.ts.map +1 -0
  296. package/dist/hooks/useFormStateHelpers.js +83 -0
  297. package/dist/hooks/useFormWorkspaceSize.d.ts +7 -0
  298. package/dist/hooks/useFormWorkspaceSize.d.ts.map +1 -0
  299. package/dist/hooks/useFormWorkspaceSize.js +46 -0
  300. package/dist/hooks/useFormWorkspaceSize.test.js +141 -0
  301. package/dist/hooks/useInitialValues.d.ts +9 -0
  302. package/dist/hooks/useInitialValues.d.ts.map +1 -0
  303. package/dist/hooks/useInitialValues.js +29 -0
  304. package/dist/hooks/useInitialValues.test.js +78 -0
  305. package/dist/hooks/usePatientData.d.ts +6 -0
  306. package/dist/hooks/usePatientData.d.ts.map +1 -0
  307. package/dist/hooks/usePatientData.js +30 -0
  308. package/dist/hooks/usePatientPrograms.d.ts +7 -0
  309. package/dist/hooks/usePatientPrograms.d.ts.map +1 -0
  310. package/dist/hooks/usePatientPrograms.js +22 -0
  311. package/dist/hooks/usePostSubmissionActions.d.ts +13 -0
  312. package/dist/hooks/usePostSubmissionActions.d.ts.map +1 -0
  313. package/dist/hooks/usePostSubmissionActions.js +23 -0
  314. package/dist/hooks/usePostSubmissionActions.test.js +55 -0
  315. package/dist/hooks/useProcessorDependencies.d.ts +8 -0
  316. package/dist/hooks/useProcessorDependencies.d.ts.map +1 -0
  317. package/dist/hooks/useProcessorDependencies.js +33 -0
  318. package/dist/index.d.ts +12 -0
  319. package/dist/index.d.ts.map +1 -0
  320. package/dist/index.js +11 -0
  321. package/dist/lifecycle.d.ts +11 -0
  322. package/dist/lifecycle.d.ts.map +1 -0
  323. package/dist/lifecycle.js +25 -0
  324. package/dist/post-submission-actions/mark-patient-deceased-action.d.ts +4 -0
  325. package/dist/post-submission-actions/mark-patient-deceased-action.d.ts.map +1 -0
  326. package/dist/post-submission-actions/mark-patient-deceased-action.js +53 -0
  327. package/dist/post-submission-actions/program-enrollment-action.d.ts +4 -0
  328. package/dist/post-submission-actions/program-enrollment-action.d.ts.map +1 -0
  329. package/dist/post-submission-actions/program-enrollment-action.js +105 -0
  330. package/dist/processors/encounter/encounter-form-processor.d.ts +26 -0
  331. package/dist/processors/encounter/encounter-form-processor.d.ts.map +1 -0
  332. package/dist/processors/encounter/encounter-form-processor.js +376 -0
  333. package/dist/processors/encounter/encounter-form-processor.test.js +207 -0
  334. package/dist/processors/encounter/encounter-processor-helper.d.ts +19 -0
  335. package/dist/processors/encounter/encounter-processor-helper.d.ts.map +1 -0
  336. package/dist/processors/encounter/encounter-processor-helper.js +293 -0
  337. package/dist/processors/form-processor.d.ts +25 -0
  338. package/dist/processors/form-processor.d.ts.map +1 -0
  339. package/dist/processors/form-processor.js +26 -0
  340. package/dist/provider/form-factory-helper.d.ts +8 -0
  341. package/dist/provider/form-factory-helper.d.ts.map +1 -0
  342. package/dist/provider/form-factory-helper.js +73 -0
  343. package/dist/provider/form-factory-provider.d.ts +48 -0
  344. package/dist/provider/form-factory-provider.d.ts.map +1 -0
  345. package/dist/provider/form-factory-provider.js +136 -0
  346. package/dist/provider/form-provider.d.ts +26 -0
  347. package/dist/provider/form-provider.d.ts.map +1 -0
  348. package/dist/provider/form-provider.js +17 -0
  349. package/dist/registry/inbuilt-components/InbuiltPostSubmissionActions.d.ts +4 -0
  350. package/dist/registry/inbuilt-components/InbuiltPostSubmissionActions.d.ts.map +1 -0
  351. package/dist/registry/inbuilt-components/InbuiltPostSubmissionActions.js +10 -0
  352. package/dist/registry/inbuilt-components/control-templates.d.ts +4 -0
  353. package/dist/registry/inbuilt-components/control-templates.d.ts.map +1 -0
  354. package/dist/registry/inbuilt-components/control-templates.js +54 -0
  355. package/dist/registry/inbuilt-components/inbuiltControls.d.ts +7 -0
  356. package/dist/registry/inbuilt-components/inbuiltControls.d.ts.map +1 -0
  357. package/dist/registry/inbuilt-components/inbuiltControls.js +94 -0
  358. package/dist/registry/inbuilt-components/inbuiltDataSources.d.ts +8 -0
  359. package/dist/registry/inbuilt-components/inbuiltDataSources.d.ts.map +1 -0
  360. package/dist/registry/inbuilt-components/inbuiltDataSources.js +36 -0
  361. package/dist/registry/inbuilt-components/inbuiltFieldValueAdapters.d.ts +4 -0
  362. package/dist/registry/inbuilt-components/inbuiltFieldValueAdapters.d.ts.map +1 -0
  363. package/dist/registry/inbuilt-components/inbuiltFieldValueAdapters.js +71 -0
  364. package/dist/registry/inbuilt-components/inbuiltTransformers.d.ts +4 -0
  365. package/dist/registry/inbuilt-components/inbuiltTransformers.d.ts.map +1 -0
  366. package/dist/registry/inbuilt-components/inbuiltTransformers.js +7 -0
  367. package/dist/registry/inbuilt-components/inbuiltValidators.d.ts +7 -0
  368. package/dist/registry/inbuilt-components/inbuiltValidators.d.ts.map +1 -0
  369. package/dist/registry/inbuilt-components/inbuiltValidators.js +29 -0
  370. package/dist/registry/inbuilt-components/template-component-map.d.ts +5 -0
  371. package/dist/registry/inbuilt-components/template-component-map.d.ts.map +1 -0
  372. package/dist/registry/inbuilt-components/template-component-map.js +27 -0
  373. package/dist/registry/registry.d.ts +61 -0
  374. package/dist/registry/registry.d.ts.map +1 -0
  375. package/dist/registry/registry.js +184 -0
  376. package/dist/registry/registry.test.js +17 -0
  377. package/dist/setup-tests.js +30 -0
  378. package/dist/transformers/default-schema-transformer.d.ts +4 -0
  379. package/dist/transformers/default-schema-transformer.d.ts.map +1 -0
  380. package/dist/transformers/default-schema-transformer.js +308 -0
  381. package/dist/transformers/default-schema-transformer.test.js +319 -0
  382. package/dist/types/domain.d.ts +219 -0
  383. package/dist/types/domain.d.ts.map +1 -0
  384. package/dist/types/domain.js +1 -0
  385. package/dist/types/index.d.ts +126 -0
  386. package/dist/types/index.d.ts.map +1 -0
  387. package/dist/types/index.js +2 -0
  388. package/dist/types/schema.d.ts +243 -0
  389. package/dist/types/schema.d.ts.map +1 -0
  390. package/dist/types/schema.js +1 -0
  391. package/dist/typings.d.js +1 -0
  392. package/dist/utils/boolean-utils.d.ts +13 -0
  393. package/dist/utils/boolean-utils.d.ts.map +1 -0
  394. package/dist/utils/boolean-utils.js +22 -0
  395. package/dist/utils/common-expression-helpers.d.ts +261 -0
  396. package/dist/utils/common-expression-helpers.d.ts.map +1 -0
  397. package/dist/utils/common-expression-helpers.js +538 -0
  398. package/dist/utils/common-expression-helpers.test.js +461 -0
  399. package/dist/utils/common-utils.d.ts +51 -0
  400. package/dist/utils/common-utils.d.ts.map +1 -0
  401. package/dist/utils/common-utils.js +102 -0
  402. package/dist/utils/common-utils.test.js +134 -0
  403. package/dist/utils/error-utils.d.ts +11 -0
  404. package/dist/utils/error-utils.d.ts.map +1 -0
  405. package/dist/utils/error-utils.js +34 -0
  406. package/dist/utils/expression-runner.d.ts +25 -0
  407. package/dist/utils/expression-runner.d.ts.map +1 -0
  408. package/dist/utils/expression-runner.js +104 -0
  409. package/dist/utils/expression-runner.test.js +362 -0
  410. package/dist/utils/form-helper.d.ts +37 -0
  411. package/dist/utils/form-helper.d.ts.map +1 -0
  412. package/dist/utils/form-helper.js +239 -0
  413. package/dist/utils/form-helper.test.js +638 -0
  414. package/dist/utils/form-page-utils.d.ts +3 -0
  415. package/dist/utils/form-page-utils.d.ts.map +1 -0
  416. package/dist/utils/form-page-utils.js +10 -0
  417. package/dist/utils/forms-loader.d.ts +45 -0
  418. package/dist/utils/forms-loader.d.ts.map +1 -0
  419. package/dist/utils/forms-loader.js +246 -0
  420. package/dist/utils/forms-loader.test.js +333 -0
  421. package/dist/utils/post-submission-action-helper.d.ts +2 -0
  422. package/dist/utils/post-submission-action-helper.d.ts.map +1 -0
  423. package/dist/utils/post-submission-action-helper.js +57 -0
  424. package/dist/utils/test-utils.js +66 -0
  425. package/dist/utils/zscore-service.d.ts +6 -0
  426. package/dist/utils/zscore-service.d.ts.map +1 -0
  427. package/dist/utils/zscore-service.js +54 -0
  428. package/dist/validators/conditional-answered-validator.d.ts +3 -0
  429. package/dist/validators/conditional-answered-validator.d.ts.map +1 -0
  430. package/dist/validators/conditional-answered-validator.js +18 -0
  431. package/dist/validators/conditional-answered-validator.test.js +63 -0
  432. package/dist/validators/date-validator.d.ts +3 -0
  433. package/dist/validators/date-validator.d.ts.map +1 -0
  434. package/dist/validators/date-validator.js +21 -0
  435. package/dist/validators/date-validator.test.js +53 -0
  436. package/dist/validators/default-value-validator.d.ts +3 -0
  437. package/dist/validators/default-value-validator.d.ts.map +1 -0
  438. package/dist/validators/default-value-validator.js +46 -0
  439. package/dist/validators/default-value-validator.test.js +95 -0
  440. package/dist/validators/form-validator.d.ts +9 -0
  441. package/dist/validators/form-validator.d.ts.map +1 -0
  442. package/dist/validators/form-validator.js +82 -0
  443. package/dist/validators/form-validator.test.js +158 -0
  444. package/dist/validators/js-expression-validator.d.ts +3 -0
  445. package/dist/validators/js-expression-validator.d.ts.map +1 -0
  446. package/dist/validators/js-expression-validator.js +25 -0
  447. package/dist/validators/js-expression-validator.test.js +115 -0
  448. package/dist/validators/schema.d.ts +1 -0
  449. package/dist/validators/schema.d.ts.map +1 -0
  450. package/dist/validators/schema.js +32 -0
  451. package/dist/zscore/bfa_boys_5_above.json +2522 -0
  452. package/dist/zscore/bfa_girls_5_above.json +2522 -0
  453. package/dist/zscore/hfa_boys_5_above.json +2186 -0
  454. package/dist/zscore/hfa_boys_below5.json +22286 -0
  455. package/dist/zscore/hfa_girls_5_above.json +2186 -0
  456. package/dist/zscore/hfa_girls_below5.json +22286 -0
  457. package/dist/zscore/wfl_boys_below5.json +7814 -0
  458. package/dist/zscore/wfl_girls_below5.json +7814 -0
  459. package/dist/zscore-tests/bmi-age.test.js +84 -0
  460. package/dist/zscore-tests/height-age.test.js +88 -0
  461. package/dist/zscore-tests/weight-height.test.js +82 -0
  462. package/package.json +105 -0
  463. package/src/adapters/control-adapter.ts +29 -0
  464. package/src/adapters/encounter-datetime-adapter.ts +38 -0
  465. package/src/adapters/encounter-diagnosis-adapter.ts +121 -0
  466. package/src/adapters/encounter-location-adapter.ts +39 -0
  467. package/src/adapters/encounter-provider-adapter.ts +48 -0
  468. package/src/adapters/encounter-role-adapter.ts +54 -0
  469. package/src/adapters/inline-date-adapter.ts +59 -0
  470. package/src/adapters/obs-adapter.ts +349 -0
  471. package/src/adapters/obs-comment-adapter.ts +61 -0
  472. package/src/adapters/orders-adapter.ts +82 -0
  473. package/src/adapters/patient-identifier-adapter.ts +46 -0
  474. package/src/adapters/person-attribute-adapter.ts +45 -0
  475. package/src/adapters/program-state-adapter.ts +57 -0
  476. package/src/api/index.ts +224 -0
  477. package/src/components/error/error-modal.component.tsx +37 -0
  478. package/src/components/error/error.scss +4 -0
  479. package/src/components/extension/extension-parcel.component.tsx +32 -0
  480. package/src/components/field-label/field-label.component.tsx +55 -0
  481. package/src/components/field-label/field-label.scss +15 -0
  482. package/src/components/group/obs-group.component.tsx +59 -0
  483. package/src/components/group/obs-group.scss +16 -0
  484. package/src/components/inputs/content-switcher/content-switcher.component.tsx +81 -0
  485. package/src/components/inputs/content-switcher/content-switcher.scss +55 -0
  486. package/src/components/inputs/date/date.component.tsx +141 -0
  487. package/src/components/inputs/date/date.scss +37 -0
  488. package/src/components/inputs/file/file-thumbnail.component.tsx +55 -0
  489. package/src/components/inputs/file/file-thumbnail.scss +42 -0
  490. package/src/components/inputs/file/file.component.tsx +98 -0
  491. package/src/components/inputs/file/file.scss +21 -0
  492. package/src/components/inputs/fixed-value/fixed-value.component.tsx +19 -0
  493. package/src/components/inputs/markdown/markdown-wrapper.component.tsx +14 -0
  494. package/src/components/inputs/markdown/markdown.component.tsx +24 -0
  495. package/src/components/inputs/multi-select/multi-select.component.tsx +152 -0
  496. package/src/components/inputs/multi-select/multi-select.scss +25 -0
  497. package/src/components/inputs/number/number.component.tsx +85 -0
  498. package/src/components/inputs/number/number.scss +15 -0
  499. package/src/components/inputs/radio/radio.component.tsx +81 -0
  500. package/src/components/inputs/radio/radio.scss +36 -0
  501. package/src/components/inputs/select/dropdown.component.tsx +86 -0
  502. package/src/components/inputs/select/dropdown.scss +11 -0
  503. package/src/components/inputs/text/text.component.tsx +67 -0
  504. package/src/components/inputs/text/text.scss +15 -0
  505. package/src/components/inputs/text-area/text-area.component.tsx +63 -0
  506. package/src/components/inputs/text-area/text-area.scss +11 -0
  507. package/src/components/inputs/toggle/toggle.component.tsx +66 -0
  508. package/src/components/inputs/toggle/toggle.scss +12 -0
  509. package/src/components/inputs/ui-select-extended/ui-select-extended.component.tsx +208 -0
  510. package/src/components/inputs/ui-select-extended/ui-select-extended.scss +19 -0
  511. package/src/components/inputs/unspecified/unspecified.component.tsx +84 -0
  512. package/src/components/inputs/unspecified/unspecified.scss +7 -0
  513. package/src/components/inputs/workspace-launcher/workspace-launcher.component.tsx +80 -0
  514. package/src/components/inputs/workspace-launcher/workspace-launcher.scss +21 -0
  515. package/src/components/label/label.component.tsx +20 -0
  516. package/src/components/label/label.scss +15 -0
  517. package/src/components/loaders/loader.component.tsx +16 -0
  518. package/src/components/loaders/loader.scss +20 -0
  519. package/src/components/patient-banner/patient-banner.component.tsx +20 -0
  520. package/src/components/patient-banner/patient-banner.scss +12 -0
  521. package/src/components/previous-value-review/previous-value-review.component.tsx +49 -0
  522. package/src/components/previous-value-review/previous-value-review.scss +36 -0
  523. package/src/components/processor-factory/form-processor-factory.component.tsx +128 -0
  524. package/src/components/renderer/custom-hooks-renderer.component.tsx +30 -0
  525. package/src/components/renderer/field/fieldLogic.ts +314 -0
  526. package/src/components/renderer/field/fieldRenderUtils.ts +16 -0
  527. package/src/components/renderer/field/form-field-renderer.component.tsx +291 -0
  528. package/src/components/renderer/field/form-field-renderer.scss +5 -0
  529. package/src/components/renderer/form/form-renderer.component.tsx +123 -0
  530. package/src/components/renderer/form/state.ts +59 -0
  531. package/src/components/renderer/page/page.renderer.component.tsx +120 -0
  532. package/src/components/renderer/page/page.renderer.scss +74 -0
  533. package/src/components/renderer/section/section-renderer.component.tsx +25 -0
  534. package/src/components/renderer/section/section-renderer.scss +19 -0
  535. package/src/components/repeat/helpers.ts +77 -0
  536. package/src/components/repeat/repeat-controls.component.tsx +38 -0
  537. package/src/components/repeat/repeat-controls.scss +7 -0
  538. package/src/components/repeat/repeat.component.tsx +206 -0
  539. package/src/components/repeat/repeat.scss +30 -0
  540. package/src/components/sidebar/page-observer.ts +58 -0
  541. package/src/components/sidebar/sidebar.component.tsx +121 -0
  542. package/src/components/sidebar/sidebar.scss +114 -0
  543. package/src/components/sidebar/useCurrentActivePage.ts +137 -0
  544. package/src/components/sidebar/usePageObserver.ts +45 -0
  545. package/src/components/value/value.component.tsx +30 -0
  546. package/src/components/value/value.scss +17 -0
  547. package/src/components/value/view/field-value-view.component.tsx +36 -0
  548. package/src/components/value/view/field-value-view.scss +31 -0
  549. package/src/constants.ts +14 -0
  550. package/src/datasources/concept-data-source.ts +42 -0
  551. package/src/datasources/data-source.ts +34 -0
  552. package/src/datasources/encounter-role-datasource.ts +15 -0
  553. package/src/datasources/historical-data-source.ts +11 -0
  554. package/src/datasources/location-data-source.ts +27 -0
  555. package/src/datasources/provider-datasource.ts +15 -0
  556. package/src/datasources/select-concept-answers-datasource.ts +25 -0
  557. package/src/declarations.d.ts +2 -0
  558. package/src/external-function-context.tsx +8 -0
  559. package/src/form-engine.component.tsx +222 -0
  560. package/src/form-engine.scss +148 -0
  561. package/src/globals.ts +2 -0
  562. package/src/hooks/useConcepts.ts +58 -0
  563. package/src/hooks/useDataSourceDependentValue.ts +16 -0
  564. package/src/hooks/useEncounter.ts +40 -0
  565. package/src/hooks/useEncounterRole.ts +15 -0
  566. package/src/hooks/useEvaluateFormFieldExpressions.ts +152 -0
  567. package/src/hooks/useExternalFormAction.ts +94 -0
  568. package/src/hooks/useFormCollapse.ts +36 -0
  569. package/src/hooks/useFormFieldValidators.ts +22 -0
  570. package/src/hooks/useFormFieldValueAdapters.ts +23 -0
  571. package/src/hooks/useFormFields.ts +65 -0
  572. package/src/hooks/useFormFieldsMeta.ts +48 -0
  573. package/src/hooks/useFormJson.ts +257 -0
  574. package/src/hooks/useFormStateHelpers.ts +72 -0
  575. package/src/hooks/useFormWorkspaceSize.ts +52 -0
  576. package/src/hooks/useInitialValues.ts +39 -0
  577. package/src/hooks/usePatientData.ts +32 -0
  578. package/src/hooks/usePatientPrograms.ts +38 -0
  579. package/src/hooks/usePostSubmissionActions.ts +31 -0
  580. package/src/hooks/useProcessorDependencies.ts +42 -0
  581. package/src/index.ts +11 -0
  582. package/src/lifecycle.ts +32 -0
  583. package/src/post-submission-actions/mark-patient-deceased-action.ts +68 -0
  584. package/src/post-submission-actions/program-enrollment-action.ts +137 -0
  585. package/src/processors/encounter/encounter-form-processor.ts +445 -0
  586. package/src/processors/encounter/encounter-processor-helper.ts +387 -0
  587. package/src/processors/form-processor.ts +40 -0
  588. package/src/provider/form-factory-helper.ts +106 -0
  589. package/src/provider/form-factory-provider.tsx +211 -0
  590. package/src/provider/form-provider.tsx +39 -0
  591. package/src/registry/inbuilt-components/InbuiltPostSubmissionActions.ts +13 -0
  592. package/src/registry/inbuilt-components/control-templates.ts +57 -0
  593. package/src/registry/inbuilt-components/inbuiltControls.ts +99 -0
  594. package/src/registry/inbuilt-components/inbuiltDataSources.ts +41 -0
  595. package/src/registry/inbuilt-components/inbuiltFieldValueAdapters.ts +74 -0
  596. package/src/registry/inbuilt-components/inbuiltTransformers.ts +10 -0
  597. package/src/registry/inbuilt-components/inbuiltValidators.ts +33 -0
  598. package/src/registry/inbuilt-components/template-component-map.ts +28 -0
  599. package/src/registry/registry.ts +290 -0
  600. package/src/transformers/default-schema-transformer.ts +340 -0
  601. package/src/types/domain.ts +237 -0
  602. package/src/types/index.ts +153 -0
  603. package/src/types/schema.ts +259 -0
  604. package/src/typings.d.ts +9 -0
  605. package/src/utils/boolean-utils.ts +25 -0
  606. package/src/utils/common-expression-helpers.ts +636 -0
  607. package/src/utils/common-utils.ts +108 -0
  608. package/src/utils/error-utils.ts +37 -0
  609. package/src/utils/expression-runner.ts +172 -0
  610. package/src/utils/form-helper.ts +283 -0
  611. package/src/utils/form-page-utils.ts +13 -0
  612. package/src/utils/forms-loader.ts +306 -0
  613. package/src/utils/post-submission-action-helper.ts +71 -0
  614. package/src/utils/zscore-service.ts +59 -0
  615. package/src/validators/conditional-answered-validator.ts +17 -0
  616. package/src/validators/date-validator.ts +19 -0
  617. package/src/validators/default-value-validator.ts +36 -0
  618. package/src/validators/form-validator.ts +95 -0
  619. package/src/validators/js-expression-validator.ts +44 -0
  620. package/src/validators/schema.ts +34 -0
  621. package/src/zscore/bfa_boys_5_above.json +2522 -0
  622. package/src/zscore/bfa_girls_5_above.json +2522 -0
  623. package/src/zscore/hfa_boys_5_above.json +2186 -0
  624. package/src/zscore/hfa_boys_below5.json +22286 -0
  625. package/src/zscore/hfa_girls_5_above.json +2186 -0
  626. package/src/zscore/hfa_girls_below5.json +22286 -0
  627. package/src/zscore/wfl_boys_below5.json +7814 -0
  628. package/src/zscore/wfl_girls_below5.json +7814 -0
@@ -0,0 +1,636 @@
1
+ import dayjs from 'dayjs';
2
+ import customParseFormat from 'dayjs/plugin/customParseFormat';
3
+ dayjs.extend(customParseFormat);
4
+ import findIndex from 'lodash/findIndex';
5
+ import filter from 'lodash/filter';
6
+ import first from 'lodash/first';
7
+ import forEach from 'lodash/forEach';
8
+ import last from 'lodash/last';
9
+ import { type FormField } from '../types';
10
+ import { type FormNode } from './expression-runner';
11
+ import { isEmpty as isValueEmpty } from '../validators/form-validator';
12
+ import * as apiFunctions from '../api';
13
+ import { getZRefByGenderAndAge } from './zscore-service';
14
+ import { formatDate, parseDate } from '@openmrs/esm-framework';
15
+
16
+ export class CommonExpressionHelpers {
17
+ node: FormNode = null;
18
+ patient: any = null;
19
+ allFields: FormField[] = [];
20
+ allFieldValues: Record<string, any> = {};
21
+ api = apiFunctions;
22
+ isEmpty = isValueEmpty;
23
+ dayjs = dayjs;
24
+
25
+ constructor(node: FormNode, patient: any, allFields: FormField[], allFieldValues: Record<string, any>) {
26
+ this.allFields = allFields;
27
+ this.allFieldValues = allFieldValues;
28
+ this.node = node;
29
+ this.patient = patient;
30
+ }
31
+
32
+ /**
33
+ * Shared helper for Z-score calculations. Finds the standard deviation (SD) value
34
+ * by comparing a measurement against WHO growth reference data.
35
+ * @param refSectionObject - Reference data object with SD columns (e.g., '-3SD', '-2SD', etc.)
36
+ * @param measurementValue - The patient's measurement to compare against reference values
37
+ * @returns The SD score as a string (e.g., '-2', '0', '1') or null if no reference data
38
+ */
39
+ private calculateZScoreFromRef = (
40
+ refSectionObject: Record<string, any> | undefined,
41
+ measurementValue: number,
42
+ ): string | null => {
43
+ if (!refSectionObject) {
44
+ console.warn('Z-score calculation: No reference data object provided');
45
+ return null;
46
+ }
47
+
48
+ const refObjectKeys = Object.keys(refSectionObject);
49
+ const refObjectValues = refObjectKeys.map((key) => refSectionObject[key]);
50
+ const minimumValue = refObjectValues[1];
51
+ const minReferencePoint: number[] = [];
52
+
53
+ if (measurementValue < minimumValue) {
54
+ minReferencePoint.push(minimumValue);
55
+ } else {
56
+ forEach(refObjectValues, (value) => {
57
+ if (value <= measurementValue) {
58
+ minReferencePoint.push(value);
59
+ }
60
+ });
61
+ }
62
+
63
+ const lastReferenceValue = last(minReferencePoint);
64
+ const lastValueIndex = findIndex(refObjectValues, (o) => o === lastReferenceValue);
65
+ const SDValue = refObjectKeys[lastValueIndex];
66
+ let formattedSDValue = SDValue?.replace('SD', '');
67
+
68
+ if (formattedSDValue?.includes('neg')) {
69
+ formattedSDValue = '-' + formattedSDValue.substring(0, 1);
70
+ }
71
+
72
+ if (formattedSDValue === 'S' || formattedSDValue === 'L' || formattedSDValue === 'M' || formattedSDValue === '-5') {
73
+ formattedSDValue = '-4';
74
+ }
75
+
76
+ return formattedSDValue ?? null;
77
+ };
78
+
79
+ /**
80
+ * Returns the current date and time.
81
+ * @returns A new Date object representing the current moment
82
+ */
83
+ today = () => {
84
+ return new Date();
85
+ };
86
+
87
+ /**
88
+ * Checks if a collection contains a specific value.
89
+ * @param collection - The array to search in
90
+ * @param value - The value to search for
91
+ * @returns true if the collection contains the value, false otherwise
92
+ */
93
+ includes = <T = any>(collection: T[], value: T) => {
94
+ return collection?.includes(value);
95
+ };
96
+
97
+ /**
98
+ * Checks if the left date is before the right date.
99
+ * @param left - The date to check
100
+ * @param right - The date to compare against (can be a Date object or string)
101
+ * @param format - Optional format string for parsing right date (defaults to 'YYYY-MM-DD')
102
+ * @returns true if left is before right
103
+ */
104
+ isDateBefore = (left: Date, right: string | Date, format?: string): boolean => {
105
+ const otherDate: Date =
106
+ right instanceof Date
107
+ ? right
108
+ : format
109
+ ? dayjs(right, format, true).toDate()
110
+ : dayjs(right, 'YYYY-MM-DD', true).toDate();
111
+ return left?.getTime() < otherDate.getTime();
112
+ };
113
+
114
+ /**
115
+ * Checks if selectedDate is on or after baseDate plus a duration offset.
116
+ * @param selectedDate - The date to check
117
+ * @param baseDate - The base date to add the duration to
118
+ * @param duration - The number of time units to add to baseDate
119
+ * @param timePeriod - The time unit: 'days', 'weeks', 'months', or 'years'
120
+ * @returns true if selectedDate >= (baseDate + duration)
121
+ */
122
+ isDateAfter = (
123
+ selectedDate: Date,
124
+ baseDate: Date,
125
+ duration: number,
126
+ timePeriod: 'days' | 'weeks' | 'months' | 'years',
127
+ ): boolean => {
128
+ const parsedBaseDate = dayjs(baseDate);
129
+
130
+ let calculatedDate: Date;
131
+ switch (timePeriod) {
132
+ case 'months':
133
+ calculatedDate = parsedBaseDate.add(duration, 'month').toDate();
134
+ break;
135
+ case 'weeks':
136
+ calculatedDate = parsedBaseDate.add(duration, 'week').toDate();
137
+ break;
138
+ case 'days':
139
+ calculatedDate = parsedBaseDate.add(duration, 'day').toDate();
140
+ break;
141
+ case 'years':
142
+ calculatedDate = parsedBaseDate.add(duration, 'year').toDate();
143
+ break;
144
+ default:
145
+ calculatedDate = new Date(0);
146
+ }
147
+ return selectedDate.getTime() >= calculatedDate.getTime();
148
+ };
149
+
150
+ /**
151
+ * Adds weeks to a date without mutating the original.
152
+ * @param date - The starting date
153
+ * @param weeks - Number of weeks to add
154
+ * @returns A new Date object with the weeks added
155
+ */
156
+ addWeeksToDate = (date: Date, weeks: number): Date => {
157
+ return dayjs(date).add(weeks, 'week').toDate();
158
+ };
159
+
160
+ /**
161
+ * Adds days to a date without mutating the original.
162
+ * @param date - The starting date
163
+ * @param days - Number of days to add
164
+ * @returns A new Date object with the days added
165
+ */
166
+ addDaysToDate = (date: Date, days: number): Date => {
167
+ return dayjs(date).add(days, 'day').toDate();
168
+ };
169
+
170
+ /**
171
+ * Simple date comparison - checks if left date is strictly after right date.
172
+ * Mirrors the API of isDateBefore for consistency.
173
+ * @param left - The date to check
174
+ * @param right - The date to compare against (string or Date)
175
+ * @param format - Optional format string for parsing right date (defaults to 'YYYY-MM-DD')
176
+ * @returns true if left is after right
177
+ */
178
+ isDateAfterSimple = (left: Date, right: string | Date, format?: string): boolean => {
179
+ const otherDate: Date =
180
+ right instanceof Date
181
+ ? right
182
+ : format
183
+ ? dayjs(right, format, true).toDate()
184
+ : dayjs(right, 'YYYY-MM-DD', true).toDate();
185
+ return left?.getTime() > otherDate.getTime();
186
+ };
187
+
188
+ /**
189
+ * Retrieves the current value of another form field and registers a dependency.
190
+ * When the referenced field changes, expressions using this helper will be re-evaluated.
191
+ * @param questionId - The ID of the field to get the value from
192
+ * @returns The field's current value, or null if not found/set
193
+ */
194
+ useFieldValue = (questionId: string) => {
195
+ const targetField = this.allFields.find((field) => field.id === questionId);
196
+ if (targetField) {
197
+ registerDependency(this.node, targetField);
198
+ }
199
+ return this.allFieldValues[questionId] ?? null;
200
+ };
201
+
202
+ /**
203
+ * Tests if a value does NOT match a regular expression pattern.
204
+ * Returns true for empty/null/undefined values (treated as non-matching).
205
+ * @param regexString - The regular expression pattern to test against
206
+ * @param val - The value to test
207
+ * @returns true if the value does not match the pattern or is empty/null/undefined
208
+ */
209
+ doesNotMatchExpression = (regexString: string, val: string | null | undefined): boolean => {
210
+ if (!val || ['undefined', 'null', ''].includes(val.toString())) {
211
+ return true;
212
+ }
213
+ const pattern = new RegExp(regexString);
214
+
215
+ return !pattern.test(val);
216
+ };
217
+
218
+ /**
219
+ * Calculates Body Mass Index (BMI) from height and weight.
220
+ * Formula: weight (kg) / height (m)²
221
+ * @param height - Height in centimeters
222
+ * @param weight - Weight in kilograms
223
+ * @returns BMI rounded to 1 decimal place, or null if inputs are missing
224
+ */
225
+ calcBMI = (height: number, weight: number) => {
226
+ if (!height || !weight) {
227
+ return null;
228
+ }
229
+ const heightInMeters = height / 100;
230
+ const bmi = (weight / (heightInMeters * heightInMeters)).toFixed(1);
231
+ return parseFloat(bmi);
232
+ };
233
+
234
+ /**
235
+ * Calculates the Expected Date of Delivery (EDD) from the last menstrual period.
236
+ * Uses Naegele's rule: LMP + 280 days (40 weeks).
237
+ * @param lmp - Last menstrual period date
238
+ * @returns Expected delivery date, or null if lmp is not provided
239
+ */
240
+ calcEDD = (lmp: Date): Date | null => {
241
+ if (!lmp) {
242
+ return null;
243
+ }
244
+ return new Date(lmp.getTime() + 280 * 24 * 60 * 60 * 1000);
245
+ };
246
+
247
+ /**
248
+ * Calculates the number of complete months a patient has been on ART.
249
+ * @param artStartDate - The date when ART treatment started
250
+ * @returns Number of months on ART, 0 if less than 30 days, or null if no start date
251
+ * @throws Error if artStartDate is not a valid Date object
252
+ */
253
+ calcMonthsOnART = (artStartDate: Date) => {
254
+ if (artStartDate == null) {
255
+ return null;
256
+ }
257
+
258
+ if (!(artStartDate instanceof Date)) {
259
+ throw new Error('DateFormatException: value passed is not a valid date');
260
+ }
261
+
262
+ const today = new Date();
263
+ const artInDays = Math.round((today.getTime() - artStartDate.getTime()) / 86400000);
264
+
265
+ if (artInDays < 30) {
266
+ return 0;
267
+ }
268
+
269
+ return dayjs(today).diff(artStartDate, 'month');
270
+ };
271
+
272
+ /**
273
+ * Determines viral load suppression status based on the viral load count.
274
+ *
275
+ * WARNING: This function returns hardcoded concept UUIDs that are specific to certain
276
+ * OpenMRS implementations. These UUIDs may not exist or may differ in your system.
277
+ * Consider using form-level configuration or concept mappings instead.
278
+ *
279
+ * @param viralLoadCount - The viral load count (copies/mL)
280
+ * @returns Concept UUID based on suppression threshold (>50 copies/mL), or null if no count
281
+ * @deprecated Consider implementing viral load status logic in form expressions with
282
+ * configurable concept UUIDs instead of using this hardcoded helper.
283
+ */
284
+ calcViralLoadStatus = (viralLoadCount: number) => {
285
+ let resultViralLoadStatus: string;
286
+ if (viralLoadCount) {
287
+ if (viralLoadCount > 50) {
288
+ resultViralLoadStatus = 'a6768be6-c08e-464d-8f53-5f4229508e54';
289
+ } else {
290
+ resultViralLoadStatus = '5d5e42cc-acc4-4069-b3a8-7163e0db5d96';
291
+ }
292
+ }
293
+ return resultViralLoadStatus ?? null;
294
+ };
295
+
296
+ /**
297
+ * Calculates the next clinic visit date based on ARV dispensing duration.
298
+ * @param followupDate - The current follow-up/encounter date
299
+ * @param arvDispensedInDays - Number of days of ARV medication dispensed
300
+ * @returns The next visit date (followupDate + arvDispensedInDays), or null if inputs are missing
301
+ */
302
+ calcNextVisitDate = (followupDate: Date, arvDispensedInDays: number): Date | null => {
303
+ if (followupDate && arvDispensedInDays) {
304
+ return new Date(followupDate.getTime() + arvDispensedInDays * 24 * 60 * 60 * 1000);
305
+ }
306
+ return null;
307
+ };
308
+
309
+ /**
310
+ * Calculates the treatment end date for patients on ART.
311
+ * Adds a 30-day grace period plus the ARV dispensing duration.
312
+ *
313
+ * WARNING: This function checks against a hardcoded concept UUID (160429AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)
314
+ * for 'Currently in Treatment' status. This UUID may not exist or may differ in your system.
315
+ * Consider implementing this logic in form expressions with configurable concept references instead.
316
+ *
317
+ * @param followupDate - The current follow-up/encounter date
318
+ * @param arvDispensedInDays - Number of days of ARV medication dispensed
319
+ * @param patientStatus - The patient's treatment status UUID (must match hardcoded UUID)
320
+ * @returns Treatment end date (followupDate + 30 + arvDispensedInDays), or null if conditions not met
321
+ * @deprecated Consider implementing treatment end date logic in form expressions with
322
+ * configurable concept UUIDs instead of using this hardcoded helper.
323
+ */
324
+ calcTreatmentEndDate = (followupDate: Date, arvDispensedInDays: number, patientStatus: string): Date | null => {
325
+ if (!followupDate || !arvDispensedInDays || patientStatus !== '160429AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') {
326
+ return null;
327
+ }
328
+ const extraDaysAdded = 30 + arvDispensedInDays;
329
+ return new Date(followupDate.getTime() + extraDaysAdded * 24 * 60 * 60 * 1000);
330
+ };
331
+
332
+ /**
333
+ * Calculates the patient's age in years based on a reference date.
334
+ * Note: Uses year-only calculation (ignores month/day), so a patient born in December 1990
335
+ * will be considered 31 years old on January 1, 2021.
336
+ * @param dateValue - The reference date to calculate age at (defaults to today if not provided)
337
+ * @returns Age in years (year difference only, not precise age)
338
+ */
339
+ calcAgeBasedOnDate = (dateValue?: ConstructorParameters<typeof Date>[0] | null): number => {
340
+ const targetYear = dateValue ? new Date(dateValue).getFullYear() : new Date().getFullYear();
341
+ const birthYear = new Date(this.patient.birthDate).getFullYear();
342
+ return targetYear - birthYear;
343
+ };
344
+
345
+ /**
346
+ * Calculates Body Surface Area (BSA) using the Mosteller formula.
347
+ * Formula: √((height × weight) / 3600)
348
+ * @param height - Height in centimeters
349
+ * @param weight - Weight in kilograms
350
+ * @returns BSA in m² rounded to 2 decimal places, or null if inputs are missing
351
+ */
352
+ calcBSA = (height: number, weight: number): number | null => {
353
+ if (!height || !weight) {
354
+ return null;
355
+ }
356
+ return parseFloat(Math.sqrt((height * weight) / 3600).toFixed(2));
357
+ };
358
+
359
+ /**
360
+ * Checks if an array contains ALL of the specified members.
361
+ * @param array - The array to search in
362
+ * @param members - A single value or array of values that must all be present
363
+ * @returns true if array contains all members, false otherwise.
364
+ * Returns true for empty members array. Returns false for null/non-array input.
365
+ */
366
+ arrayContains = <T = any>(array: T[], members: T[] | T) => {
367
+ if (!array || !Array.isArray(array)) {
368
+ return false;
369
+ }
370
+
371
+ if (array.length === 0) {
372
+ return members === undefined || members === null || (Array.isArray(members) && members.length === 0);
373
+ }
374
+
375
+ if (!Array.isArray(members)) {
376
+ members = [members];
377
+ }
378
+
379
+ if (members.length === 0) {
380
+ return true;
381
+ }
382
+
383
+ for (let val of members) {
384
+ if (array.indexOf(val) === -1) {
385
+ return false;
386
+ }
387
+ }
388
+
389
+ return true;
390
+ };
391
+
392
+ /**
393
+ * Checks if an array contains ANY of the specified members.
394
+ * @param array - The array to search in
395
+ * @param members - An array of values where at least one must be present
396
+ * @returns true if array contains at least one member, false otherwise.
397
+ * Returns true for empty members array. Returns false for null/non-array input.
398
+ */
399
+ arrayContainsAny = <T = any>(array: T[], members: T[]) => {
400
+ if (!array || !Array.isArray(array)) {
401
+ return false;
402
+ }
403
+
404
+ if (array.length === 0) {
405
+ return members === undefined || members === null || (Array.isArray(members) && members.length === 0);
406
+ }
407
+
408
+ if (!Array.isArray(members)) {
409
+ members = [members];
410
+ }
411
+
412
+ if (members.length === 0) {
413
+ return true;
414
+ }
415
+
416
+ for (let val of members) {
417
+ if (array.indexOf(val) !== -1) {
418
+ return true;
419
+ }
420
+ }
421
+
422
+ return false;
423
+ };
424
+
425
+ /**
426
+ * Parses a date string into a Date object using OpenMRS framework parsing.
427
+ * @param dateString - The date string to parse
428
+ * @returns A Date object
429
+ */
430
+ parseDate = (dateString: string) => {
431
+ return parseDate(dateString);
432
+ };
433
+
434
+ /**
435
+ * Formats a date value into a string.
436
+ * @param value - The date to format (Date object or value that can be converted to Date)
437
+ * @param format - Optional dayjs format string (e.g., 'YYYY-MM-DD', 'DD/MM/YYYY').
438
+ * If not provided, uses OpenMRS default locale format.
439
+ * @returns Formatted date string
440
+ * @throws Error if the value cannot be converted to a valid date
441
+ */
442
+ formatDate = (value: ConstructorParameters<typeof Date>[0], format?: string) => {
443
+ if (!(value instanceof Date)) {
444
+ value = new Date(value);
445
+ if (isNaN(value.getTime())) {
446
+ throw new Error('DateFormatException: value passed is not a valid date');
447
+ }
448
+ }
449
+ if (format) {
450
+ return dayjs(value).format(format);
451
+ }
452
+ return formatDate(value);
453
+ };
454
+
455
+ /**
456
+ * Extracts values for a specific key from an array of objects (typically repeating group data).
457
+ * @param key - The property key to extract from each object
458
+ * @param array - Array of objects to extract values from
459
+ * @returns Array of values for the specified key
460
+ */
461
+ extractRepeatingGroupValues = (key: string | number | symbol, array: Record<string | number | symbol, unknown>[]) => {
462
+ const values = array.map(function (item) {
463
+ return item[key];
464
+ });
465
+ return values;
466
+ };
467
+
468
+ /**
469
+ * Calculates the gravida (total number of pregnancies) based on term pregnancies and abortions/miscarriages.
470
+ * @param parityTerm - The number of term pregnancies (can be number or numeric string)
471
+ * @param parityAbortion - The number of abortions including miscarriages (can be number or numeric string)
472
+ * @returns The total number of pregnancies (gravida)
473
+ * @throws Error if either input is not a valid number
474
+ */
475
+ calcGravida = (parityTerm: number | string, parityAbortion: number | string): number => {
476
+ const term = typeof parityTerm === 'number' ? parityTerm : parseInt(parityTerm, 10);
477
+ const abortion = typeof parityAbortion === 'number' ? parityAbortion : parseInt(parityAbortion, 10);
478
+
479
+ if (!Number.isInteger(term) || !Number.isInteger(abortion)) {
480
+ throw new Error('Both inputs must be valid numbers.');
481
+ }
482
+
483
+ return term + abortion;
484
+ };
485
+
486
+ /**
487
+ * Calculates the Weight-for-Height Z-score for pediatric patients using WHO growth standards.
488
+ * Used to assess acute malnutrition (wasting).
489
+ * @param height - Patient's height/length in centimeters (valid range: 45-110 cm)
490
+ * @param weight - Patient's weight in kilograms
491
+ * @returns Z-score as a string (e.g., '-2', '0', '1'), '-4' if out of range, or null if inputs missing
492
+ */
493
+ calcWeightForHeightZscore = (height: number, weight: number): string | null => {
494
+ if (!height || !weight) {
495
+ return null;
496
+ }
497
+
498
+ const birthDate = new Date(this.patient.birthDate);
499
+ const weightForHeightRef = getZRefByGenderAndAge(this.patient.sex, birthDate, new Date()).weightForHeightRef;
500
+
501
+ const formattedHeight = height.toFixed(1);
502
+ const standardHeightMin = 45;
503
+ const standardMaxHeight = 110;
504
+
505
+ if (parseFloat(formattedHeight) < standardHeightMin || parseFloat(formattedHeight) > standardMaxHeight) {
506
+ return '-4';
507
+ }
508
+
509
+ const refSection = filter(weightForHeightRef, (refObject) => {
510
+ return parseFloat(refObject['Length']).toFixed(1) === formattedHeight;
511
+ });
512
+
513
+ const refSectionObject = first(refSection);
514
+ return this.calculateZScoreFromRef(refSectionObject, weight);
515
+ };
516
+
517
+ /**
518
+ * Calculates the BMI-for-Age Z-score for pediatric patients using WHO growth standards.
519
+ * Used to assess both undernutrition and overweight/obesity.
520
+ * @param height - Patient's height in centimeters
521
+ * @param weight - Patient's weight in kilograms
522
+ * @returns Z-score as a string (e.g., '-2', '0', '1'), or null if inputs missing
523
+ */
524
+ calcBMIForAgeZscore = (height: number, weight: number): string | null => {
525
+ if (!height || !weight) {
526
+ return null;
527
+ }
528
+
529
+ const birthDate = new Date(this.patient.birthDate);
530
+ const bmiForAgeRef = getZRefByGenderAndAge(this.patient.sex, birthDate, new Date()).bmiForAgeRef;
531
+
532
+ const heightInMeters = height / 100;
533
+ const bmi = parseFloat((weight / (heightInMeters * heightInMeters)).toFixed(1));
534
+
535
+ const refSectionObject = first(bmiForAgeRef);
536
+ return this.calculateZScoreFromRef(refSectionObject, bmi);
537
+ };
538
+
539
+ /**
540
+ * Calculates the Height-for-Age Z-score for pediatric patients using WHO growth standards.
541
+ * Used to assess chronic malnutrition (stunting).
542
+ * @param height - Patient's height/length in centimeters
543
+ * @param _weight - Unused parameter kept for backward compatibility
544
+ * @returns Z-score as a string (e.g., '-2', '0', '1'), or null if height is missing
545
+ */
546
+ calcHeightForAgeZscore = (height: number, _weight?: number): string | null => {
547
+ if (!height) {
548
+ return null;
549
+ }
550
+
551
+ const birthDate = new Date(this.patient.birthDate);
552
+ const heightForAgeRef = getZRefByGenderAndAge(this.patient.sex, birthDate, new Date()).heightForAgeRef;
553
+ const refSectionObject = first(heightForAgeRef);
554
+
555
+ return this.calculateZScoreFromRef(refSectionObject, height);
556
+ };
557
+
558
+ /**
559
+ * Calculates the time difference between an observation date and today.
560
+ * @param obsDate - The observation/reference date to compare against today
561
+ * @param timeFrame - The unit of time: 'd' (days), 'w' (weeks), 'm' (months), or 'y' (years)
562
+ * @returns The absolute time difference as a number, or 0 if obsDate is not provided
563
+ */
564
+ calcTimeDifference = (obsDate: Date | dayjs.Dayjs, timeFrame: 'd' | 'w' | 'm' | 'y'): number => {
565
+ if (!obsDate) {
566
+ return 0;
567
+ }
568
+
569
+ const endDate = dayjs();
570
+ switch (timeFrame) {
571
+ case 'd':
572
+ return Math.abs(Math.round(endDate.diff(obsDate, 'day', true)));
573
+ case 'w':
574
+ return Math.abs(Math.round(endDate.diff(obsDate, 'week', true)));
575
+ case 'm':
576
+ return Math.abs(Math.round(endDate.diff(obsDate, 'month', true)));
577
+ case 'y':
578
+ return Math.abs(Math.round(endDate.diff(obsDate, 'year', true)));
579
+ }
580
+ };
581
+
582
+ /**
583
+ * Resolves a Promise and returns its value. Used to await async operations in form expressions.
584
+ * @param lazy - A Promise to resolve
585
+ * @returns A Promise that resolves to the value of the input Promise
586
+ */
587
+ resolve = (lazy: Promise<unknown>) => {
588
+ return Promise.resolve(lazy);
589
+ };
590
+ }
591
+
592
+ /**
593
+ * Simple hash function to generate a unique identifier for a string.
594
+ * @param str - The string to hash.
595
+ * @returns A unique identifier for the string.
596
+ */
597
+ export function simpleHash(str: string) {
598
+ let hash = 0;
599
+ for (let i = 0; i < str.length; i++) {
600
+ const char = str.charCodeAt(i);
601
+ hash = (hash << 5) - hash + char;
602
+ hash |= 0;
603
+ }
604
+ return hash;
605
+ }
606
+
607
+ /**
608
+ * Registers a dependency relationship between a form node and a field.
609
+ * When the determinant field's value changes, the dependent node will be re-evaluated.
610
+ * @param node - The dependent node (page, section, or field) that depends on the determinant
611
+ * @param determinant - The field that the node depends on
612
+ */
613
+ export function registerDependency(node: FormNode, determinant: FormField) {
614
+ if (!node || !determinant) {
615
+ return;
616
+ }
617
+ switch (node.type) {
618
+ case 'page':
619
+ if (!determinant.pageDependents) {
620
+ determinant.pageDependents = new Set();
621
+ }
622
+ determinant.pageDependents.add(node.value.label);
623
+ break;
624
+ case 'section':
625
+ if (!determinant.sectionDependents) {
626
+ determinant.sectionDependents = new Set();
627
+ }
628
+ determinant.sectionDependents.add(node.value.label);
629
+ break;
630
+ default:
631
+ if (!determinant.fieldDependents) {
632
+ determinant.fieldDependents = new Set();
633
+ }
634
+ determinant.fieldDependents.add(node.value['id']);
635
+ }
636
+ }