From 385faccb5a5be64acd5ca65ace26d6a7db37b64f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 16 Apr 2022 23:37:12 -0300 Subject: HSMusic REPL + supporting internal improvements --- src/util/cli.js | 1 + src/util/find.js | 29 +++++++++++++++++++++++++++++ src/util/io.js | 14 ++++++++++++++ src/util/sugar.js | 17 ++++++++++++++--- 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 src/util/io.js (limited to 'src/util') diff --git a/src/util/cli.js b/src/util/cli.js index 4b2d3498..0bbf3af4 100644 --- a/src/util/cli.js +++ b/src/util/cli.js @@ -17,6 +17,7 @@ const C = n => (ENABLE_COLOR export const color = { bright: C('1'), dim: C('2'), + normal: C('22'), black: C('30'), red: C('31'), green: C('32'), diff --git a/src/util/find.js b/src/util/find.js index dd39bad9..7cedb3d2 100644 --- a/src/util/find.js +++ b/src/util/find.js @@ -124,3 +124,32 @@ const find = { }; export default find; + +// Handy utility function for binding the find.thing() functions to a complete +// wikiData object, optionally taking default options to provide to the find +// function. Note that this caches the arrays read from wikiData right when it's +// called, so if their values change, you'll have to continue with a fresh call +// to bindFind. +export function bindFind(wikiData, opts1) { + return Object.fromEntries(Object.entries({ + album: 'albumData', + artist: 'artistData', + artTag: 'artTagData', + flash: 'flashData', + group: 'groupData', + listing: 'listingSpec', + newsEntry: 'newsData', + staticPage: 'staticPageData', + track: 'trackData', + }).map(([ key, value ]) => { + const findFn = find[key]; + const thingData = wikiData[value]; + return [key, (opts1 + ? (ref, opts2) => (opts2 + ? findFn(ref, thingData, {...opts1, ...opts2}) + : findFn(ref, thingData, opts1)) + : (ref, opts2) => (opts2 + ? findFn(ref, thingData, opts2) + : findFn(ref, thingData)))]; + })); +} diff --git a/src/util/io.js b/src/util/io.js new file mode 100644 index 00000000..1d74399f --- /dev/null +++ b/src/util/io.js @@ -0,0 +1,14 @@ +// Utility functions for interacting with files and other external data +// interfacey constructs. + +import { readdir } from 'fs/promises'; +import * as path from 'path'; + +export async function findFiles(dataPath, { + filter = f => true, + joinParentDirectory = true, +} = {}) { + return (await readdir(dataPath)) + .filter(file => filter(file)) + .map(file => joinParentDirectory ? path.join(dataPath, file) : file); +} diff --git a/src/util/sugar.js b/src/util/sugar.js index 7a132271..f425989b 100644 --- a/src/util/sugar.js +++ b/src/util/sugar.js @@ -215,7 +215,7 @@ export function mapAggregate(array, fn, aggregateOpts) { } export function mapAggregateAsync(array, fn, { - promiseAll = Promise.all, + promiseAll = Promise.all.bind(Promise), ...aggregateOpts } = {}) { return _mapAggregate('async', promiseAll, array, fn, aggregateOpts); @@ -255,7 +255,7 @@ export function filterAggregate(array, fn, aggregateOpts) { } export async function filterAggregateAsync(array, fn, { - promiseAll = Promise.all, + promiseAll = Promise.all.bind(Promise), ...aggregateOpts } = {}) { return _filterAggregate('async', promiseAll, array, fn, aggregateOpts); @@ -370,7 +370,7 @@ export function showAggregate(topError, { const stackLine = stackLines?.find(line => line.trim().startsWith('at') && !line.includes('sugar') - && !line.includes('node:internal') + && !line.includes('node:') && !line.includes('')); const tracePart = (stackLine ? '- ' + stackLine.trim().replace(/file:\/\/(.*\.js)/, (match, pathname) => pathToFile(pathname)) @@ -399,3 +399,14 @@ export function showAggregate(topError, { console.error(recursive(topError, {level: 0})); } + +export function decorateErrorWithIndex(fn) { + return (x, index, array) => { + try { + return fn(x, index, array); + } catch (error) { + error.message = `(${color.yellow(`#${index + 1}`)}) ${error.message}`; + throw error; + } + } +} -- cgit 1.3.0-6-gf8a5