Repository: FHIR/sushi (ts)

Issue:
SUSHI tries to read spreadsheets as XML resources
The `input/resources`, `input/profiles`, etc, folders can include spreadsheet XML files (e.g., `resources-spreadsheet.xml`).  SUSHI tries to read these as FHIR resources and then emits an error:
```
error Loading resources-spreadsheet.xml failed with the following error:
Unknown resource type: Workbook
```


Pull request description:
Dont process spreadsheets
If an XML file name ends with "-spreadsheet.xml" or it contains the mso-application declaration for excel, ignore it.

Fixes #638

Patch:
diff --git a/src/fhirdefs/load.ts b/src/fhirdefs/load.ts
index ef148a0..e0f7a25 100644
--- a/src/fhirdefs/load.ts
+++ b/src/fhirdefs/load.ts
@@ -189,6 +189,7 @@ export function loadCustomResources(resourceDir: string, defs: FHIRDefinitions):
   const converter = new FHIRConverter();
   for (const pathEnd of pathEnds) {
     let invalidFile = false;
+    let foundSpreadsheets = false;
     const dirPath = path.join(resourceDir, pathEnd);
     if (fs.existsSync(dirPath)) {
       const files = fs.readdirSync(dirPath);
@@ -200,8 +201,16 @@ export function loadCustomResources(resourceDir: string, defs: FHIRDefinitions):
             continue;
           } else if (file.endsWith('.json')) {
             resourceJSON = fs.readJSONSync(path.join(dirPath, file));
+          } else if (file.endsWith('-spreadsheet.xml')) {
+            foundSpreadsheets = true;
+            continue;
           } else if (file.endsWith('xml')) {
-            resourceJSON = converter.xmlToObj(fs.readFileSync(path.join(dirPath, file)).toString());
+            const xml = fs.readFileSync(path.join(dirPath, file)).toString();
+            if (/<\?mso-application progid="Excel\.Sheet"\?>/m.test(xml)) {
+              foundSpreadsheets = true;
+              continue;
+            }
+            resourceJSON = converter.xmlToObj(xml);
           } else {
             invalidFile = true;
             continue;
@@ -225,6 +234,11 @@ export function loadCustomResources(resourceDir: string, defs: FHIRDefinitions):
         `Invalid file detected in directory ${dirPath}. Input FHIR definitions must be JSON or XML.`
       );
     }
+    if (foundSpreadsheets) {
+      logger.info(
+        `Found spreadsheets in directory ${dirPath}. SUSHI does not support spreadsheets, so any resources in the spreadsheets will be ignored.`
+      );
+    }
   }
 }
 


Test patch:
diff --git a/test/fhirdefs/fixtures/customized-ig-with-resources/ig-data/input/resources/resources-spreadsheet.xml b/test/fhirdefs/fixtures/customized-ig-with-resources/ig-data/input/resources/resources-spreadsheet.xml
new file mode 100644
index 0000000..56bd446
--- /dev/null
+++ b/test/fhirdefs/fixtures/customized-ig-with-resources/ig-data/input/resources/resources-spreadsheet.xml
@@ -0,0 +1,2 @@
+﻿<?xml version="1.0"?>
+<!-- Not actually a spreadsheet, but testing that we ignore it if it *looks* like a spreadsheet based on file name -->
diff --git a/test/fhirdefs/fixtures/customized-ig-with-resources/ig-data/input/resources/sneaky-spread-like-bread-sheet.xml b/test/fhirdefs/fixtures/customized-ig-with-resources/ig-data/input/resources/sneaky-spread-like-bread-sheet.xml
new file mode 100644
index 0000000..6dd4763
--- /dev/null
+++ b/test/fhirdefs/fixtures/customized-ig-with-resources/ig-data/input/resources/sneaky-spread-like-bread-sheet.xml
@@ -0,0 +1,10 @@
+﻿<?xml version="1.0"?>
+<?mso-application progid="Excel.Sheet"?>
+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
+ xmlns:o="urn:schemas-microsoft-com:office:office"
+ xmlns:x="urn:schemas-microsoft-com:office:excel"
+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
+ xmlns:html="http://www.w3.org/TR/REC-html40">
+  <!-- We don't need all the contents to test that this is a workbook since we only look at the declaration on line 2 -->
+  <!-- Snipping out the rest since it is a waste of bytes for these tests. -->
+</Workbook>
diff --git a/test/fhirdefs/load.test.ts b/test/fhirdefs/load.test.ts
index 312606a..a236529 100644
--- a/test/fhirdefs/load.test.ts
+++ b/test/fhirdefs/load.test.ts
@@ -377,6 +377,24 @@ describe('#loadCustomResources', () => {
     );
   });
 
+  it('should not log an error for spreadsheet XML files following standard naming convention', () => {
+    loggerSpy.getAllMessages('error').forEach(m => {
+      expect(m).not.toMatch(/Loading resources-spreadsheet.xml failed with the following error:/);
+    });
+  });
+
+  it('should not log an error for spreadsheet XML files NOT following standard naming convention', () => {
+    loggerSpy.getAllMessages('error').forEach(m => {
+      expect(m).not.toMatch(
+        /Loading sneaky-spread-like-bread-sheet.xml failed with the following error:/
+      );
+    });
+  });
+
+  it('should log an info message when it finds spreadsheets', () => {
+    expect(loggerSpy.getLastMessage('info')).toMatch(/Found spreadsheets in directory/);
+  });
+
   it('should log an error for invalid JSON files', () => {
     expect(loggerSpy.getMessageAtIndex(-3, 'error')).toMatch(
       /Loading InvalidFile.json failed with the following error:/