Repository: FHIR/sushi (ts)

Issue:
SUSHI should allow artifacts.html to be listed in pages
SUSHI currently checks that every page listed in the `pages` entry in `sushi-config.yaml` actually exists.  But authors may want to list some pages that the IG Publisher generates (such as artifacts.html).  We should either update SUSHI to allow references to _any_ pages (without checking for existence) or at least allow for certain known-to-be-generated pages.

See: https://chat.fhir.org/#narrow/stream/215610-shorthand/topic/pages

Pull request description:
Allow any configured page
This PR fixes #696. I took the approach of letting SUSHI reference _any_ page in the configuration because I thought that was the latest approach we talked about. However, if we'd prefer this implementation to only allow certain known-to-be-generated pages and check the existence for others, I can update it.

Patch:
diff --git a/src/ig/IGExporter.ts b/src/ig/IGExporter.ts
index acce5b7..68882dc 100644
--- a/src/ig/IGExporter.ts
+++ b/src/ig/IGExporter.ts
@@ -524,13 +524,7 @@ export class IGExporter {
         name = page.nameUrl.slice(0, lastPeriod);
         fileType = page.nameUrl.slice(lastPeriod + 1);
       }
-      // page content may be in pagecontent or pages folders
-      const pageFolder = ['pagecontent', 'pages'].find(folder => {
-        return existsSync(path.join(this.igDataPath, 'input', folder, page.nameUrl));
-      });
-      if (!pageFolder) {
-        logger.error(`File for configured page ${page.nameUrl} not found.`);
-      }
+      // Any page listed in configuration will be added, even if it does not exist.
       const igPage: ImplementationGuideDefinitionPage = {
         nameUrl: `${name}.html`,
         title: page.title ?? titleCase(words(name).join(' ')),


Test patch:
diff --git a/test/ig/IGExporter.IG.test.ts b/test/ig/IGExporter.IG.test.ts
index ee9067f..fa29597 100644
--- a/test/ig/IGExporter.IG.test.ts
+++ b/test/ig/IGExporter.IG.test.ts
@@ -739,7 +739,7 @@ describe('IGExporter', () => {
       ]);
     });
 
-    it('should log an error when no file exists for a configured page', () => {
+    it('should not log an error when no file exists for a configured page', () => {
       config.pages = [
         {
           nameUrl: 'index.md',
@@ -768,7 +768,7 @@ describe('IGExporter', () => {
           generation: 'markdown'
         }
       ]);
-      expect(loggerSpy.getLastMessage('error')).toMatch(/nothing\.md not found/s);
+      expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
     });
 
     it('should copy over the templates property', () => {
diff --git a/test/ig/IGExporter.addConfiguredPageContent.test.ts b/test/ig/IGExporter.addConfiguredPageContent.test.ts
index df315cc..5137029 100644
--- a/test/ig/IGExporter.addConfiguredPageContent.test.ts
+++ b/test/ig/IGExporter.addConfiguredPageContent.test.ts
@@ -28,7 +28,8 @@ describe('IGExporter', () => {
           nameUrl: 'examples.xml',
           title: 'Examples Overview',
           page: [{ nameUrl: 'simpleExamples.xml' }]
-        }
+        },
+        { nameUrl: 'generated.md', title: 'A generated page that does not exist yet' }
       ];
       loggerSpy.reset();
     });
@@ -51,6 +52,7 @@ describe('IGExporter', () => {
       const pageContentPath = path.join(tempOut, 'input', 'pagecontent');
       expect(fs.existsSync(pageContentPath)).toBeFalsy();
       expect(outputFileSyncSpy).not.toHaveBeenCalled();
+      expect(loggerSpy.getAllMessages()).toHaveLength(0); // No error logged for specifying generated.md, which doesn't exist yet
     });
 
     it('should copy over configured page content in legacy IG publisher configuration', () => {
@@ -74,6 +76,7 @@ describe('IGExporter', () => {
         const content = fs.readFileSync(path.join(pageContentPath, file), 'utf8');
         expect(content).toMatch(/^\*\s+WARNING: DO NOT EDIT THIS FILE\s+\*$/m);
       }
+      expect(loggerSpy.getAllMessages()).toHaveLength(0); // No error logged for specifying generated.md, which doesn't exist yet
     });
   });
 });