UNPKG

@scaffdog/config

Version:
81 lines (77 loc) 2.15 kB
import { z } from 'zod'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import createJITI from 'jiti'; const variableSchema = z.lazy( () => z.union([z.string(), z.record(variableSchema), z.array(variableSchema)]) ); const configSchema = z.object({ files: z.array(z.string()), variables: z.record(variableSchema).optional(), helpers: z.array(z.union([z.function(), z.record(z.string(), z.any())])).optional(), tags: z.tuple([z.string(), z.string()]).optional() }); const validateConfig = (maybeConfig) => { return configSchema.parse(maybeConfig); }; const jiti = createJITI(fileURLToPath(import.meta.url), { cache: false, interopDefault: true, requireCache: false, esmResolve: true }); const extensions = ["js", "cjs", "mjs", "ts"]; const obj2map = (obj) => { return new Map(Object.entries(obj)); }; const fstat = (filepath) => { try { return fs.statSync(filepath); } catch (e) { return null; } }; const fileExists = (filepath) => fstat(filepath)?.isFile() ?? false; const normalizeHelpers = (helpers) => { let map = /* @__PURE__ */ new Map(); (helpers ?? []).forEach((value) => { if (typeof value === "function") { value(map); } else { map = new Map([...map, ...obj2map(value)]); } }); return map; }; const loadConfig = (project) => { const dirname = project ?? path.resolve(process.cwd(), ".scaffdog"); let filepath = ""; let maybeConfig; for (const ext of extensions) { filepath = path.resolve(dirname, `config.${ext}`); if (!fileExists(filepath)) { continue; } maybeConfig = jiti(filepath); if (maybeConfig != null) { break; } } if (maybeConfig == null) { const expected = `config.{${extensions.join(",")}}`; throw new Error( `scaffdog configuration file not found (filename expected: "${expected}" in "${dirname}")` ); } const config = validateConfig(maybeConfig); return { filepath, config: { ...config, variables: obj2map(config.variables ?? {}), helpers: normalizeHelpers(config.helpers) } }; }; export { loadConfig, validateConfig };