78 lines
2.5 KiB
JavaScript
78 lines
2.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import { createHash } from "node:crypto";
|
|
import {
|
|
cpSync,
|
|
existsSync,
|
|
readFileSync,
|
|
renameSync,
|
|
rmSync,
|
|
writeFileSync,
|
|
} from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const assetReferencePattern =
|
|
/(\b(?:src|href)=")(\.\/assets\/([^"?]+\.(?:css|js)))(?:\?v=[^"]+)?(")/g;
|
|
|
|
export function cacheBustZooModelingAppAssets(
|
|
outputDir,
|
|
{ retainOriginalAssets = false } = {}
|
|
) {
|
|
const indexPath = path.join(outputDir, "index.html");
|
|
const source = readFileSync(indexPath, "utf8");
|
|
const assetReferences = [...source.matchAll(assetReferencePattern)];
|
|
|
|
if (assetReferences.length === 0) {
|
|
const currentVersion = source.match(/\.\/assets-([a-f0-9]{12})\//)?.[1];
|
|
if (currentVersion) {
|
|
return { assetCount: 0, version: currentVersion };
|
|
}
|
|
throw new Error(`No HiCAD entry assets found in ${indexPath}`);
|
|
}
|
|
|
|
const assetsDir = path.join(outputDir, "assets");
|
|
const contentHash = createHash("sha256");
|
|
for (const reference of assetReferences.sort((a, b) =>
|
|
a[3].localeCompare(b[3])
|
|
)) {
|
|
contentHash.update(reference[3]);
|
|
contentHash.update(readFileSync(path.join(assetsDir, reference[3])));
|
|
}
|
|
|
|
const version = contentHash.digest("hex").slice(0, 12);
|
|
const versionedAssetsName = `assets-${version}`;
|
|
const versionedAssetsDir = path.join(outputDir, versionedAssetsName);
|
|
rmSync(versionedAssetsDir, { force: true, recursive: true });
|
|
if (retainOriginalAssets) {
|
|
cpSync(assetsDir, versionedAssetsDir, { recursive: true });
|
|
} else {
|
|
renameSync(assetsDir, versionedAssetsDir);
|
|
}
|
|
|
|
const versionedSource = source.replace(
|
|
assetReferencePattern,
|
|
(_match, prefix, _assetReference, assetPath, suffix) =>
|
|
`${prefix}./${versionedAssetsName}/${assetPath}${suffix}`
|
|
);
|
|
writeFileSync(indexPath, versionedSource);
|
|
return { assetCount: assetReferences.length, version };
|
|
}
|
|
|
|
const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : "";
|
|
if (invokedPath === fileURLToPath(import.meta.url)) {
|
|
const outputDir = path.resolve(
|
|
process.argv.slice(2).find((argument) => !argument.startsWith("--")) ||
|
|
"public/vendor/zoo-modeling-app"
|
|
);
|
|
if (!existsSync(outputDir)) {
|
|
throw new Error(`HiCAD output directory does not exist: ${outputDir}`);
|
|
}
|
|
const { assetCount, version } = cacheBustZooModelingAppAssets(outputDir, {
|
|
retainOriginalAssets: process.argv.includes("--retain-original"),
|
|
});
|
|
console.log(
|
|
`Versioned ${assetCount} HiCAD entry assets as assets-${version} in ${outputDir}`
|
|
);
|
|
}
|