Files
roast_command_center/scripts/stamp-asset-version.mjs

40 lines
1.4 KiB
JavaScript

import { createHash } from "node:crypto";
import { readFile, writeFile, readdir } from "node:fs/promises";
import path from "node:path";
const PLACEHOLDER = "__ASSET_VERSION__";
const root = path.resolve(process.argv[2] || process.cwd());
const assetRoots = ["public", "shared"];
async function walk(directory) {
const entries = await readdir(directory, { withFileTypes: true });
const files = await Promise.all(
entries.map((entry) => {
const target = path.join(directory, entry.name);
return entry.isDirectory() ? walk(target) : target;
}),
);
return files.flat().sort();
}
const files = (
await Promise.all(assetRoots.map((directory) => walk(path.join(root, directory))))
).flat();
const sources = await Promise.all(files.map((file) => readFile(file, "utf8")));
const version = createHash("sha256")
.update(files.map((file, index) => `${path.relative(root, file)}\0${sources[index]}`).join("\0"))
.digest("hex")
.slice(0, 16);
let replacements = 0;
await Promise.all(
files.map(async (file, index) => {
const source = sources[index];
const count = source.split(PLACEHOLDER).length - 1;
if (!count) return;
replacements += count;
await writeFile(file, source.replaceAll(PLACEHOLDER, version));
}),
);
if (!replacements) throw new Error(`No ${PLACEHOLDER} markers found under ${assetRoots.join(", ")}.`);
console.log(`Stamped ${replacements} asset references with version ${version}.`);