« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/util/find.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/find.js')
-rw-r--r--src/util/find.js83
1 files changed, 57 insertions, 26 deletions
diff --git a/src/util/find.js b/src/util/find.js
index 1cbeb82c..5f69bbec 100644
--- a/src/util/find.js
+++ b/src/util/find.js
@@ -1,15 +1,36 @@
 import {
+    logError,
     logWarn
 } from './cli.js';
 
-function findHelper(keys, dataProp, findFn) {
-    return (ref, {wikiData}) => {
-        if (!ref) return null;
-        ref = ref.replace(new RegExp(`^(${keys.join('|')}):`), '');
+function findHelper(keys, dataProp, findFns = {}) {
+    const byDirectory = findFns.byDirectory || matchDirectory;
+    const byName = findFns.byName || matchName;
+
+    const keyRefRegex = new RegExp(`^((${keys.join('|')}):)?(.*)$`);
+
+    return (fullRef, {wikiData}) => {
+        if (!fullRef) return null;
+        if (typeof fullRef !== 'string') {
+            throw new Error(`Got a reference that is ${typeof fullRef}, not string: ${fullRef}`);
+        }
+
+        const match = fullRef.match(keyRefRegex);
+        if (!match) {
+            throw new Error(`Malformed link reference: "${fullRef}"`);
+        }
+
+        const key = match[1];
+        const ref = match[3];
+
+        const data = wikiData[dataProp];
+
+        const found = (key
+            ? byDirectory(ref, data)
+            : byName(ref, data));
 
-        const found = findFn(ref, wikiData[dataProp]);
         if (!found) {
-            logWarn`Didn't match anything for ${ref}! (${keys.join(', ')})`;
+            logWarn`Didn't match anything for ${fullRef}!`;
         }
 
         return found;
@@ -20,35 +41,45 @@ function matchDirectory(ref, data) {
     return data.find(({ directory }) => directory === ref);
 }
 
-function matchDirectoryOrName(ref, data) {
-    let thing;
+function matchName(ref, data) {
+    const matches = data.filter(({ name }) => name.toLowerCase() === ref.toLowerCase());
 
-    thing = matchDirectory(ref, data);
-    if (thing) return thing;
+    if (matches.length > 1) {
+        logError`Multiple matches for reference "${ref}". Please resolve:`;
+        for (const match of matches) {
+            logError`- ${match.name} (${match.directory})`;
+        }
+        logError`Returning null for this reference.`;
+        return null;
+    }
 
-    thing = data.find(({ name }) => name === ref);
-    if (thing) return thing;
+    if (matches.length === 0) {
+        return null;
+    }
 
-    thing = data.find(({ name }) => name.toLowerCase() === ref.toLowerCase());
-    if (thing) {
+    const thing = matches[0];
+
+    if (ref !== thing.name) {
         logWarn`Bad capitalization: ${'\x1b[31m' + ref} -> ${'\x1b[32m' + thing.name}`;
-        return thing;
     }
 
-    return null;
+    return thing;
+}
+
+function matchTagName(ref, data) {
+    return matchName(ref.startsWith('cw: ') ? ref.slice(4) : ref, data);
 }
 
 const find = {
-    album: findHelper(['album', 'album-commentary'], 'albumData', matchDirectoryOrName),
-    artist: findHelper(['artist', 'artist-gallery'], 'artistData', matchDirectoryOrName),
-    flash: findHelper(['flash'], 'flashData', matchDirectory),
-    group: findHelper(['group', 'group-gallery'], 'groupData', matchDirectoryOrName),
-    listing: findHelper(['listing'], 'listingSpec', matchDirectory),
-    newsEntry: findHelper(['news-entry'], 'newsData', matchDirectory),
-    staticPage: findHelper(['static'], 'staticPageData', matchDirectory),
-    tag: findHelper(['tag'], 'tagData', (ref, data) =>
-        matchDirectoryOrName(ref.startsWith('cw: ') ? ref.slice(4) : ref, data)),
-    track: findHelper(['track'], 'trackData', matchDirectoryOrName)
+    album: findHelper(['album', 'album-commentary'], 'albumData'),
+    artist: findHelper(['artist', 'artist-gallery'], 'artistData'),
+    flash: findHelper(['flash'], 'flashData'),
+    group: findHelper(['group', 'group-gallery'], 'groupData'),
+    listing: findHelper(['listing'], 'listingSpec'),
+    newsEntry: findHelper(['news-entry'], 'newsData'),
+    staticPage: findHelper(['static'], 'staticPageData'),
+    tag: findHelper(['tag'], 'tagData', {byName: matchTagName}),
+    track: findHelper(['track'], 'trackData')
 };
 
 export default find;