From cd3a59d5024984a2d3be5164f6b2ce9ee05e9f62 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 27 Feb 2022 12:13:53 -0400 Subject: generalized reference errors --- src/util/find.js | 75 ++++++++++++++++++++++++++++++---------------------- src/util/replacer.js | 12 ++++----- 2 files changed, 50 insertions(+), 37 deletions(-) (limited to 'src/util') diff --git a/src/util/find.js b/src/util/find.js index e8e04a5b..fc82ba9e 100644 --- a/src/util/find.js +++ b/src/util/find.js @@ -1,9 +1,21 @@ import { + color, logError, logWarn } from './cli.js'; -function findHelper(keys, dataProp, findFns = {}) { +function warnOrThrow(mode, message) { + switch (mode) { + case 'error': + throw new Error(message); + case 'warn': + logWarn(message); + default: + return null; + } +} + +function findHelper(keys, findFns = {}) { // Note: This cache explicitly *doesn't* support mutable data arrays. If the // data array is modified, make sure it's actually a new array object, not // the original, or the cache here will break and act as though the data @@ -15,18 +27,24 @@ function findHelper(keys, dataProp, findFns = {}) { const keyRefRegex = new RegExp(String.raw`^(?:(${keys.join('|')}):(?=\S))?(.*)$`); - return (fullRef, {wikiData, quiet = false}) => { + // The mode argument here may be 'warn', 'error', or 'quiet'. 'error' throws + // errors for null matches (with details about the error), while 'warn' and + // 'quiet' both return null, with 'warn' logging details directly to the + // console. + return (fullRef, data, {mode = 'warn'} = {}) => { if (!fullRef) return null; if (typeof fullRef !== 'string') { throw new Error(`Got a reference that is ${typeof fullRef}, not string: ${fullRef}`); } - const data = wikiData[dataProp]; - if (!data) { throw new Error(`Expected data to be present`); } + if (!Array.isArray(data) && data.wikiData) { + throw new Error(`Old {wikiData: {...}} format provided`); + } + let cacheForThisData = cache.get(data); const cachedValue = cacheForThisData?.[fullRef]; if (cachedValue) { @@ -40,18 +58,18 @@ function findHelper(keys, dataProp, findFns = {}) { const match = fullRef.match(keyRefRegex); if (!match) { - throw new Error(`Malformed link reference: "${fullRef}"`); + return warnOrThrow(mode, `Malformed link reference: "${fullRef}"`); } const key = match[1]; const ref = match[2]; const found = (key - ? byDirectory(ref, data, quiet) - : byName(ref, data, quiet)); + ? byDirectory(ref, data, mode) + : byName(ref, data, mode)); - if (!found && !quiet) { - logWarn`Didn't match anything for ${fullRef}!`; + if (!found) { + warnOrThrow(mode, `Didn't match anything for ${color.bright(fullRef)}`); } cacheForThisData[fullRef] = found; @@ -60,23 +78,18 @@ function findHelper(keys, dataProp, findFns = {}) { }; } -function matchDirectory(ref, data, quiet) { +function matchDirectory(ref, data, mode) { return data.find(({ directory }) => directory === ref); } -function matchName(ref, data, quiet) { +function matchName(ref, data, mode) { const matches = data.filter(({ name }) => name.toLowerCase() === ref.toLowerCase()); if (matches.length > 1) { - // TODO: This should definitely be a thrown error. - if (!quiet) { - 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; + return warnOrThrow(mode, + `Multiple matches for reference "${ref}". Please resolve:\n` + + matches.map(match => `- ${match.name} (${match.directory})\n`).join('') + + `Returning null for this reference.`); } if (matches.length === 0) { @@ -85,8 +98,8 @@ function matchName(ref, data, quiet) { const thing = matches[0]; - if (ref !== thing.name && !quiet) { - logWarn`Bad capitalization: ${'\x1b[31m' + ref} -> ${'\x1b[32m' + thing.name}`; + if (ref !== thing.name) { + warnOrThrow(mode, `Bad capitalization: ${color.red(ref)} -> ${color.green(thing.name)}`); } return thing; @@ -97,15 +110,15 @@ function matchTagName(ref, data, quiet) { } const find = { - album: findHelper(['album', 'album-commentary'], 'albumData'), - artist: findHelper(['artist', 'artist-gallery'], 'artistData'), - artTag: findHelper(['tag'], 'artTagData', {byName: matchTagName}), - flash: findHelper(['flash'], 'flashData'), - group: findHelper(['group', 'group-gallery'], 'groupData'), - listing: findHelper(['listing'], 'listingSpec'), - newsEntry: findHelper(['news-entry'], 'newsData'), - staticPage: findHelper(['static'], 'staticPageData'), - track: findHelper(['track'], 'trackData') + album: findHelper(['album', 'album-commentary']), + artist: findHelper(['artist', 'artist-gallery']), + artTag: findHelper(['tag'], {byName: matchTagName}), + flash: findHelper(['flash']), + group: findHelper(['group', 'group-gallery']), + listing: findHelper(['listing']), + newsEntry: findHelper(['news-entry']), + staticPage: findHelper(['static']), + track: findHelper(['track']) }; export default find; diff --git a/src/util/replacer.js b/src/util/replacer.js index 6c524778..0066d218 100644 --- a/src/util/replacer.js +++ b/src/util/replacer.js @@ -1,8 +1,7 @@ -import find from './find.js'; import {logError, logWarn} from './cli.js'; import {escapeRegex} from './sugar.js'; -export function validateReplacerSpec(replacerSpec, link) { +export function validateReplacerSpec(replacerSpec, {find, link}) { let success = true; for (const [key, {link: linkKey, find: findKey, value, html}] of Object.entries(replacerSpec)) { @@ -320,7 +319,7 @@ export function parseInput(input) { } function evaluateTag(node, opts) { - const { input, link, replacerSpec, strings, to, wikiData } = opts; + const { find, input, link, replacerSpec, strings, to, wikiData } = opts; const source = input.slice(node.i, node.iEnd); @@ -348,7 +347,7 @@ function evaluateTag(node, opts) { valueFn ? valueFn(replacerValue) : findKey ? find[findKey]((replacerKeyImplied ? replacerValue - : replacerKey + `:` + replacerValue), {wikiData}) : + : replacerKey + `:` + replacerValue)) : { directory: replacerValue, name: null @@ -417,13 +416,14 @@ function transformNodes(nodes, opts) { return nodes.map(node => transformNode(node, opts)).join(''); } -export function transformInline(input, {replacerSpec, link, strings, to, wikiData}) { +export function transformInline(input, {replacerSpec, find, link, strings, to, wikiData}) { if (!replacerSpec) throw new Error('Expected replacerSpec'); + if (!find) throw new Error('Expected find'); if (!link) throw new Error('Expected link'); if (!strings) throw new Error('Expected strings'); if (!to) throw new Error('Expected to'); if (!wikiData) throw new Error('Expected wikiData'); const nodes = parseInput(input); - return transformNodes(nodes, {input, link, replacerSpec, strings, to, wikiData}); + return transformNodes(nodes, {input, find, link, replacerSpec, strings, to, wikiData}); } -- cgit 1.3.0-6-gf8a5