« 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/language.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/language.js')
-rw-r--r--src/data/language.js36
1 files changed, 32 insertions, 4 deletions
diff --git a/src/data/language.js b/src/data/language.js
index 15c11933..6ffc31e0 100644
--- a/src/data/language.js
+++ b/src/data/language.js
@@ -4,6 +4,7 @@ import path from 'node:path';
 
 import chokidar from 'chokidar';
 import he from 'he'; // It stands for "HTML Entities", apparently. Cursed.
+import yaml from 'js-yaml';
 
 import T from '#things';
 import {colors, logWarn} from '#cli';
@@ -45,8 +46,24 @@ export function processLanguageSpec(spec, {existingCode = null} = {}) {
   return {code, intlCode, name, hidden, strings};
 }
 
+function flattenLanguageSpec(spec) {
+  const recursive = (keyPath, value) =>
+    (typeof value === 'object'
+      ? Object.assign({}, ...
+          Object.entries(value)
+            .map(([key, value]) =>
+              (key === '_'
+                ? {[keyPath]: value}
+                : recursive(
+                    (keyPath ? `${keyPath}.${key}` : key),
+                    value))))
+      : {[keyPath]: value});
+
+  return recursive('', spec);
+}
+
 async function processLanguageSpecFromFile(file, processLanguageSpecOpts) {
-  let contents, spec;
+  let contents;
 
   try {
     contents = await readFile(file, 'utf-8');
@@ -56,16 +73,27 @@ async function processLanguageSpecFromFile(file, processLanguageSpecOpts) {
       error => annotateErrorWithFile(error, file));
   }
 
+  let rawSpec;
+  let parseLanguage;
+
   try {
-    spec = JSON.parse(contents);
+    if (path.extname(file) === '.yaml') {
+      parseLanguage = 'YAML';
+      rawSpec = yaml.load(contents);
+    } else {
+      parseLanguage = 'JSON';
+      rawSpec = JSON.parse(contents);
+    }
   } catch (caughtError) {
     throw annotateError(
-      new Error(`Failed to parse language file as valid JSON`, {cause: caughtError}),
+      new Error(`Failed to parse language file as valid ${parseLanguage}`, {cause: caughtError}),
       error => annotateErrorWithFile(error, file));
   }
 
+  const flattenedSpec = flattenLanguageSpec(rawSpec);
+
   try {
-    return processLanguageSpec(spec, processLanguageSpecOpts);
+    return processLanguageSpec(flattenedSpec, processLanguageSpecOpts);
   } catch (caughtError) {
     throw annotateErrorWithFile(caughtError, file);
   }