Repository: FHIR/sushi
Pull request #1493 (2024-07-16 11:11:19)

Valueset versioned caret rules
**Description:**
added the version to the check in ValueSetExporter and added a new test case

**Related Issue:**
Fixes https://github.com/FHIR/sushi/issues/1492




Patch:
diff --git a/src/export/ValueSetExporter.ts b/src/export/ValueSetExporter.ts
index 4e74631..e27ca9e 100644
--- a/src/export/ValueSetExporter.ts
+++ b/src/export/ValueSetExporter.ts
@@ -298,11 +298,16 @@ export class ValueSetExporter {
     for (const rule of rules) {
       const splitConcept = rule.pathArray[0].split('#');
       const system = splitConcept[0];
+      const baseSystem = system?.split('|')[0];
+      const version = system?.split('|')[1];
       const code = splitConcept.slice(1).join('#');
-      const systemMeta = this.fisher.fishForMetadata(system, Type.CodeSystem);
+      const systemMeta = this.fisher.fishForMetadata(baseSystem, Type.CodeSystem);
       let composeIndex =
         vs.compose?.include?.findIndex(composeElement => {
-          return composeElement.system === system || composeElement.system === systemMeta?.url;
+          return (
+            (composeElement.system === baseSystem && composeElement.version === version) ||
+            (composeElement.system === systemMeta?.url && composeElement.version === version)
+          );
         }) ?? -1;
       let composeArray: string;
       let composeElement: ValueSetComposeIncludeOrExclude;
@@ -317,7 +322,7 @@ export class ValueSetExporter {
       if (conceptIndex === -1) {
         composeIndex =
           vs.compose?.exclude?.findIndex(composeElement => {
-            return composeElement.system === system;
+            return composeElement.system === baseSystem;
           }) ?? -1;
         if (composeIndex !== -1) {
           composeArray = 'exclude';


Test patch:
diff --git a/test/export/ValueSetExporter.test.ts b/test/export/ValueSetExporter.test.ts
index 3a7793b..b6f9a35 100644
--- a/test/export/ValueSetExporter.test.ts
+++ b/test/export/ValueSetExporter.test.ts
@@ -2269,6 +2269,65 @@ describe('ValueSetExporter', () => {
     expect(loggerSpy.getLastMessage('error')).toMatch(/File: ValueSet\.fsh.*Line: 4\D*/s);
   });
 
+  it('should not throw an error when caret rules are applied to a code from a specific version of a codeSystem', () => {
+    const valueSet = new FshValueSet('DinnerVS');
+    const unversionedComponent = new ValueSetConceptComponentRule(true);
+    unversionedComponent.from = { system: 'http://food.org/food' };
+    unversionedComponent.concepts.push(
+      new FshCode('Pizza', 'http://food.org/food', 'Delicious pizza to share.')
+    );
+    const versionComponent = new ValueSetConceptComponentRule(true);
+    versionComponent.from = { system: 'http://food.org/food|2.0.1' };
+    versionComponent.concepts.push(
+      new FshCode('Salad', 'http://food.org/food|2.0.1', 'Plenty of fresh vegetables.')
+    );
+    const designationValue = new CaretValueRule('');
+    designationValue.caretPath = 'designation.value';
+    designationValue.pathArray = ['http://food.org/food|2.0.1#Salad'];
+    designationValue.value = 'Salat';
+    valueSet.rules.push(unversionedComponent, versionComponent, designationValue);
+    doc.valueSets.set(valueSet.name, valueSet);
+    const exported = exporter.export().valueSets;
+    expect(exported.length).toBe(1);
+    expect(exported[0]).toEqual({
+      resourceType: 'ValueSet',
+      id: 'DinnerVS',
+      name: 'DinnerVS',
+      url: 'http://hl7.org/fhir/us/minimal/ValueSet/DinnerVS',
+      status: 'draft',
+      compose: {
+        include: [
+          {
+            system: 'http://food.org/food',
+            concept: [
+              {
+                code: 'Pizza',
+                display: 'Delicious pizza to share.'
+              }
+            ]
+          },
+          {
+            system: 'http://food.org/food',
+            version: '2.0.1',
+            concept: [
+              {
+                code: 'Salad',
+                display: 'Plenty of fresh vegetables.',
+                designation: [
+                  {
+                    value: 'Salat'
+                  }
+                ]
+              }
+            ]
+          }
+        ]
+      }
+    });
+    expect(designationValue.isCodeCaretRule).toBeTrue();
+    expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
+  });
+
   describe('#insertRules', () => {
     let vs: FshValueSet;
     let ruleSet: RuleSet;