Repository: FHIR/sushi (ts)

Issue:
SUSHI does not support FHIR 5.0.0-snapshot1
If you specify the `fhirVersion` as `5.0.0-snapshot1`, SUSHI will complain:
> The sushi-config.yaml must specify a supported version of FHIR. Be sure to add "fhirVersion: 4.0.1" (or 4.x.y, as appropriate) to the sushi-config.yaml file.

https://chat.fhir.org/#narrow/stream/215610-shorthand/topic/R5.20support

Pull request description:
Support 5.0.0-snapshot1
This PR adds support for `fhirVersion: 5.0.0-snapshot1`.  Previous versions of SUSHI expected the version number to always start with `4` (since even the R5 pre-releases used to start with `4`).  Now we support releases starting with `5` and do a better job of detecting pre-releases.

Fixes #994


Patch:
diff --git a/regression/repos-all.txt b/regression/repos-all.txt
index 6cbd067..299b71b 100644
--- a/regression/repos-all.txt
+++ b/regression/repos-all.txt
@@ -165,3 +165,17 @@ mcode/mcode-omop#master
 mcode/biomarker#master
 ehealthsuisse/ch-vacd#master
 oliveregger/BundleConformsTo#master
+# Added Tue Dec 21 2021 16:33:22 GMT-0500 (Eastern Standard Time)
+HL7/fhir-directory-query#master
+HL7/fhircast-docs#master
+JohnMoehrke/SlicingSlicedExtension#main
+hl7ch/ch-resp#master
+hl7ch/ch-ems#master
+hl7dk/dk-medcom-core#master
+hl7dk/dk-medcom-hospitalnotification#master
+hl7dk/dk-medcom-messaging#main
+IHE/ITI.MHDS#master
+medcomdk/FFBFSHTestScripts#master
+medcomdk/HospitalnotificationFSHTestScripts#master
+ehealthsuisse/ch-epr-mhealth#master
+ehealthsuisse/ch-mhd#master
diff --git a/src/utils/Processing.ts b/src/utils/Processing.ts
index 7d230fd..8b42cfa 100644
--- a/src/utils/Processing.ts
+++ b/src/utils/Processing.ts
@@ -26,9 +26,9 @@ const EXT_PKG_TO_FHIR_PKG_MAP: { [key: string]: string } = {
 };
 
 export function isSupportedFHIRVersion(version: string): boolean {
-  // For now, allow current or any 4.x version of FHIR except 4.0.0. This is a quick check; not a guarantee.  If a user passes
+  // For now, allow current or any 4.x/5.x version of FHIR except 4.0.0. This is a quick check; not a guarantee.  If a user passes
   // in an invalid version that passes this test (e.g., 4.99.0), it is still expected to fail when we load dependencies.
-  return /current|4\.0\.1|4\.[1-9]\d*.\d+/.test(version);
+  return version !== '4.0.0' && /^(current|[45]\.\d+.\d+(-.+)?)$/.test(version);
 }
 
 export function ensureInputDir(input: string): string {
@@ -151,7 +151,7 @@ export function readConfig(input: string): Configuration {
   if (!config.fhirVersion.some(v => isSupportedFHIRVersion(v))) {
     logger.error(
       `The ${path.basename(config.filePath)} must specify a supported version of FHIR. Be sure to` +
-        ` add "fhirVersion: 4.0.1" (or 4.x.y, as appropriate) to the ${path.basename(
+        ` add "fhirVersion: 4.0.1" (or 4.x.y, 5.0.0-snapshot1, etc., as appropriate) to the ${path.basename(
           config.filePath
         )} file.`
     );
@@ -169,13 +169,15 @@ export async function loadExternalDependencies(
   const fhirVersion = config.fhirVersion.find(v => isSupportedFHIRVersion(v));
   let fhirPackageId: string;
   let prerelease = false;
-  if (fhirVersion.startsWith('4.0.')) {
+  if (/^4\.0\./.test(fhirVersion)) {
     fhirPackageId = 'hl7.fhir.r4.core';
-  } else if (fhirVersion.startsWith('4.1.')) {
+  } else if (/^(4\.1\.|4\.3.\d+-)/.test(fhirVersion)) {
     fhirPackageId = 'hl7.fhir.r4b.core';
     prerelease = true;
-  } else if (fhirVersion.startsWith('4.3.')) {
+  } else if (/^4\.3.\d+$/.test(fhirVersion)) {
     fhirPackageId = 'hl7.fhir.r4b.core';
+  } else if (/^5\.0.\d+$/.test(fhirVersion)) {
+    fhirPackageId = 'hl7.fhir.r5.core';
   } else {
     fhirPackageId = 'hl7.fhir.r5.core';
     prerelease = true;


Test patch:
diff --git a/test/utils/Processing.test.ts b/test/utils/Processing.test.ts
index d32ecd7..796d6f2 100644
--- a/test/utils/Processing.test.ts
+++ b/test/utils/Processing.test.ts
@@ -357,6 +357,18 @@ describe('Processing', () => {
       });
     });
 
+    it('should support prerelease FHIR R4B snapshot dependencies', () => {
+      const config = cloneDeep(minimalConfig);
+      config.fhirVersion = ['4.3.0-snapshot1'];
+      const defs = new FHIRDefinitions();
+      return loadExternalDependencies(defs, config).then(() => {
+        expect(defs.packages).toEqual(['hl7.fhir.r4b.core#4.3.0-snapshot1']);
+        expect(loggerSpy.getLastMessage('warn')).toMatch(
+          /support for pre-release versions of FHIR is experimental/s
+        );
+      });
+    });
+
     it('should support official FHIR R4B dependency (will be 4.3.0)', () => {
       const config = cloneDeep(minimalConfig);
       config.fhirVersion = ['4.3.0'];
@@ -379,6 +391,28 @@ describe('Processing', () => {
       });
     });
 
+    it('should support prerelease FHIR R5 snapshot dependencies', () => {
+      const config = cloneDeep(minimalConfig);
+      config.fhirVersion = ['5.0.0-snapshot1'];
+      const defs = new FHIRDefinitions();
+      return loadExternalDependencies(defs, config).then(() => {
+        expect(defs.packages).toEqual(['hl7.fhir.r5.core#5.0.0-snapshot1']);
+        expect(loggerSpy.getLastMessage('warn')).toMatch(
+          /support for pre-release versions of FHIR is experimental/s
+        );
+      });
+    });
+
+    it('should support official FHIR R5 dependency (will be 5.0.0)', () => {
+      const config = cloneDeep(minimalConfig);
+      config.fhirVersion = ['5.0.0'];
+      const defs = new FHIRDefinitions();
+      return loadExternalDependencies(defs, config).then(() => {
+        expect(defs.packages).toEqual(['hl7.fhir.r5.core#5.0.0']);
+        expect(loggerSpy.getAllLogs('warn')).toHaveLength(0);
+      });
+    });
+
     it('should support FHIR current dependencies', () => {
       const config = cloneDeep(minimalConfig);
       config.fhirVersion = ['current'];