@scaffdog/config
Version:
A module to manipulate configs of scaffdog.
81 lines (77 loc) • 2.15 kB
JavaScript
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 };