Repository: FHIR/sushi (ts)

Issue:
References to contained resources
If you run SUSHI on the following snippet of FSH:
```
Instance: Foo
InstanceOf: ServiceRequest
* contained = annexSR2
* supportingInfo = Reference(annexSR2)

Instance: annexSR2
InstanceOf: Binary
Usage: #inline
* contentType = #zip
```
The output JSON has `supportingInfo.reference` set to `Binary/annexSR2`. The IG Publisher issues errors in the QA report, because `Binary/annexSR2` cannot be resolved, since it is an inline defined contained resource, so it does not exist on its own. Instead, the reference should be set as `#annexSR2` to keep the IG Publisher happy.

Pull request description:
Fixing contained references
So #518 was supposed to fix #508, but in fixing it, it broke references to resources within a Bundle.

Now this fixes #508 without breaking references to any inline resource. The approach taken in this PR is specific to resources in the `contained` array. I couldn't figure out how to do it without post processing, and I don't really love post processing, so if you also don't love post processing and can think of a better way, please let me know.

Patch:
diff --git a/src/fhirtypes/common.ts b/src/fhirtypes/common.ts
index 5eaee8c..9e5164d 100644
--- a/src/fhirtypes/common.ts
+++ b/src/fhirtypes/common.ts
@@ -248,7 +248,7 @@ export function replaceReferences(
       const id = idRule?.fixedValue ?? instance.id;
       clone = cloneDeep(rule);
       const fv = clone.fixedValue as FshReference;
-      fv.reference = instance.usage === 'Inline' ? `#${id}` : `${instanceMeta.sdType}/${id}`;
+      fv.reference = `${instanceMeta.sdType}/${id}`;
       fv.sdType = instanceMeta.sdType;
     }
   } else if (rule.fixedValue instanceof FshCode) {
@@ -328,6 +328,17 @@ export function cleanResource(
     (o, p) => (o[p] = o[p].fixedValue),
     skipFn
   );
+
+  // Update references to any contained resources to be #id instead of resourceType/id
+  resourceDef.contained?.forEach((containedResource: any) => {
+    const referenceString = `${containedResource.resourceType}/${containedResource.id}`;
+    replaceField(
+      resourceDef,
+      (o, p) => o[p] === referenceString,
+      (o, p) => (o[p] = `#${containedResource.id}`),
+      skipFn
+    );
+  });
 }
 
 /**


Test patch:
diff --git a/test/export/InstanceExporter.test.ts b/test/export/InstanceExporter.test.ts
index 313a6bd..ac19354 100644
--- a/test/export/InstanceExporter.test.ts
+++ b/test/export/InstanceExporter.test.ts
@@ -1043,16 +1043,18 @@ describe('InstanceExporter', () => {
       });
     });
 
-    it('should fix an inline reference while resolving the Instance being referred to', () => {
+    it('should fix a reference to a contained resource using a relative reference', () => {
       const orgInstance = new Instance('TestOrganization');
       orgInstance.instanceOf = 'Organization';
-      orgInstance.usage = 'Inline';
       const fixedIdRule = new FixedValueRule('id');
       fixedIdRule.fixedValue = 'org-id';
       orgInstance.rules.push(fixedIdRule);
+      const containedRule = new FixedValueRule('contained');
+      containedRule.fixedValue = 'TestOrganization';
+      containedRule.isInstance = true;
       const fixedRefRule = new FixedValueRule('managingOrganization');
       fixedRefRule.fixedValue = new FshReference('TestOrganization');
-      patientInstance.rules.push(fixedRefRule);
+      patientInstance.rules.push(containedRule, fixedRefRule);
       doc.instances.set(patientInstance.name, patientInstance);
       doc.instances.set(orgInstance.name, orgInstance);
       const exported = exportInstance(patientInstance);
diff --git a/test/export/StructureDefinitionExporter.test.ts b/test/export/StructureDefinitionExporter.test.ts
index 771d7a7..e5869d2 100644
--- a/test/export/StructureDefinitionExporter.test.ts
+++ b/test/export/StructureDefinitionExporter.test.ts
@@ -1501,30 +1501,6 @@ describe('StructureDefinitionExporter', () => {
     });
   });
 
-  it('should apply a Reference FixedValueRule and replace the Reference to an inline instance', () => {
-    const profile = new Profile('Foo');
-    profile.parent = 'Observation';
-
-    const instance = new Instance('Bar');
-    instance.id = 'bar-id';
-    instance.instanceOf = 'Patient';
-    instance.usage = 'Inline';
-    doc.instances.set(instance.name, instance);
-
-    const rule = new FixedValueRule('subject');
-    rule.fixedValue = new FshReference('Bar');
-    profile.rules.push(rule);
-
-    exporter.exportStructDef(profile);
-    const sd = pkg.profiles[0];
-
-    const fixedSubject = sd.findElement('Observation.subject');
-
-    expect(fixedSubject.patternReference).toEqual({
-      reference: '#bar-id'
-    });
-  });
-
   it('should not apply a Reference FixedValueRule with invalid type and log an error', () => {
     const profile = new Profile('Foo');
     profile.parent = 'Observation';