« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/yaml.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/yaml.js')
-rw-r--r--src/data/yaml.js62
1 files changed, 48 insertions, 14 deletions
diff --git a/src/data/yaml.js b/src/data/yaml.js
index f269d447..9c3a4b88 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -4,7 +4,7 @@
 import * as path from 'path';
 import yaml from 'js-yaml';
 
-import {readFile} from 'fs/promises';
+import {readFile, stat} from 'fs/promises';
 import {inspect as nodeInspect} from 'util';
 
 import T from './things/index.js';
@@ -241,7 +241,7 @@ export const processTrackSectionDocument = makeProcessDocument(T.TrackSectionHel
 
 export const processTrackDocument = makeProcessDocument(T.Track, {
   fieldTransformations: {
-    'Duration': getDurationInSeconds,
+    'Duration': parseDuration,
 
     'Date First Released': (value) => new Date(value),
     'Cover Art Date': (value) => new Date(value),
@@ -447,13 +447,9 @@ export function processHomepageLayoutRowDocument(document) {
 
 // --> Utilities shared across document parsing functions
 
-export function getDurationInSeconds(string) {
-  if (typeof string === 'number') {
-    return string;
-  }
-
+export function parseDuration(string) {
   if (typeof string !== 'string') {
-    throw new TypeError(`Expected a string or number, got ${string}`);
+    return string;
   }
 
   const parts = string.split(':').map((n) => parseInt(n));
@@ -467,7 +463,6 @@ export function getDurationInSeconds(string) {
 }
 
 export function parseAdditionalFiles(array) {
-  if (!array) return null;
   if (!Array.isArray(array)) {
     // Error will be caught when validating against whatever this value is
     return array;
@@ -493,8 +488,11 @@ export function parseCommentary(text) {
 }
 
 export function parseContributors(contributors) {
-  if (!contributors) {
-    return null;
+  // If this isn't something we can parse, just return it as-is.
+  // The Thing object's validators will handle the data error better
+  // than we're able to here.
+  if (!Array.isArray(contributors)) {
+    return contributors;
   }
 
   if (contributors.length === 1 && contributors[0].startsWith('<i>')) {
@@ -528,8 +526,11 @@ export function parseContributors(contributors) {
 }
 
 function parseDimensions(string) {
-  if (!string) {
-    return null;
+  // It's technically possible to pass an array like [30, 40] through here.
+  // That's not really an issue because if it isn't of the appropriate shape,
+  // the Thing object's validators will handle the error.
+  if (typeof string !== 'string') {
+    return string;
   }
 
   const parts = string.split(/[x,* ]+/g);
@@ -940,6 +941,30 @@ export async function loadAndProcessDataDocuments({dataPath}) {
               ? await callAsync(dataStep.file, dataPath)
               : dataStep.file);
 
+          const statResult = await callAsync(() =>
+            stat(file).then(
+              () => true,
+              error => {
+                if (error.code === 'ENOENT') {
+                  return false;
+                } else {
+                  throw error;
+                }
+              }));
+
+          if (statResult === false) {
+            const saveResult = call(dataStep.save, {
+              [documentModes.allInOne]: [],
+              [documentModes.oneDocumentTotal]: {},
+            }[documentMode]);
+
+            if (!saveResult) return;
+
+            Object.assign(wikiDataResult, saveResult);
+
+            return;
+          }
+
           const readResult = await callAsync(readFile, file, 'utf-8');
 
           if (!readResult) {
@@ -987,7 +1012,16 @@ export async function loadAndProcessDataDocuments({dataPath}) {
 
         let files = (
           typeof dataStep.files === 'function'
-            ? await callAsync(dataStep.files, dataPath)
+            ? await callAsync(() =>
+                dataStep.files(dataPath).then(
+                  files => files,
+                  error => {
+                    if (error.code === 'ENOENT') {
+                      return [];
+                    } else {
+                      throw error;
+                    }
+                  }))
             : dataStep.files
         );