Repository: FHIR/sushi (ts)

Issue:
SUSHI should automatically populate `url` for appropriate #definition instances
If an `Instance` has `Usage: #definition` and is a type that has a `url` field intended to represent the definition's canonical, then SUSHI should automatically set the `url` like it does for `Profile`, `Extension`, `CodeSystem`, and `ValueSet` definitions.  Otherwise the user must manually type in the full URL, which can be brittle if the overall canonical of the IG changes.

Pull request description:
Url property now set automatically on instance definitions
Fixes #791, making it so that SUSHI now sets the URL on instances with a `Usage: #definition` just as it does on other entities. You can see this in action with [this simple example](https://fshschool.org/FSHOnline/#/share/3mtrCzr). Running this in FSHOnline will not set the url automatically, but running this same example on this branch will set a url based on the canonical. An assignment rule explicitly setting the url will take precedence over the auto-generated URL.

Patch:
diff --git a/src/export/InstanceExporter.ts b/src/export/InstanceExporter.ts
index ec9291b..523d422 100644
--- a/src/export/InstanceExporter.ts
+++ b/src/export/InstanceExporter.ts
@@ -297,6 +297,14 @@ export class InstanceExporter implements Fishable {
     }
     if (fshDefinition.usage) {
       instanceDef._instanceMeta.usage = fshDefinition.usage;
+      if (
+        fshDefinition.usage === 'Definition' &&
+        instanceOfStructureDefinition.elements.some(
+          element => element.id === `${instanceOfStructureDefinition.type}.url`
+        )
+      ) {
+        instanceDef.url = `${this.tank.config.canonical}/${instanceOfStructureDefinition.type}/${fshDefinition.id}`;
+      }
     }
     if (isResource) {
       instanceDef.resourceType = instanceOfStructureDefinition.type; // ResourceType is determined by the StructureDefinition of the type


Test patch:
diff --git a/test/export/InstanceExporter.test.ts b/test/export/InstanceExporter.test.ts
index c0746ad..cb3c2f0 100644
--- a/test/export/InstanceExporter.test.ts
+++ b/test/export/InstanceExporter.test.ts
@@ -537,6 +537,35 @@ describe('InstanceExporter', () => {
       ]);
     });
 
+    it('should automatically set the URL property on definition instances', () => {
+      const codeSystemInstance = new Instance('TestInstance');
+      codeSystemInstance.instanceOf = 'CodeSystem';
+      codeSystemInstance.usage = 'Definition';
+      const exported = exportInstance(codeSystemInstance);
+      expect(exported.url).toBe('http://hl7.org/fhir/us/minimal/CodeSystem/TestInstance');
+    });
+
+    it('should not automatically set the URL property on definition instances if the URL is set explicitly', () => {
+      const codeSystemInstance = new Instance('TestInstance');
+      codeSystemInstance.instanceOf = 'CodeSystem';
+      codeSystemInstance.usage = 'Definition';
+
+      const urlRule = new AssignmentRule('url');
+      urlRule.value = 'http://someDifferentCanonical.org/testInstance';
+      codeSystemInstance.rules.push(urlRule);
+      const exported = exportInstance(codeSystemInstance);
+      expect(exported.url).toBe('http://someDifferentCanonical.org/testInstance');
+    });
+
+    it('should not automatically set the URL property on definition instances if the profile does not support URL setting', () => {
+      const patientInstance = new Instance('TestInstance');
+      patientInstance.instanceOf = 'Patient';
+      patientInstance.usage = 'Definition';
+
+      const exported = exportInstance(patientInstance);
+      expect(exported.url).toBeUndefined;
+    });
+
     // Setting instance id
     it('should set id to instance name by default', () => {
       const myExamplePatient = new Instance('MyExample');