sdc-qrf 0.2.0 → 0.3.2

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 (176) hide show
  1. package/lib/components.d.ts +3 -3
  2. package/lib/components.js +40 -22
  3. package/lib/components.js.map +1 -1
  4. package/lib/context.d.ts +0 -1
  5. package/lib/converter/extensions.d.ts +36 -0
  6. package/lib/converter/extensions.js +132 -0
  7. package/lib/converter/extensions.js.map +1 -0
  8. package/lib/converter/fceToFhir/index.d.ts +4 -0
  9. package/lib/converter/fceToFhir/index.js +15 -0
  10. package/lib/converter/fceToFhir/index.js.map +1 -0
  11. package/lib/converter/fceToFhir/questionnaire/index.d.ts +3 -0
  12. package/lib/converter/fceToFhir/questionnaire/index.js +17 -0
  13. package/lib/converter/fceToFhir/questionnaire/index.js.map +1 -0
  14. package/lib/converter/fceToFhir/questionnaire/processExtensions.d.ts +3 -0
  15. package/lib/converter/fceToFhir/questionnaire/processExtensions.js +61 -0
  16. package/lib/converter/fceToFhir/questionnaire/processExtensions.js.map +1 -0
  17. package/lib/converter/fceToFhir/questionnaire/processItems.d.ts +3 -0
  18. package/lib/converter/fceToFhir/questionnaire/processItems.js +144 -0
  19. package/lib/converter/fceToFhir/questionnaire/processItems.js.map +1 -0
  20. package/lib/converter/fceToFhir/questionnaire/processMeta.d.ts +3 -0
  21. package/lib/converter/fceToFhir/questionnaire/processMeta.js +20 -0
  22. package/lib/converter/fceToFhir/questionnaire/processMeta.js.map +1 -0
  23. package/lib/converter/fceToFhir/questionnaireResponse/index.d.ts +3 -0
  24. package/lib/converter/fceToFhir/questionnaireResponse/index.js +20 -0
  25. package/lib/converter/fceToFhir/questionnaireResponse/index.js.map +1 -0
  26. package/lib/converter/fceToFhir/questionnaireResponse/processAnswers.d.ts +2 -0
  27. package/lib/converter/fceToFhir/questionnaireResponse/processAnswers.js +48 -0
  28. package/lib/converter/fceToFhir/questionnaireResponse/processAnswers.js.map +1 -0
  29. package/lib/converter/fceToFhir/questionnaireResponse/processMeta.d.ts +3 -0
  30. package/lib/converter/fceToFhir/questionnaireResponse/processMeta.js +18 -0
  31. package/lib/converter/fceToFhir/questionnaireResponse/processMeta.js.map +1 -0
  32. package/lib/converter/fceToFhir/questionnaireResponse/processReference.d.ts +3 -0
  33. package/lib/converter/fceToFhir/questionnaireResponse/processReference.js +19 -0
  34. package/lib/converter/fceToFhir/questionnaireResponse/processReference.js.map +1 -0
  35. package/lib/converter/fhirToFce/index.d.ts +4 -0
  36. package/lib/converter/fhirToFce/index.js +15 -0
  37. package/lib/converter/fhirToFce/index.js.map +1 -0
  38. package/lib/converter/fhirToFce/questionnaire/index.d.ts +3 -0
  39. package/lib/converter/fhirToFce/questionnaire/index.js +21 -0
  40. package/lib/converter/fhirToFce/questionnaire/index.js.map +1 -0
  41. package/lib/converter/fhirToFce/questionnaire/processExtensions.d.ts +8 -0
  42. package/lib/converter/fhirToFce/questionnaire/processExtensions.js +89 -0
  43. package/lib/converter/fhirToFce/questionnaire/processExtensions.js.map +1 -0
  44. package/lib/converter/fhirToFce/questionnaire/processItems.d.ts +3 -0
  45. package/lib/converter/fhirToFce/questionnaire/processItems.js +131 -0
  46. package/lib/converter/fhirToFce/questionnaire/processItems.js.map +1 -0
  47. package/lib/converter/fhirToFce/questionnaire/processMeta.d.ts +32 -0
  48. package/lib/converter/fhirToFce/questionnaire/processMeta.js +14 -0
  49. package/lib/converter/fhirToFce/questionnaire/processMeta.js.map +1 -0
  50. package/lib/converter/fhirToFce/questionnaireResponse/index.d.ts +3 -0
  51. package/lib/converter/fhirToFce/questionnaireResponse/index.js +20 -0
  52. package/lib/converter/fhirToFce/questionnaireResponse/index.js.map +1 -0
  53. package/lib/converter/fhirToFce/questionnaireResponse/processAnswers.d.ts +2 -0
  54. package/lib/converter/fhirToFce/questionnaireResponse/processAnswers.js +46 -0
  55. package/lib/converter/fhirToFce/questionnaireResponse/processAnswers.js.map +1 -0
  56. package/lib/converter/fhirToFce/questionnaireResponse/processMeta.d.ts +3 -0
  57. package/lib/converter/fhirToFce/questionnaireResponse/processMeta.js +15 -0
  58. package/lib/converter/fhirToFce/questionnaireResponse/processMeta.js.map +1 -0
  59. package/lib/converter/fhirToFce/questionnaireResponse/processReference.d.ts +3 -0
  60. package/lib/converter/fhirToFce/questionnaireResponse/processReference.js +18 -0
  61. package/lib/converter/fhirToFce/questionnaireResponse/processReference.js.map +1 -0
  62. package/lib/converter/fhirToFce/utils.d.ts +3 -0
  63. package/lib/converter/fhirToFce/utils.js +37 -0
  64. package/lib/converter/fhirToFce/utils.js.map +1 -0
  65. package/lib/converter/index.d.ts +12 -0
  66. package/lib/converter/index.js +84 -0
  67. package/lib/converter/index.js.map +1 -0
  68. package/lib/index.d.ts +1 -0
  69. package/lib/index.js +1 -0
  70. package/lib/index.js.map +1 -1
  71. package/lib/setupTests.d.ts +1 -0
  72. package/lib/setupTests.js +4 -0
  73. package/lib/setupTests.js.map +1 -0
  74. package/lib/types.d.ts +10 -10
  75. package/lib/utils.d.ts +4 -1
  76. package/lib/utils.js +24 -11
  77. package/lib/utils.js.map +1 -1
  78. package/package.json +4 -5
  79. package/src/components.tsx +67 -29
  80. package/src/converter/__tests__/fce.test.ts +224 -0
  81. package/src/converter/__tests__/resources/questionnaire_fce/allergies.json +405 -0
  82. package/src/converter/__tests__/resources/questionnaire_fce/beverages.json +72 -0
  83. package/src/converter/__tests__/resources/questionnaire_fce/choice_answer_option.json +53 -0
  84. package/src/converter/__tests__/resources/questionnaire_fce/consent.json +86 -0
  85. package/src/converter/__tests__/resources/questionnaire_fce/enable_when.json +103 -0
  86. package/src/converter/__tests__/resources/questionnaire_fce/encounter_create.json +126 -0
  87. package/src/converter/__tests__/resources/questionnaire_fce/gad_7.json +459 -0
  88. package/src/converter/__tests__/resources/questionnaire_fce/immunization.json +182 -0
  89. package/src/converter/__tests__/resources/questionnaire_fce/medication.json +189 -0
  90. package/src/converter/__tests__/resources/questionnaire_fce/multiple_type_launch_context.json +406 -0
  91. package/src/converter/__tests__/resources/questionnaire_fce/patient_create.json +84 -0
  92. package/src/converter/__tests__/resources/questionnaire_fce/patient_edit.json +125 -0
  93. package/src/converter/__tests__/resources/questionnaire_fce/phq_2_phq_9.json +552 -0
  94. package/src/converter/__tests__/resources/questionnaire_fce/physicalexam.json +385 -0
  95. package/src/converter/__tests__/resources/questionnaire_fce/practitioner_create.json +90 -0
  96. package/src/converter/__tests__/resources/questionnaire_fce/practitioner_create_structure_map.json +91 -0
  97. package/src/converter/__tests__/resources/questionnaire_fce/practitioner_edit.json +144 -0
  98. package/src/converter/__tests__/resources/questionnaire_fce/practitioner_role_create.json +37 -0
  99. package/src/converter/__tests__/resources/questionnaire_fce/public_appointment.json +91 -0
  100. package/src/converter/__tests__/resources/questionnaire_fce/review_of_systems.json +389 -0
  101. package/src/converter/__tests__/resources/questionnaire_fce/source_queries.json +34 -0
  102. package/src/converter/__tests__/resources/questionnaire_fce/vitals.json +234 -0
  103. package/src/converter/__tests__/resources/questionnaire_fhir/allergies.json +433 -0
  104. package/src/converter/__tests__/resources/questionnaire_fhir/beverages.json +99 -0
  105. package/src/converter/__tests__/resources/questionnaire_fhir/choice_answer_option.json +49 -0
  106. package/src/converter/__tests__/resources/questionnaire_fhir/consent.json +119 -0
  107. package/src/converter/__tests__/resources/questionnaire_fhir/enable_when.json +87 -0
  108. package/src/converter/__tests__/resources/questionnaire_fhir/encounter_create.json +171 -0
  109. package/src/converter/__tests__/resources/questionnaire_fhir/gad_7.json +489 -0
  110. package/src/converter/__tests__/resources/questionnaire_fhir/immunization.json +215 -0
  111. package/src/converter/__tests__/resources/questionnaire_fhir/medication.json +226 -0
  112. package/src/converter/__tests__/resources/questionnaire_fhir/multiple_type_launch_context.json +416 -0
  113. package/src/converter/__tests__/resources/questionnaire_fhir/patient_create.json +97 -0
  114. package/src/converter/__tests__/resources/questionnaire_fhir/patient_edit.json +183 -0
  115. package/src/converter/__tests__/resources/questionnaire_fhir/phq_2_phq_9.json +580 -0
  116. package/src/converter/__tests__/resources/questionnaire_fhir/physicalexam.json +544 -0
  117. package/src/converter/__tests__/resources/questionnaire_fhir/practitioner_create.json +87 -0
  118. package/src/converter/__tests__/resources/questionnaire_fhir/practitioner_create_structure_map.json +91 -0
  119. package/src/converter/__tests__/resources/questionnaire_fhir/practitioner_edit.json +193 -0
  120. package/src/converter/__tests__/resources/questionnaire_fhir/practitioner_role_create.json +44 -0
  121. package/src/converter/__tests__/resources/questionnaire_fhir/public_appointment.json +116 -0
  122. package/src/converter/__tests__/resources/questionnaire_fhir/review_of_systems.json +368 -0
  123. package/src/converter/__tests__/resources/questionnaire_fhir/source_queries.json +37 -0
  124. package/src/converter/__tests__/resources/questionnaire_fhir/vitals.json +317 -0
  125. package/src/converter/__tests__/resources/questionnaire_response_fce/allergies_inprogress.json +78 -0
  126. package/src/converter/__tests__/resources/questionnaire_response_fce/cardiology.json +96 -0
  127. package/src/converter/__tests__/resources/questionnaire_response_fce/few_answers.json +48 -0
  128. package/src/converter/__tests__/resources/questionnaire_response_fce/gad_7.json +165 -0
  129. package/src/converter/__tests__/resources/questionnaire_response_fce/immunization.json +86 -0
  130. package/src/converter/__tests__/resources/questionnaire_response_fce/medication.json +116 -0
  131. package/src/converter/__tests__/resources/questionnaire_response_fce/new_appointment.json +96 -0
  132. package/src/converter/__tests__/resources/questionnaire_response_fce/patient.json +87 -0
  133. package/src/converter/__tests__/resources/questionnaire_response_fce/phq_2_phq_9.json +193 -0
  134. package/src/converter/__tests__/resources/questionnaire_response_fce/physicalexam.json +187 -0
  135. package/src/converter/__tests__/resources/questionnaire_response_fce/practitioner.json +57 -0
  136. package/src/converter/__tests__/resources/questionnaire_response_fce/reference_answer_with_assoc.json +147 -0
  137. package/src/converter/__tests__/resources/questionnaire_response_fce/review_of_systems.json +129 -0
  138. package/src/converter/__tests__/resources/questionnaire_response_fce/vitals.json +168 -0
  139. package/src/converter/__tests__/resources/questionnaire_response_fhir/allergies_inprogress.json +73 -0
  140. package/src/converter/__tests__/resources/questionnaire_response_fhir/cardiology.json +87 -0
  141. package/src/converter/__tests__/resources/questionnaire_response_fhir/few_answers.json +46 -0
  142. package/src/converter/__tests__/resources/questionnaire_response_fhir/gad_7.json +146 -0
  143. package/src/converter/__tests__/resources/questionnaire_response_fhir/immunization.json +77 -0
  144. package/src/converter/__tests__/resources/questionnaire_response_fhir/medication.json +101 -0
  145. package/src/converter/__tests__/resources/questionnaire_response_fhir/new_appointment.json +86 -0
  146. package/src/converter/__tests__/resources/questionnaire_response_fhir/patient.json +78 -0
  147. package/src/converter/__tests__/resources/questionnaire_response_fhir/phq_2_phq_9.json +170 -0
  148. package/src/converter/__tests__/resources/questionnaire_response_fhir/physicalexam.json +158 -0
  149. package/src/converter/__tests__/resources/questionnaire_response_fhir/practitioner.json +54 -0
  150. package/src/converter/__tests__/resources/questionnaire_response_fhir/reference_answer_with_assoc.json +86 -0
  151. package/src/converter/__tests__/resources/questionnaire_response_fhir/review_of_systems.json +118 -0
  152. package/src/converter/__tests__/resources/questionnaire_response_fhir/vitals.json +145 -0
  153. package/src/converter/extensions.ts +153 -0
  154. package/src/converter/fceToFhir/index.ts +27 -0
  155. package/src/converter/fceToFhir/questionnaire/index.ts +15 -0
  156. package/src/converter/fceToFhir/questionnaire/processExtensions.ts +75 -0
  157. package/src/converter/fceToFhir/questionnaire/processItems.ts +194 -0
  158. package/src/converter/fceToFhir/questionnaire/processMeta.ts +19 -0
  159. package/src/converter/fceToFhir/questionnaireResponse/index.ts +21 -0
  160. package/src/converter/fceToFhir/questionnaireResponse/processAnswers.ts +53 -0
  161. package/src/converter/fceToFhir/questionnaireResponse/processMeta.ts +16 -0
  162. package/src/converter/fceToFhir/questionnaireResponse/processReference.ts +24 -0
  163. package/src/converter/fhirToFce/index.ts +27 -0
  164. package/src/converter/fhirToFce/questionnaire/index.ts +25 -0
  165. package/src/converter/fhirToFce/questionnaire/processExtensions.ts +113 -0
  166. package/src/converter/fhirToFce/questionnaire/processItems.ts +159 -0
  167. package/src/converter/fhirToFce/questionnaire/processMeta.ts +17 -0
  168. package/src/converter/fhirToFce/questionnaireResponse/index.ts +21 -0
  169. package/src/converter/fhirToFce/questionnaireResponse/processAnswers.ts +53 -0
  170. package/src/converter/fhirToFce/questionnaireResponse/processMeta.ts +14 -0
  171. package/src/converter/fhirToFce/questionnaireResponse/processReference.ts +20 -0
  172. package/src/converter/fhirToFce/utils.ts +36 -0
  173. package/src/converter/index.ts +106 -0
  174. package/src/index.ts +1 -0
  175. package/src/setupTests.ts +1 -0
  176. package/src/utils.ts +50 -25
@@ -0,0 +1,21 @@
1
+ import { QuestionnaireResponse as FHIRQuestionnaireResponse } from 'fhir/r4b';
2
+ import cloneDeep from 'lodash/cloneDeep';
3
+
4
+ import { QuestionnaireResponse as FCEQuestionnaireResponse } from 'shared/src/contrib/aidbox';
5
+
6
+ import { processAnswers } from './processAnswers';
7
+ import { processMeta } from './processMeta';
8
+ import { processReference } from './processReference';
9
+
10
+ export function convertQuestionnaireResponse(
11
+ questionnaireResponse: FHIRQuestionnaireResponse,
12
+ ): FCEQuestionnaireResponse {
13
+ questionnaireResponse = cloneDeep(questionnaireResponse);
14
+ if (questionnaireResponse.item) {
15
+ processAnswers(questionnaireResponse.item);
16
+ }
17
+ if (questionnaireResponse.meta) {
18
+ questionnaireResponse.meta = processMeta(questionnaireResponse.meta);
19
+ }
20
+ return processReference(questionnaireResponse);
21
+ }
@@ -0,0 +1,53 @@
1
+ import {
2
+ Coding as FHIRCoding,
3
+ QuestionnaireResponseItem as FHIRQuestionnaireResponseItem,
4
+ QuestionnaireResponseItemAnswer as FHIRQuestionnaireResponseItemAnswer,
5
+ Reference as FHIRReference,
6
+ } from 'fhir/r4b';
7
+ import isEmpty from 'lodash/isEmpty';
8
+
9
+ import { QuestionnaireResponseItemAnswer as FCEQuestionnaireResponseItemAnswer } from 'shared/src/contrib/aidbox';
10
+
11
+ import { fromFHIRReference } from '../../../converter';
12
+
13
+ export function processAnswers(items: FHIRQuestionnaireResponseItem[]) {
14
+ if (!items) {
15
+ return;
16
+ }
17
+ for (const item of items) {
18
+ if (item.answer) {
19
+ item.answer = item.answer.map(processAnswer).filter((answer) => !isEmpty(answer));
20
+ }
21
+ if (item.item) {
22
+ processAnswers(item.item);
23
+ }
24
+ }
25
+ }
26
+
27
+ function processAnswer(
28
+ answer: FHIRQuestionnaireResponseItemAnswer,
29
+ ): FCEQuestionnaireResponseItemAnswer {
30
+ const fceAnswer: FCEQuestionnaireResponseItemAnswer = { ...answer };
31
+ const valueHandlers = {
32
+ valueString: (value: string) => ({ string: value }),
33
+ valueInteger: (value: number) => ({ integer: value }),
34
+ valueDecimal: (value: number) => ({ decimal: value }),
35
+ valueBoolean: (value: boolean) => ({ boolean: value }),
36
+ valueCoding: (value: FHIRCoding) => ({ Coding: value }),
37
+ valueDate: (value: string) => ({ date: value }),
38
+ valueDateTime: (value: string) => ({ dateTime: value }),
39
+ valueReference: (value: FHIRReference) => ({
40
+ Reference: fromFHIRReference(value),
41
+ }),
42
+ valueTime: (value: string) => ({ time: value }),
43
+ };
44
+
45
+ for (const key in valueHandlers) {
46
+ if (key in fceAnswer) {
47
+ const value = fceAnswer[key];
48
+ delete fceAnswer[key];
49
+ fceAnswer.value = valueHandlers[key]?.(value);
50
+ }
51
+ }
52
+ return fceAnswer;
53
+ }
@@ -0,0 +1,14 @@
1
+ import { Meta as FHIRMeta } from 'fhir/r4b';
2
+
3
+ import { Meta as FCEMeta } from 'shared/src/contrib/aidbox';
4
+
5
+ import { extractExtension } from '../../../converter';
6
+
7
+ export function processMeta(meta: FHIRMeta): FCEMeta {
8
+ const { extension, ...commonMeta } = meta;
9
+ const fceMeta: FCEMeta = { ...commonMeta };
10
+ if (extension) {
11
+ fceMeta.createdAt = extractExtension(extension, 'ex:createdAt');
12
+ }
13
+ return fceMeta;
14
+ }
@@ -0,0 +1,20 @@
1
+ import { QuestionnaireResponse as FHIRQuestionnaireResponse } from 'fhir/r4b';
2
+
3
+ import { QuestionnaireResponse as FCEQuestionnaireResponse } from 'shared/src/contrib/aidbox';
4
+
5
+ import { fromFHIRReference } from '../../../converter';
6
+
7
+ export function processReference(
8
+ fhirQuestionnaireResponse: FHIRQuestionnaireResponse,
9
+ ): FCEQuestionnaireResponse {
10
+ const { encounter, source, ...commonProperties } = fhirQuestionnaireResponse;
11
+ const fceQuestionnaireResponse: FCEQuestionnaireResponse =
12
+ commonProperties as FCEQuestionnaireResponse;
13
+ if (encounter?.reference) {
14
+ fceQuestionnaireResponse.encounter = fromFHIRReference(encounter);
15
+ }
16
+ if (source?.reference) {
17
+ fceQuestionnaireResponse.source = fromFHIRReference(source);
18
+ }
19
+ return fceQuestionnaireResponse;
20
+ }
@@ -0,0 +1,36 @@
1
+ import { Questionnaire as FHIRQuestionnaire } from 'fhir/r4b';
2
+
3
+ export function checkFhirQuestionnaireProfile(fhirQuestionnaire: FHIRQuestionnaire): void {
4
+ if (
5
+ !(
6
+ (fhirQuestionnaire.meta?.profile?.length ?? 0) === 1 &&
7
+ fhirQuestionnaire.meta?.profile?.[0] === 'https://beda.software/beda-emr-questionnaire'
8
+ )
9
+ ) {
10
+ throw new Error('Only beda emr questionanire supported');
11
+ }
12
+ }
13
+
14
+ export function trimUndefined(e: any) {
15
+ for (const prop in e) {
16
+ // eslint-disable-next-line no-prototype-builtins
17
+ if (e.hasOwnProperty(prop)) {
18
+ const val = e[prop];
19
+ if (val === undefined) {
20
+ delete e[prop];
21
+ } else if (typeof val === 'object') {
22
+ if (Array.isArray(val)) {
23
+ for (let i = 0; i < val.length; i++) {
24
+ if (typeof val[i] === 'object') {
25
+ trimUndefined(val[i]);
26
+ }
27
+ }
28
+ } else {
29
+ trimUndefined(val);
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ return e;
36
+ }
@@ -0,0 +1,106 @@
1
+ import {
2
+ Reference as FHIRReference,
3
+ Extension as FHIRExtension,
4
+ QuestionnaireItem as FHIRQuestionnaireItem,
5
+ } from 'fhir/r4b';
6
+
7
+ import {
8
+ Extension as FCEExtension,
9
+ QuestionnaireItem as FCEQuestionnaireItem,
10
+ InternalReference,
11
+ } from 'shared/src/contrib/aidbox';
12
+
13
+ import { ExtensionIdentifier, extensionTransformers } from './extensions';
14
+ import { fromFirstClassExtension } from './fceToFhir';
15
+ import { toFirstClassExtension } from './fhirToFce';
16
+ import { processLaunchContext as processLaunchContextToFce } from './fhirToFce/questionnaire/processExtensions';
17
+
18
+ export function convertFromFHIRExtension(
19
+ extension: FHIRExtension,
20
+ ): Partial<FCEQuestionnaireItem> | undefined {
21
+ const identifier = extension.url;
22
+ const transformer = extensionTransformers[identifier as ExtensionIdentifier];
23
+ if (transformer !== undefined) {
24
+ if ('transform' in transformer) {
25
+ return transformer.transform.fromExtension(extension);
26
+ } else {
27
+ return { [transformer.path.questionnaire]: extension[transformer.path.extension] };
28
+ }
29
+ }
30
+ }
31
+
32
+ export function convertToFHIRExtension(item: FCEQuestionnaireItem): FHIRExtension[] {
33
+ const extensions: FHIRExtension[] = [];
34
+ for (const identifer in ExtensionIdentifier) {
35
+ const transformer =
36
+ extensionTransformers[ExtensionIdentifier[identifer] as ExtensionIdentifier];
37
+ if ('transform' in transformer) {
38
+ const extension = transformer.transform.toExtension(item);
39
+ if (extension !== undefined) {
40
+ extensions.push(extension);
41
+ }
42
+ } else {
43
+ const extensionValue = item[transformer.path.questionnaire];
44
+ if (extensionValue !== undefined) {
45
+ const extension: FHIRExtension = {
46
+ [transformer.path.extension]: extensionValue,
47
+ url: ExtensionIdentifier[identifer],
48
+ };
49
+ extensions.push(extension);
50
+ }
51
+ }
52
+ }
53
+ return extensions;
54
+ }
55
+
56
+ export function extractExtension(extension: FCEExtension[] | undefined, url: 'ex:createdAt') {
57
+ return extension?.find((e) => e.url === url)?.valueInstant;
58
+ }
59
+
60
+ export function findExtension(item: FHIRQuestionnaireItem, url: string) {
61
+ return item.extension?.find((ext) => ext.url === url);
62
+ }
63
+
64
+ export function fromFHIRReference(r?: FHIRReference): InternalReference | undefined {
65
+ if (!r || !r.reference) {
66
+ return undefined;
67
+ }
68
+
69
+ const { reference: literalReference, ...commonReferenceProperties } = r;
70
+ const isHistoryVersionLink = r.reference.split('/').slice(-2, -1)[0] === '_history';
71
+
72
+ if (isHistoryVersionLink) {
73
+ const [, , id, resourceType] = r.reference.split('/').reverse();
74
+
75
+ return {
76
+ ...commonReferenceProperties,
77
+ id: id!,
78
+ resourceType,
79
+ };
80
+ } else {
81
+ const [id, resourceType] = r.reference.split('/').reverse();
82
+
83
+ return {
84
+ ...commonReferenceProperties,
85
+ id: id!,
86
+ resourceType,
87
+ };
88
+ }
89
+ }
90
+
91
+ export function toFHIRReference(r?: InternalReference): FHIRReference | undefined {
92
+ if (!r) {
93
+ return undefined;
94
+ }
95
+
96
+ const { id, resourceType, ...commonReferenceProperties } = r;
97
+
98
+ delete commonReferenceProperties.resource;
99
+
100
+ return {
101
+ ...commonReferenceProperties,
102
+ reference: `${resourceType}/${id}`,
103
+ };
104
+ }
105
+
106
+ export { toFirstClassExtension, fromFirstClassExtension, processLaunchContextToFce };
package/src/index.ts CHANGED
@@ -2,3 +2,4 @@ export * from './types';
2
2
  export * from './utils';
3
3
  export * from './hooks';
4
4
  export * from './components';
5
+ export * from './converter';
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/extend-expect';
package/src/utils.ts CHANGED
@@ -110,15 +110,25 @@ export function calcContext(
110
110
  qrItem: QuestionnaireResponseItem,
111
111
  ): ItemContext {
112
112
  // TODO: add root variable support
113
- return {
114
- ...(variables || []).reduce(
115
- (acc, curVariable) => ({
116
- ...acc,
117
- [curVariable.name!]: fhirpath.evaluate(qrItem || {}, curVariable.expression!, acc),
118
- }),
119
- { ...initialContext, context: qrItem, qitem: qItem },
120
- ),
121
- };
113
+ try {
114
+ return {
115
+ ...(variables || []).reduce(
116
+ (acc, curVariable) => ({
117
+ ...acc,
118
+ [curVariable.name!]: fhirpath.evaluate(
119
+ qrItem || {},
120
+ curVariable.expression!,
121
+ acc,
122
+ ),
123
+ }),
124
+ { ...initialContext, context: qrItem, qitem: qItem },
125
+ ),
126
+ };
127
+ } catch (err: unknown) {
128
+ throw Error(
129
+ `FHIRPath expression evaluation failure for "variable" in ${qItem.linkId}: ${err}`,
130
+ );
131
+ }
122
132
  }
123
133
 
124
134
  export function compareValue(firstAnswerValue: AnswerValue, secondAnswerValue: AnswerValue) {
@@ -319,7 +329,7 @@ export function mapResponseToForm(resource: QuestionnaireResponse, questionnaire
319
329
  }
320
330
 
321
331
  function initialToQuestionnaireResponseItemAnswer(initial: QuestionnaireItemInitial[] | undefined) {
322
- return (initial ?? []).map(({ value }) => ({ value } as QuestionnaireResponseItemAnswer));
332
+ return (initial ?? []).map(({ value }) => ({ value }) as QuestionnaireResponseItemAnswer);
323
333
  }
324
334
 
325
335
  export function findAnswersForQuestionsRecursive(linkId: string, values?: FormItems): any | null {
@@ -433,7 +443,8 @@ export function getChecker(
433
443
  return (values, answerValue) => {
434
444
  const answersLength = _.reject(
435
445
  values,
436
- (value) => _.isEmpty(value.value) || _.every(_.mapValues(value.value, _.isEmpty)),
446
+ (value) =>
447
+ isValueEmpty(value.value) || _.every(_.mapValues(value.value, isValueEmpty)),
437
448
  ).length;
438
449
  const answer = answerValue?.boolean ?? true;
439
450
  return answersLength > 0 === answer;
@@ -500,21 +511,25 @@ function isQuestionEnabled(args: IsQuestionEnabledArgs) {
500
511
  }
501
512
 
502
513
  if (enableWhenExpression && enableWhenExpression.language === 'text/fhirpath') {
503
- const expressionResult = fhirpath.evaluate(
504
- args.context.resource,
505
- enableWhenExpression.expression!,
506
- args.context ?? {},
507
- )[0];
508
-
509
- if (typeof expressionResult !== 'boolean') {
510
- throw Error(`
511
- linkId: ${args.qItem.linkId}
512
- Expression result: ${expressionResult}
513
- The result of enableWhenExpression is not a boolean value
514
- `);
515
- }
514
+ try {
515
+ const expressionResult = fhirpath.evaluate(
516
+ args.context.resource,
517
+ enableWhenExpression.expression!,
518
+ args.context ?? {},
519
+ )[0];
520
+
521
+ if (typeof expressionResult !== 'boolean') {
522
+ throw Error(
523
+ `The result of enableWhenExpression is not a boolean value. Expression result: ${expressionResult}`,
524
+ );
525
+ }
516
526
 
517
- return expressionResult;
527
+ return expressionResult;
528
+ } catch (err: unknown) {
529
+ throw Error(
530
+ `FHIRPath expression evaluation failure for "enableWhenExpression" in ${args.qItem.linkId}: ${err}`,
531
+ );
532
+ }
518
533
  }
519
534
 
520
535
  const iterFn = enableBehavior === 'any' ? _.some : _.every;
@@ -738,3 +753,13 @@ export function parseFhirQueryExpression(expression: string, context: ItemContex
738
753
 
739
754
  return [resourceType, searchParams];
740
755
  }
756
+
757
+ export function isValueEmpty(value: any) {
758
+ if (_.isNaN(value)) {
759
+ console.warn(
760
+ 'Please be aware that a NaN value has been detected. In the context of an "exist" operator, a NaN value is interpreted as a non-existent value. This may lead to unexpected behavior in your code. Ensure to handle or correct this to maintain the integrity of your application.',
761
+ );
762
+ }
763
+
764
+ return _.isFinite(value) || _.isBoolean(value) ? false : _.isEmpty(value);
765
+ }