Repository: FHIR/sushi (ts)

Issue:
Don't inherit potentially irrelevant metadata from parents
This issue stems from the conversation of #128.  The general discussion was around clearing inherited metadata that causes issues in the IG Publisher or is potentially irrelevant to the profile.  The main concern of #128 was the `"comment"` field, which is in `ElementDefinition`.  We've currently decided _not_ to address that because clearing comments would cause _many_ differential elements.

This issue is to point out that the top-level metadata of profiles and extensions still inherits many fields that are potentially irrelevant or wrong for the profile/extension.  We should remove those.  I proposed an approach on Zulip here: https://chat.fhir.org/#narrow/stream/179252-IG-creation/topic/Bad.20links.20on.20Detailed.20Description.20tab/near/186460459

I've also copied the approach in case something happens to the zulip:

* **id** - overwrite w/ new id
* **meta** - clear
* **implicitRules** - clear
* **language** - clear
* **text** - clear
* **contained** - clear
* **extension** - clear (see https://github.com/FHIR/sushi/issues/116)
* **modifierExtension** - clear
* **url** - overwrite w/ new url
* **identifier** - clear
* **version** - overwrite w/ IG version (author can override if maintaining per-profile versions)
* **name** - overwrite w/ new name
* **title** - clear or overwrite w/ new title (if applicable)
* **status** - currently defaults to `active` but FSH should add (required?) keyword
* **experimental** - clear
* **date** - clear
* **publisher** - clear (or overwrite w/ publisher from config?)
* **contact** - clear (or overwrite w/ contributors from config?)
* **description** - clear or overwrite w/ new description (if applicable)
* **useContext** - clear
* **jursidiction** - clear
* **purpose** - clear
* **copyright** - clear
* **keyword** - clear or keep? Would parent keywords still be applicable to child profiles?
* **fhirVersion** - set to target version (should match anyway)
* **mapping** - keep (assuming mappings are still valid and because removing them would require use to remove mappings from every element, creating tons of diffs)
* **kind** - keep (this should not change)
* **abstract** - keep or set to false.  If you set an abstract profile as a parent should you need to explicitly toggle abstractness to `false`?  Or should we default to `false`?
* **context** - keep (assuming context is still valid for child extensions)
* **contextInvariant** - keep (assuming context is still valid for child extensions)
* **type** - keep (this should not change for profiles or extensions)
* **baseDefinition** - overwrite w/ the parent URL of the new profile/extension
* **derivation** - set to constraint (so far, SUSHI only supports constraints)
* **snapshot** - keep, but elements will obviously be overwritten by constraints
* **differential** - clear, as the differential starts from scratch to reflect changes the profile has made to the parent

Pull request description:
Start with cleaner plate
When creating a profile, start from a cleaner slate, clearing potentially irrelevant metadata from the parent.  This PR fixes #157.

The unit tests show the basic functionality.  You can also verify by generating profiles/extensions using the `master` branch and then generating them with this branch.  A file compare will show the differences.

Patch:
diff --git a/.eslintignore b/.eslintignore
index 7798cbf..2ab48b2 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,7 +3,7 @@
 # build artefacts
 dist/*
 coverage/*
-build/*
+build*/*
 # data definition files
 **/*.d.ts
 # 3rd party libs
diff --git a/.prettierignore b/.prettierignore
index 23715c0..e8a5ce2 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,6 +1,6 @@
 .vscode
 coverage
 dist
-build
+build*
 node_modules
 **/generated
\ No newline at end of file
diff --git a/src/export/StructureDefinitionExporter.ts b/src/export/StructureDefinitionExporter.ts
index bcf3701..d6cb532 100644
--- a/src/export/StructureDefinitionExporter.ts
+++ b/src/export/StructureDefinitionExporter.ts
@@ -27,33 +27,70 @@ export class StructureDefinitionExporter implements Fishable {
   ) {}
 
   /**
-   * Sets the metadata for the StructureDefinition
+   * Sets the metadata for the StructureDefinition.  This includes clearing metadata that was copied from the parent
+   * that may not be relevant to the child StructureDefinition.  Overall approach was discussed on Zulip.  This
+   * function represents implementation of that approach plus setting extra metadata provided by FSH.
+   * This essentially aligns closely with the approach that Forge uses (ensuring some consistency across tools).
+   * @see {@link https://chat.fhir.org/#narrow/stream/179252-IG-creation/topic/Bad.20links.20on.20Detailed.20Description.20tab/near/186766845}
    * @param {StructureDefinition} structDef - The StructureDefinition to set metadata on
    * @param {Profile | Extension} fshDefinition - The Profile or Extension we are exporting
    */
   private setMetadata(structDef: StructureDefinition, fshDefinition: Profile | Extension): void {
-    structDef.setName(fshDefinition.name, fshDefinition.sourceInfo);
+    // First save the original URL, as that is the URL we'll want to set as the baseDefinition
+    const baseURL = structDef.url;
+
+    // Now set/clear elements in order of their appearance in Resource/DomainResource/StructureDefinition definitions
     structDef.setId(fshDefinition.id, fshDefinition.sourceInfo);
-    if (fshDefinition.title) structDef.title = fshDefinition.title;
-    if (fshDefinition.description) structDef.description = fshDefinition.description;
-    // Version is set to value provided in config, will be overriden if reset by rules
-    structDef.version = this.tank.config.version;
-    // Assuming the starting StructureDefinition was a clone of the parent,
-    // set the baseDefinition to the parent url before re-assiging the url
-    structDef.baseDefinition = structDef.url;
-    // Now re-assign the URL based on canonical and id
+    delete structDef.meta;
+    delete structDef.implicitRules;
+    delete structDef.language;
+    delete structDef.text;
+    delete structDef.contained;
+    delete structDef.extension; // see https://github.com/FHIR/sushi/issues/116
+    delete structDef.modifierExtension;
     structDef.url = `${this.tank.config.canonical}/StructureDefinition/${structDef.id}`;
-    // Set the derivation as appropriate
-    if (fshDefinition instanceof Profile) {
-      structDef.derivation = 'constraint';
-    } else if (fshDefinition instanceof Extension) {
+    delete structDef.identifier;
+    structDef.version = this.tank.config.version; // can be overridden using a rule
+    structDef.setName(fshDefinition.name, fshDefinition.sourceInfo);
+    if (fshDefinition.title) {
+      structDef.title = fshDefinition.title;
+    } else {
+      delete structDef.title;
+    }
+    structDef.status = 'draft'; // it's 1..1 so we have to set it to something; can be overridden w/ rule
+    delete structDef.experimental;
+    delete structDef.date;
+    delete structDef.publisher;
+    delete structDef.contact;
+    if (fshDefinition.description) {
+      structDef.description = fshDefinition.description;
+    } else {
+      delete structDef.description;
+    }
+    delete structDef.useContext;
+    delete structDef.jurisdiction;
+    delete structDef.purpose;
+    delete structDef.copyright;
+    delete structDef.keyword;
+    // keep structDef.fhirVersion as that ought not change from parent to child
+    // keep mapping since existing elements refer to the mapping and we're not removing those
+    // keep kind since it should not change
+    structDef.abstract = false; // always reset to false, assuming most children of abstracts aren't abstract
+    // keep context, assuming context is still valid for child extensions
+    // keep contextInvariant, assuming context is still valid for child extensions
+    // keep type since this should not change for profiles or extensions
+    structDef.baseDefinition = baseURL;
+    structDef.derivation = 'constraint'; // always constraint since SUSHI only supports profiles/extensions right now
+
+    if (fshDefinition instanceof Extension) {
       // Automatically set url.fixedUri on Extensions
       const url = structDef.findElement('Extension.url');
       url.fixedUri = structDef.url;
-      structDef.derivation = 'constraint';
       if (structDef.context == null) {
-        // NOTE: For now, we always set context to everything, but this will be user-specified
-        // in the future
+        // Set context to everything by default, but users can override w/ rules, e.g.
+        // ^context[0].type = #element
+        // ^context[0].expression = "Patient"
+        // TODO: Consider introducing metadata keywords for this
         structDef.context = [
           {
             type: 'element',
@@ -62,8 +99,6 @@ export class StructureDefinitionExporter implements Fishable {
         ];
       }
     }
-    // Remove the base-level extensions as they may not be valid in this context
-    delete structDef.extension;
   }
 
   /**
diff --git a/src/fhirtypes/CodeSystem.ts b/src/fhirtypes/CodeSystem.ts
index d344276..9599861 100644
--- a/src/fhirtypes/CodeSystem.ts
+++ b/src/fhirtypes/CodeSystem.ts
@@ -23,7 +23,7 @@ export class CodeSystem {
   version?: string;
   // name?: string; // provided by HasName mixin
   title?: string;
-  status = 'active';
+  status: 'draft' | 'active' | 'retired' | 'unknown' = 'draft';
   experimental?: boolean;
   date?: string;
   publisher?: string;
@@ -38,7 +38,7 @@ export class CodeSystem {
   hierarchyMeaning?: string;
   compositional?: boolean;
   versionNeeded?: boolean;
-  content = 'complete';
+  content: 'not-present' | 'example' | 'fragment' | 'complete' | 'supplement' = 'complete';
   supplements?: string;
   count?: number;
   filter?: CodeSystemFilter[];
diff --git a/src/fhirtypes/ValueSet.ts b/src/fhirtypes/ValueSet.ts
index 8768e21..193920d 100644
--- a/src/fhirtypes/ValueSet.ts
+++ b/src/fhirtypes/ValueSet.ts
@@ -27,7 +27,7 @@ export class ValueSet {
   version: string;
   // name: string; // provided by HasName mixin
   title: string;
-  status = 'active';
+  status: 'draft' | 'active' | 'retired' | 'unknown' = 'draft';
   experimental: boolean;
   date: string;
   publisher: string;


Test patch:
diff --git a/test/export/CodeSystemExporter.test.ts b/test/export/CodeSystemExporter.test.ts
index 4adbd1a..467956b 100644
--- a/test/export/CodeSystemExporter.test.ts
+++ b/test/export/CodeSystemExporter.test.ts
@@ -32,7 +32,7 @@ describe('CodeSystemExporter', () => {
     expect(exported[0]).toEqual({
       name: 'MyCodeSystem',
       id: 'MyCodeSystem',
-      status: 'active',
+      status: 'draft',
       content: 'complete',
       url: 'http://example.com/CodeSystem/MyCodeSystem',
       version: '0.0.1'
@@ -50,7 +50,7 @@ describe('CodeSystemExporter', () => {
     expect(exported[0]).toEqual({
       name: 'MyCodeSystem',
       id: 'CodeSystem1',
-      status: 'active',
+      status: 'draft',
       content: 'complete',
       url: 'http://example.com/CodeSystem/CodeSystem1',
       title: 'My Fancy Code System',
@@ -79,7 +79,7 @@ describe('CodeSystemExporter', () => {
     expect(exported[0]).toEqual({
       name: 'MyCodeSystem',
       id: 'MyCodeSystem',
-      status: 'active',
+      status: 'draft',
       content: 'complete',
       url: 'http://example.com/CodeSystem/MyCodeSystem',
       version: '0.0.1',
@@ -102,7 +102,7 @@ describe('CodeSystemExporter', () => {
     expect(exported[0]).toEqual({
       name: 'MyCodeSystem',
       id: 'MyCodeSystem',
-      status: 'active',
+      status: 'draft',
       content: 'complete',
       url: 'http://example.com/CodeSystem/MyCodeSystem',
       version: '0.0.1',
diff --git a/test/export/StructureDefinitionExporter.test.ts b/test/export/StructureDefinitionExporter.test.ts
index 4ca83ee..70f5099 100644
--- a/test/export/StructureDefinitionExporter.test.ts
+++ b/test/export/StructureDefinitionExporter.test.ts
@@ -52,7 +52,7 @@ describe('StructureDefinitionExporter', () => {
   });
 
   // Profile
-  it('should set all metadata for a profile', () => {
+  it('should set all user-provided metadata for a profile', () => {
     const profile = new Profile('Foo');
     profile.id = 'foo';
     profile.parent = 'Observation';
@@ -69,7 +69,63 @@ describe('StructureDefinitionExporter', () => {
     expect(exported.version).toBe('0.0.1');
     expect(exported.type).toBe('Observation');
     expect(exported.baseDefinition).toBe('http://hl7.org/fhir/StructureDefinition/Observation');
-    expect(exported.derivation).toBe('constraint');
+  });
+
+  it('should properly set/clear all metadata properties for a profile', () => {
+    const profile = new Profile('Foo');
+    profile.parent = 'Observation';
+    doc.profiles.set(profile.name, profile);
+    exporter.exportStructDef(profile);
+    const exported = pkg.profiles[0];
+
+    expect(exported.id).toBe('Foo'); // defaulted from user-provided name
+    expect(exported.meta).toBeUndefined();
+    expect(exported.implicitRules).toBeUndefined();
+    expect(exported.language).toBeUndefined();
+    expect(exported.text).toBeUndefined();
+    expect(exported.contained).toBeUndefined(); // inherited from Observation
+    expect(exported.extension).toBeUndefined();
+    expect(exported.modifierExtension).toBeUndefined();
+    expect(exported.url).toBe('http://example.com/StructureDefinition/Foo'); // constructed from canonical and id
+    expect(exported.identifier).toBeUndefined();
+    expect(exported.version).toBe('0.0.1'); // provided by config
+    expect(exported.name).toBe('Foo'); // provided by user
+    expect(exported.title).toBeUndefined();
+    expect(exported.status).toBe('draft'); // always active
+    expect(exported.experimental).toBeUndefined();
+    expect(exported.date).toBeUndefined();
+    expect(exported.publisher).toBeUndefined();
+    expect(exported.contact).toBeUndefined();
+    expect(exported.description).toBeUndefined();
+    expect(exported.useContext).toBeUndefined();
+    expect(exported.jurisdiction).toBeUndefined();
+    expect(exported.purpose).toBeUndefined();
+    expect(exported.copyright).toBeUndefined();
+    expect(exported.keyword).toBeUndefined();
+    expect(exported.fhirVersion).toBe('4.0.1'); // Inherited from Observation
+    expect(exported.mapping).toEqual([
+      { identity: 'workflow', uri: 'http://hl7.org/fhir/workflow', name: 'Workflow Pattern' },
+      {
+        identity: 'sct-concept',
+        uri: 'http://snomed.info/conceptdomain',
+        name: 'SNOMED CT Concept Domain Binding'
+      },
+      { identity: 'v2', uri: 'http://hl7.org/v2', name: 'HL7 v2 Mapping' },
+      { identity: 'rim', uri: 'http://hl7.org/v3', name: 'RIM Mapping' },
+      { identity: 'w5', uri: 'http://hl7.org/fhir/fivews', name: 'FiveWs Pattern Mapping' },
+      {
+        identity: 'sct-attr',
+        uri: 'http://snomed.org/attributebinding',
+        name: 'SNOMED CT Attribute Binding'
+      }
+    ]); // inherited from Observation
+    expect(exported.kind).toBe('resource'); // inherited from Observation
+    expect(exported.abstract).toBe(false); // always abstract
+    expect(exported.context).toBeUndefined(); // inherited from Observation
+    expect(exported.contextInvariant).toBeUndefined(); // inherited from Observation
+    expect(exported.type).toBe('Observation'); // inherited from Observation
+    expect(exported.baseDefinition).toBe('http://hl7.org/fhir/StructureDefinition/Observation'); // url for Observation
+    expect(exported.derivation).toBe('constraint'); // always constraint
   });
 
   it('should not overwrite metadata that is not given for a profile', () => {
@@ -80,7 +136,7 @@ describe('StructureDefinitionExporter', () => {
     expect(exported.name).toBe('Foo');
     expect(exported.id).toBe('Foo');
     expect(exported.title).toBeUndefined();
-    expect(exported.description).toBe('This is the base resource type for everything.');
+    expect(exported.description).toBeUndefined();
     expect(exported.url).toBe('http://example.com/StructureDefinition/Foo');
     expect(exported.version).toBe('0.0.1');
     expect(exported.type).toBe('Resource');
@@ -88,12 +144,18 @@ describe('StructureDefinitionExporter', () => {
     expect(exported.derivation).toBe('constraint');
   });
 
-  it('should remove the base-level extensions from the parent resource', () => {
+  it('should allow metadata to be overwritten with caret rule', () => {
     const profile = new Profile('Foo');
+    profile.parent = 'Observation';
+    const rule = new CaretValueRule('');
+    rule.caretPath = 'status';
+    rule.value = new FshCode('active');
+    profile.rules.push(rule);
     doc.profiles.set(profile.name, profile);
     exporter.exportStructDef(profile);
     const exported = pkg.profiles[0];
-    expect(exported.extension).toBeUndefined();
+    expect(exported.name).toBe('Foo');
+    expect(exported.status).toBe('active');
   });
 
   it('should throw ParentNotDefinedError when parent resource is not found', () => {
@@ -106,7 +168,7 @@ describe('StructureDefinitionExporter', () => {
   });
 
   // Extension
-  it('should set all metadata for an extension', () => {
+  it('should set all user-provided metadata for an extension', () => {
     const extension = new Extension('Foo');
     extension.id = 'foo';
     extension.title = 'Foo Profile';
@@ -119,21 +181,66 @@ describe('StructureDefinitionExporter', () => {
     expect(exported.title).toBe('Foo Profile');
     expect(exported.description).toBe('foo bar foobar');
     expect(exported.url).toBe('http://example.com/StructureDefinition/foo');
-    expect(exported.elements.find(e => e.id === 'Extension.url').fixedUri).toBe(
-      'http://example.com/StructureDefinition/foo'
-    );
     expect(exported.version).toBe('0.0.1');
-    // NOTE: For now, we always set context to everything, but this will be user-specified in
-    // the future
-    expect(exported.context).toEqual([
-      {
-        type: 'element',
-        expression: 'Element'
-      }
-    ]);
     expect(exported.type).toBe('Extension');
     expect(exported.baseDefinition).toBe('http://hl7.org/fhir/StructureDefinition/Extension');
-    expect(exported.derivation).toBe('constraint');
+
+    // Check that Extension.url is correctly fixed
+    expect(exported.elements.find(e => e.id === 'Extension.url').fixedUri).toBe(
+      'http://example.com/StructureDefinition/foo'
+    );
+  });
+
+  it('should properly set/clear all metadata properties for an extension', () => {
+    const extension = new Extension('Foo');
+    extension.parent = 'patient-mothersMaidenName';
+    doc.profiles.set(extension.name, extension);
+    exporter.exportStructDef(extension);
+    const exported = pkg.extensions[0];
+
+    expect(exported.id).toBe('Foo'); // defaulted from user-provided name
+    expect(exported.meta).toBeUndefined();
+    expect(exported.implicitRules).toBeUndefined();
+    expect(exported.language).toBeUndefined();
+    expect(exported.text).toBeUndefined();
+    expect(exported.contained).toBeUndefined(); // inherited from patient-mothersMaidenName
+    expect(exported.extension).toBeUndefined();
+    expect(exported.modifierExtension).toBeUndefined();
+    expect(exported.url).toBe('http://example.com/StructureDefinition/Foo'); // constructed from canonical and id
+    expect(exported.identifier).toBeUndefined();
+    expect(exported.version).toBe('0.0.1'); // provided by config
+    expect(exported.name).toBe('Foo'); // provided by user
+    expect(exported.title).toBeUndefined();
+    expect(exported.status).toBe('draft'); // always active
+    expect(exported.experimental).toBeUndefined();
+    expect(exported.date).toBeUndefined();
+    expect(exported.publisher).toBeUndefined();
+    expect(exported.contact).toBeUndefined();
+    expect(exported.description).toBeUndefined();
+    expect(exported.useContext).toBeUndefined();
+    expect(exported.jurisdiction).toBeUndefined();
+    expect(exported.purpose).toBeUndefined();
+    expect(exported.copyright).toBeUndefined();
+    expect(exported.keyword).toBeUndefined();
+    expect(exported.fhirVersion).toBe('4.0.1'); // Inherited from patient-mothersMaidenName
+    expect(exported.mapping).toEqual([
+      { identity: 'v2', uri: 'http://hl7.org/v2', name: 'HL7 v2 Mapping' },
+      { identity: 'rim', uri: 'http://hl7.org/v3', name: 'RIM Mapping' }
+    ]); // inherited from patient-mothersMaidenName
+    expect(exported.kind).toBe('complex-type'); // inherited from patient-mothersMaidenName
+    expect(exported.abstract).toBe(false); // always abstract
+    expect(exported.context).toEqual([{ type: 'element', expression: 'Patient' }]); // inherited from patient-mothersMaidenName
+    expect(exported.contextInvariant).toBeUndefined(); // inherited from patient-mothersMaidenName
+    expect(exported.type).toBe('Extension'); // inherited from patient-mothersMaidenName
+    expect(exported.baseDefinition).toBe(
+      'http://hl7.org/fhir/StructureDefinition/patient-mothersMaidenName'
+    ); // url for patient-mothersMaidenName
+    expect(exported.derivation).toBe('constraint'); // always constraint
+
+    // Check that Extension.url is correctly fixed
+    expect(exported.elements.find(e => e.id === 'Extension.url').fixedUri).toBe(
+      'http://example.com/StructureDefinition/Foo'
+    );
   });
 
   it('should not overwrite metadata that is not given for an extension', () => {
@@ -144,16 +251,11 @@ describe('StructureDefinitionExporter', () => {
     expect(exported.name).toBe('Foo');
     expect(exported.id).toBe('Foo');
     expect(exported.title).toBeUndefined();
-    expect(exported.description).toBe(
-      'Base StructureDefinition for Extension Type: Optional Extension Element - found in all resources.'
-    );
     expect(exported.url).toBe('http://example.com/StructureDefinition/Foo');
     expect(exported.elements.find(e => e.id === 'Extension.url').fixedUri).toBe(
       'http://example.com/StructureDefinition/Foo'
     );
     expect(exported.version).toBe('0.0.1');
-    // NOTE: For now, we always set context to everything, but this will be user-specified in
-    // the future
     expect(exported.context).toEqual([
       {
         type: 'element',
@@ -183,6 +285,31 @@ describe('StructureDefinitionExporter', () => {
     ]);
   });
 
+  it('should allow metadata to be overwritten with caret rule', () => {
+    const extension = new Extension('Foo');
+    const rule1 = new CaretValueRule('');
+    rule1.caretPath = 'status';
+    rule1.value = new FshCode('active');
+    const rule2 = new CaretValueRule('');
+    rule2.caretPath = 'context[0].type';
+    rule2.value = new FshCode('element');
+    const rule3 = new CaretValueRule('');
+    rule3.caretPath = 'context[0].expression';
+    rule3.value = 'Observation';
+    extension.rules.push(rule1, rule2, rule3);
+    doc.extensions.set(extension.name, extension);
+    exporter.exportStructDef(extension);
+    const exported = pkg.extensions[0];
+    expect(exported.name).toBe('Foo');
+    expect(exported.status).toBe('active');
+    expect(exported.context).toEqual([
+      {
+        type: 'element',
+        expression: 'Observation'
+      }
+    ]);
+  });
+
   it('should throw ParentNotDefinedError when parent extension is not found', () => {
     const extension = new Extension('Foo');
     extension.parent = 'Bar';
@@ -1212,9 +1339,8 @@ describe('StructureDefinitionExporter', () => {
 
     exporter.exportStructDef(profile);
     const sd = pkg.profiles[0];
-    const baseStructDef = fisher.fishForStructureDefinition('Observation');
 
-    expect(sd.description).toBe(baseStructDef.description);
+    expect(sd.description).toBeUndefined();
     expect(loggerSpy.getLastMessage()).toMatch(/File: InvalidValue\.fsh.*Line: 6\D/s);
   });
 
diff --git a/test/export/ValueSetExporter.test.ts b/test/export/ValueSetExporter.test.ts
index f0f6cad..006698d 100644
--- a/test/export/ValueSetExporter.test.ts
+++ b/test/export/ValueSetExporter.test.ts
@@ -52,7 +52,7 @@ describe('ValueSetExporter', () => {
     expect(exported[0]).toEqual({
       name: 'BreakfastVS',
       id: 'BreakfastVS',
-      status: 'active',
+      status: 'draft',
       url: 'http://example.com/ValueSet/BreakfastVS',
       version: '0.0.1'
     });
@@ -77,7 +77,7 @@ describe('ValueSetExporter', () => {
     expect(exported[0]).toEqual({
       name: 'BreakfastVS',
       id: 'BreakfastVS',
-      status: 'active',
+      status: 'draft',
       title: 'Breakfast Values',
       description: 'A value set for breakfast items',
       url: 'http://example.com/ValueSet/BreakfastVS',
@@ -130,7 +130,7 @@ describe('ValueSetExporter', () => {
     expect(exported[0]).toEqual({
       name: 'DinnerVS',
       id: 'DinnerVS',
-      status: 'active',
+      status: 'draft',
       url: 'http://example.com/ValueSet/DinnerVS',
       version: '0.0.1',
       compose: {
@@ -153,7 +153,7 @@ describe('ValueSetExporter', () => {
     expect(exported[0]).toEqual({
       name: 'DinnerVS',
       id: 'DinnerVS',
-      status: 'active',
+      status: 'draft',
       url: 'http://example.com/ValueSet/DinnerVS',
       version: '0.0.1',
       compose: {
@@ -180,7 +180,7 @@ describe('ValueSetExporter', () => {
       name: 'DinnerVS',
       url: 'http://example.com/ValueSet/DinnerVS',
       version: '0.0.1',
-      status: 'active',
+      status: 'draft',
       compose: {
         include: [
           {
@@ -215,7 +215,7 @@ describe('ValueSetExporter', () => {
       name: 'DinnerVS',
       url: 'http://example.com/ValueSet/DinnerVS',
       version: '0.0.1',
-      status: 'active',
+      status: 'draft',
       compose: {
         include: [
           {
@@ -249,7 +249,7 @@ describe('ValueSetExporter', () => {
       name: 'DinnerVS',
       url: 'http://example.com/ValueSet/DinnerVS',
       version: '0.0.1',
-      status: 'active',
+      status: 'draft',
       compose: {
         include: [
           {
@@ -283,7 +283,7 @@ describe('ValueSetExporter', () => {
       name: 'BreakfastVS',
       url: 'http://example.com/ValueSet/BreakfastVS',
       version: '0.0.1',
-      status: 'active',
+      status: 'draft',
       compose: {
         include: [
           {
@@ -319,7 +319,7 @@ describe('ValueSetExporter', () => {
       name: 'BreakfastVS',
       url: 'http://example.com/ValueSet/BreakfastVS',
       version: '0.0.1',
-      status: 'active',
+      status: 'draft',
       compose: {
         include: [
           {
@@ -355,7 +355,7 @@ describe('ValueSetExporter', () => {
       name: 'BreakfastVS',
       url: 'http://example.com/ValueSet/BreakfastVS',
       version: '0.0.1',
-      status: 'active',
+      status: 'draft',
       compose: {
         include: [
           {
@@ -395,7 +395,7 @@ describe('ValueSetExporter', () => {
       name: 'DinnerVS',
       url: 'http://example.com/ValueSet/DinnerVS',
       version: '0.0.1',
-      status: 'active',
+      status: 'draft',
       compose: {
         include: [
           {