diff options
Diffstat (limited to 'src/util/urls.js')
-rw-r--r-- | src/util/urls.js | 196 |
1 files changed, 107 insertions, 89 deletions
diff --git a/src/util/urls.js b/src/util/urls.js index e15c018b..45ec4c85 100644 --- a/src/util/urls.js +++ b/src/util/urls.js @@ -1,3 +1,5 @@ +/** @format */ + // Code that deals with URLs (really the pathnames that get referenced all // throughout the gener8ted HTML). Most nota8ly here is generateURLs, which // is in charge of pre-gener8ting a complete network of template strings @@ -9,116 +11,132 @@ // the domain of link.js. import * as path from 'path'; -import { withEntries } from './sugar.js'; +import {withEntries} from './sugar.js'; export function generateURLs(urlSpec) { - const getValueForFullKey = (obj, fullKey, prop = null) => { - const [ groupKey, subKey ] = fullKey.split('.'); - if (!groupKey || !subKey) { - throw new Error(`Expected group key and subkey (got ${fullKey})`); - } - - if (!obj.hasOwnProperty(groupKey)) { - throw new Error(`Expected valid group key (got ${groupKey})`); - } - - const group = obj[groupKey]; - - if (!group.hasOwnProperty(subKey)) { - throw new Error(`Expected valid subkey (got ${subKey} for group ${groupKey})`); - } - - return { - value: group[subKey], - group - }; + const getValueForFullKey = (obj, fullKey) => { + const [groupKey, subKey] = fullKey.split('.'); + if (!groupKey || !subKey) { + throw new Error(`Expected group key and subkey (got ${fullKey})`); + } + + if (!Object.hasOwn(obj, groupKey)) { + throw new Error(`Expected valid group key (got ${groupKey})`); + } + + const group = obj[groupKey]; + + if (!Object.hasOwn(group, subKey)) { + throw new Error( + `Expected valid subkey (got ${subKey} for group ${groupKey})` + ); + } + + return { + value: group[subKey], + group, }; + }; - // This should be called on values which are going to be passed to - // path.relative, because relative will resolve a leading slash as the root - // directory of the working device, which we aren't looking for here. - const trimLeadingSlash = P => P.startsWith('/') ? P.slice(1) : P; - - const generateTo = (fromPath, fromGroup) => { - const A = trimLeadingSlash(fromPath); + // This should be called on values which are going to be passed to + // path.relative, because relative will resolve a leading slash as the root + // directory of the working device, which we aren't looking for here. + const trimLeadingSlash = (P) => (P.startsWith('/') ? P.slice(1) : P); - const rebasePrefix = '../'.repeat((fromGroup.prefix || '').split('/').filter(Boolean).length); + const generateTo = (fromPath, fromGroup) => { + const A = trimLeadingSlash(fromPath); - const pathHelper = (toPath, toGroup) => { - let B = trimLeadingSlash(toPath); + const rebasePrefix = '../'.repeat( + (fromGroup.prefix || '').split('/').filter(Boolean).length + ); - let argIndex = 0; - B = B.replaceAll('<>', () => `<${argIndex++}>`); + const pathHelper = (toPath, toGroup) => { + let B = trimLeadingSlash(toPath); - if (toGroup.prefix !== fromGroup.prefix) { - // TODO: Handle differing domains in prefixes. - B = rebasePrefix + (toGroup.prefix || '') + B; - } + let argIndex = 0; + B = B.replaceAll('<>', () => `<${argIndex++}>`); - const suffix = (toPath.endsWith('/') ? '/' : ''); + if (toGroup.prefix !== fromGroup.prefix) { + // TODO: Handle differing domains in prefixes. + B = rebasePrefix + (toGroup.prefix || '') + B; + } - return { - posix: path.posix.relative(A, B) + suffix, - device: path.relative(A, B) + suffix - }; - }; + const suffix = toPath.endsWith('/') ? '/' : ''; - const groupSymbol = Symbol(); + return { + posix: path.posix.relative(A, B) + suffix, + device: path.relative(A, B) + suffix, + }; + }; - const groupHelper = urlGroup => ({ - [groupSymbol]: urlGroup, - ...withEntries(urlGroup.paths, entries => entries - .map(([key, path]) => [key, pathHelper(path, urlGroup)])) + const groupSymbol = Symbol(); + + const groupHelper = (urlGroup) => ({ + [groupSymbol]: urlGroup, + ...withEntries(urlGroup.paths, (entries) => + entries.map(([key, path]) => [key, pathHelper(path, urlGroup)]) + ), + }); + + const relative = withEntries(urlSpec, (entries) => + entries.map(([key, urlGroup]) => [key, groupHelper(urlGroup)]) + ); + + const toHelper = + (delimiterMode) => + (key, ...args) => { + const { + value: {[delimiterMode]: template}, + } = getValueForFullKey(relative, key); + + let missing = 0; + let result = template.replaceAll(/<([0-9]+)>/g, (match, n) => { + if (n < args.length) { + return args[n]; + } else { + missing++; + } }); - const relative = withEntries(urlSpec, entries => entries - .map(([key, urlGroup]) => [key, groupHelper(urlGroup)])); - - const toHelper = (delimiterMode) => (key, ...args) => { - const { - value: {[delimiterMode]: template} - } = getValueForFullKey(relative, key); - - let missing = 0; - let result = template.replaceAll(/<([0-9]+)>/g, (match, n) => { - if (n < args.length) { - return args[n]; - } else { - missing++; - } - }); - - if (missing) { - throw new Error(`Expected ${missing + args.length} arguments, got ${args.length} (key ${key}, args [${args}])`); - } - - return result; - }; - - return { - to: toHelper('posix'), - toDevice: toHelper('device') - }; + if (missing) { + throw new Error( + `Expected ${missing + args.length} arguments, got ${ + args.length + } (key ${key}, args [${args}])` + ); + } + + return result; + }; + + return { + to: toHelper('posix'), + toDevice: toHelper('device'), }; + }; - const generateFrom = () => { - const map = withEntries(urlSpec, entries => entries - .map(([key, group]) => [key, withEntries(group.paths, entries => entries - .map(([key, path]) => [key, generateTo(path, group)]) - )])); + const generateFrom = () => { + const map = withEntries(urlSpec, (entries) => + entries.map(([key, group]) => [ + key, + withEntries(group.paths, (entries) => + entries.map(([key, path]) => [key, generateTo(path, group)]) + ), + ]) + ); - const from = key => getValueForFullKey(map, key).value; + const from = (key) => getValueForFullKey(map, key).value; - return {from, map}; - }; + return {from, map}; + }; - return generateFrom(); + return generateFrom(); } -const thumbnailHelper = name => file => - file.replace(/\.(jpg|png)$/, name + '.jpg'); +const thumbnailHelper = (name) => (file) => + file.replace(/\.(jpg|png)$/, name + '.jpg'); export const thumb = { - medium: thumbnailHelper('.medium'), - small: thumbnailHelper('.small') + medium: thumbnailHelper('.medium'), + small: thumbnailHelper('.small'), }; |