UNPKG

aubade

Version:

filesystem-based content processor

79 lines (78 loc) 2.72 kB
import * as fs from 'fs/promises'; import { engrave } from '../artisan/index.js'; import { assemble } from '../core/index.js'; export async function orchestrate(entry, inspect = ({ path }) => { if (!path.endsWith('.md')) return; return async ({ assemble, buffer }) => { const { manifest, md, meta } = assemble(buffer.toString('utf-8')); if (!manifest) return; return { ...manifest, words: meta.words, content: md.html() }; }; }) { const results = []; const pending = []; async function scan(current, { depth = 0 } = {}) { const tree = await fs.readdir(current, { withFileTypes: true }); const files = tree.flatMap((i) => { if (i.isDirectory()) return []; return { filename: i.name, get buffer() { return fs.readFile(catenate(current, i.name)); }, }; }); for (const item of tree) { const path = catenate(current, item.name); if (item.isDirectory()) { pending.push(scan(path, { depth: depth + 1 })); continue; } const hydrate = inspect({ breadcrumb: path.split(/[/\\]/).reverse(), depth, path, parent: current, }); if (hydrate) { const transformed = hydrate({ assemble, buffer: await fs.readFile(path), engrave, siblings: files.filter(({ filename }) => filename !== item.name), task: (fn) => pending.push(fn({ fs })), }); results.push(transformed); } } } await scan(entry); // await for the initial scan to complete while (pending.length) await Promise.all(pending.splice(0)); return (await Promise.all(results)).filter((i) => !!i); } function catenate(...paths) { if (!paths.length) return '.'; const index = paths[0].replace(/\\/g, '/').trim(); if (paths.length === 1 && index === '') return '.'; const parts = index.replace(/[/]*$/g, '').split('/'); if (parts[0] === '') parts.shift(); for (let i = 1; i < paths.length; i += 1) { const part = paths[i].replace(/\\/g, '/').trim(); for (const slice of part.split('/')) { if (slice === '.') continue; if (slice === '..') parts.pop(); else if (slice) parts.push(slice); } } return (index[0] === '/' ? '/' : '') + parts.join('/'); }