sdc-qrf 1.1.0-alpha.5 → 1.1.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sdc-qrf",
3
3
  "license": "MIT",
4
- "version": "1.1.0-alpha.5",
4
+ "version": "1.1.0-alpha.6",
5
5
  "scripts": {
6
6
  "test": "vitest --watch=false",
7
7
  "test:watch": "vitest --watch",
@@ -37,6 +37,7 @@ import fce_practitioner_create_structure_map from './resources/questionnaire_fce
37
37
  import fce_practitioner_edit from './resources/questionnaire_fce/practitioner_edit.json';
38
38
  import fce_practitioner_role_create from './resources/questionnaire_fce/practitioner_role_create.json';
39
39
  import fce_public_appointment from './resources/questionnaire_fce/public_appointment.json';
40
+ import fce_questionnaire_variable from './resources/questionnaire_fce/questionnaire_variable.json';
40
41
  import fce_review_of_systems from './resources/questionnaire_fce/review_of_systems.json';
41
42
  import fce_source_queries from './resources/questionnaire_fce/source_queries.json';
42
43
  import fce_sub_questionnaire from './resources/questionnaire_fce/sub-questionnaire.json';
@@ -81,6 +82,7 @@ import fhir_practitioner_create_structure_map from './resources/questionnaire_fh
81
82
  import fhir_practitioner_edit from './resources/questionnaire_fhir/practitioner_edit.json';
82
83
  import fhir_practitioner_role_create from './resources/questionnaire_fhir/practitioner_role_create.json';
83
84
  import fhir_public_appointment from './resources/questionnaire_fhir/public_appointment.json';
85
+ import fhir_questionnaire_variable from './resources/questionnaire_fhir/questionnaire_variable.json';
84
86
  import fhir_review_of_systems from './resources/questionnaire_fhir/review_of_systems.json';
85
87
  import fhir_source_queries from './resources/questionnaire_fhir/source_queries.json';
86
88
  import fhir_sub_questionnaire from './resources/questionnaire_fhir/sub-questionnaire.json';
@@ -128,6 +130,7 @@ describe('Questionanire and QuestionnaireResponses transformation', () => {
128
130
  ['answerOptionsToggleExpression', fhir_answer_options_toggle_expression, fce_answer_options_toggle_expression],
129
131
  ['unit-option', fhir_unit_option, fce_unit_option],
130
132
  ['variable', fhir_variable, fce_variable],
133
+ ['questionnaire-variable', fhir_questionnaire_variable, fce_questionnaire_variable],
131
134
  ['sub-questionnaire', fhir_sub_questionnaire, fce_sub_questionnaire],
132
135
  ['with-attachment-questionnaire', fhir_with_attachment_questionnaire, fce_with_attachment_questionnaire],
133
136
  // NOTE: this following is not included here because it's example of mixed FCE + extensions, it is only for FCE -> FHIR
@@ -180,6 +183,7 @@ describe('Questionanire and QuestionnaireResponses transformation', () => {
180
183
  ['answerOptionsToggleExpression', fce_answer_options_toggle_expression, fhir_answer_options_toggle_expression],
181
184
  ['unit-option', fce_unit_option, fhir_unit_option],
182
185
  ['variable', fce_variable, fhir_variable],
186
+ ['questionnaire-variable', fce_questionnaire_variable, fhir_questionnaire_variable],
183
187
  ['sub-questionnaire', fce_sub_questionnaire, fhir_sub_questionnaire],
184
188
  ['with-attachment-questionnaire', fce_with_attachment_questionnaire, fhir_with_attachment_questionnaire],
185
189
  ['mixed-fce-with-extensions', fce_mixed_fce_with_extensions, fhir_mixed_fce_with_extensions],
@@ -0,0 +1,28 @@
1
+ {
2
+ "resourceType": "Questionnaire",
3
+ "id": "questionnaire-variable",
4
+ "meta": {
5
+ "profile": [
6
+ "https://emr-core.beda.software/StructureDefinition/fhir-emr-questionnaire"
7
+ ]
8
+ },
9
+ "status": "active",
10
+ "variable": [
11
+ {
12
+ "name": "First",
13
+ "language": "text/fhirpath",
14
+ "expression": "'First'"
15
+ },
16
+ {
17
+ "name": "Second",
18
+ "language": "text/fhirpath",
19
+ "expression": "%First + 'Second'"
20
+ }
21
+ ],
22
+ "item": [
23
+ {
24
+ "type": "string",
25
+ "linkId": "test"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "item": [
3
+ {
4
+ "type": "string",
5
+ "linkId": "test"
6
+ }
7
+ ],
8
+ "meta": {
9
+ "profile": ["https://emr-core.beda.software/StructureDefinition/fhir-emr-questionnaire"]
10
+ },
11
+ "extension": [
12
+ {
13
+ "url": "http://hl7.org/fhir/StructureDefinition/variable",
14
+ "valueExpression": {
15
+ "name": "First",
16
+ "language": "text/fhirpath",
17
+ "expression": "'First'"
18
+ }
19
+ },
20
+ {
21
+ "url": "http://hl7.org/fhir/StructureDefinition/variable",
22
+ "valueExpression": {
23
+ "name": "Second",
24
+ "language": "text/fhirpath",
25
+ "expression": "%First + 'Second'"
26
+ }
27
+ }
28
+ ],
29
+ "status": "active",
30
+ "id": "questionnaire-variable",
31
+ "resourceType": "Questionnaire"
32
+ }
@@ -10,6 +10,7 @@ export function processExtensions(questionnaire: FCEQuestionnaire): FHIRQuestion
10
10
  assembledFrom,
11
11
  assembleContext,
12
12
  itemPopulationContext,
13
+ variable,
13
14
  ...fhirQuestionnaire
14
15
  } = questionnaire;
15
16
 
@@ -107,6 +108,15 @@ export function processExtensions(questionnaire: FCEQuestionnaire): FHIRQuestion
107
108
  });
108
109
  }
109
110
 
111
+ if (variable) {
112
+ extensions = extensions.concat(
113
+ variable.map((expr) => ({
114
+ url: 'http://hl7.org/fhir/StructureDefinition/variable',
115
+ valueExpression: expr,
116
+ })),
117
+ );
118
+ }
119
+
110
120
  if (extensions.length) {
111
121
  fhirQuestionnaire.extension = (fhirQuestionnaire.extension ?? []).concat(extensions);
112
122
  }
@@ -8,6 +8,7 @@ export function processExtensions(fhirQuestionnaire: FHIRQuestionnaire): {
8
8
  assembledFrom?: any;
9
9
  assembleContext?: string[];
10
10
  itemPopulationContext?: FHIRExpression;
11
+ variable?: FHIRExpression[];
11
12
  } {
12
13
  const launchContext = processLaunchContext(fhirQuestionnaire);
13
14
  const mapping = processMapping(fhirQuestionnaire);
@@ -16,6 +17,7 @@ export function processExtensions(fhirQuestionnaire: FHIRQuestionnaire): {
16
17
  const assembledFrom = processAssembledFrom(fhirQuestionnaire);
17
18
  const assembleContext = processAssembleContext(fhirQuestionnaire);
18
19
  const itemPopulationContext = processItemPopulationContext(fhirQuestionnaire);
20
+ const variable = processVariable(fhirQuestionnaire);
19
21
 
20
22
  return {
21
23
  launchContext: launchContext?.length ? launchContext : undefined,
@@ -25,6 +27,7 @@ export function processExtensions(fhirQuestionnaire: FHIRQuestionnaire): {
25
27
  assembledFrom: assembledFrom ? assembledFrom : undefined,
26
28
  assembleContext: assembleContext.length ? assembleContext : undefined,
27
29
  itemPopulationContext: itemPopulationContext ? itemPopulationContext : undefined,
30
+ variable: variable?.length ? variable : undefined,
28
31
  };
29
32
  }
30
33
 
@@ -141,3 +144,15 @@ function processItemPopulationContext(fhirQuestionnaire: FHIRQuestionnaire): FHI
141
144
 
142
145
  return extension.valueExpression;
143
146
  }
147
+
148
+ function processVariable(fhirQuestionnaire: FHIRQuestionnaire): FHIRExpression[] | undefined {
149
+ const extensions = fhirQuestionnaire.extension?.filter(
150
+ (ext) => ext.url === 'http://hl7.org/fhir/StructureDefinition/variable',
151
+ );
152
+
153
+ if (!extensions?.length) {
154
+ return undefined;
155
+ }
156
+
157
+ return extensions.map((ext) => ext.valueExpression!);
158
+ }
package/src/utils.ts CHANGED
@@ -729,13 +729,14 @@ export function getEnabledQuestions(
729
729
  export function calcInitialContext(
730
730
  qrfDataContext: QuestionnaireResponseFormData['context'],
731
731
  values: FormItems,
732
+ evaluateFhirpath?: EvaluateFhirpath,
732
733
  ): ItemContext {
733
734
  const questionnaireResponse = {
734
735
  ...qrfDataContext.questionnaireResponse,
735
736
  ...mapFormToResponse(values, qrfDataContext.questionnaire),
736
737
  };
737
738
 
738
- return {
739
+ const baseContext: ItemContext = {
739
740
  ...qrfDataContext.launchContextParameters.reduce((acc, { name, resource, ...param }) => {
740
741
  const value = getChoiceTypeValue(param, 'value');
741
742
 
@@ -754,6 +755,23 @@ export function calcInitialContext(
754
755
  Questionnaire: qrfDataContext.questionnaire,
755
756
  QuestionnaireResponse: questionnaireResponse,
756
757
  };
758
+
759
+ // Evaluate questionnaire-level FHIRPath variables in declaration order
760
+ return (qrfDataContext.fceQuestionnaire.variable ?? []).reduce((ctx: ItemContext, variable) => {
761
+ if (!variable?.name || !variable.expression || variable.language !== 'text/fhirpath') {
762
+ console.warn(`Only fhirpath variables are supported. Variable ${variable.name} is not supported.`);
763
+ return ctx;
764
+ }
765
+ return {
766
+ ...ctx,
767
+ [variable.name]: evaluateFHIRPathExpression(
768
+ variable,
769
+ ctx,
770
+ `questionnaire.variable.${variable.name}`,
771
+ evaluateFhirpath,
772
+ ),
773
+ };
774
+ }, baseContext);
757
775
  }
758
776
 
759
777
  export function resolveTemplateExpr(