@withstudiocms/config-utils
Version:
Utilities for managing configuration files
99 lines (98 loc) • 2.31 kB
JavaScript
import { constants } from "node:fs";
import { access, unlink, writeFile } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import { build as esbuild } from "esbuild";
import { tryCatch } from "./utils/tryCatch.js";
async function bundleConfigFile({ fileUrl }) {
const result = await esbuild({
absWorkingDir: process.cwd(),
entryPoints: [fileURLToPath(fileUrl)],
outfile: "out.js",
packages: "external",
write: false,
target: ["node18"],
platform: "node",
bundle: true,
format: "esm",
sourcemap: "inline",
metafile: true
});
const file = result.outputFiles[0];
if (!file) {
throw new Error("Unexpected: no output file");
}
return {
code: file.text,
dependencies: Object.keys(result.metafile.inputs)
};
}
async function importBundledFile({
code,
root,
label = "bundled-tmp.config"
}) {
const tmpFileUrl = new URL(
`./${label}.timestamp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}.mjs`,
root
);
await writeFile(tmpFileUrl, code, { encoding: "utf8" });
try {
return await import(
/* @vite-ignore */
tmpFileUrl.toString()
);
} finally {
await tryCatch(unlink(tmpFileUrl));
}
}
async function loadAndBundleConfigFile({
root,
fileUrl,
label
}) {
if (!fileUrl) {
return { mod: void 0, dependencies: [] };
}
const { code, dependencies } = await bundleConfigFile({
fileUrl
});
return {
mod: await importBundledFile({ code, root, label }),
dependencies
};
}
async function loadConfigFile(root, configPaths, label) {
let configFileUrl;
for (const path of configPaths) {
const fileUrl = new URL(path, root);
try {
await access(fileUrl, constants.F_OK);
configFileUrl = fileUrl;
break;
} catch {
}
}
if (!configFileUrl) {
return void 0;
}
const { mod: configMod } = await loadAndBundleConfigFile({
root,
fileUrl: configFileUrl,
label
});
if (!configMod) {
return void 0;
}
if (!configMod.default) {
throw new Error(
"Missing or invalid default export. Please export your config object as the default export."
);
}
return configMod.default;
}
export {
bundleConfigFile,
importBundledFile,
loadAndBundleConfigFile,
loadConfigFile
};