diff --git a/scripts/cache-bust-zoo-modeling-app-assets.mjs b/scripts/cache-bust-zoo-modeling-app-assets.mjs new file mode 100644 index 000000000..98dbe158b --- /dev/null +++ b/scripts/cache-bust-zoo-modeling-app-assets.mjs @@ -0,0 +1,44 @@ +#!/usr/bin/env node + +import { createHash } from "node:crypto"; +import { readFileSync, 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) { + const indexPath = path.join(outputDir, "index.html"); + const source = readFileSync(indexPath, "utf8"); + let versionedAssetCount = 0; + + const versionedSource = source.replace( + assetReferencePattern, + (_match, prefix, assetReference, suffix) => { + const assetPath = path.join(outputDir, assetReference.slice(2)); + const version = createHash("sha256") + .update(readFileSync(assetPath)) + .digest("hex") + .slice(0, 12); + versionedAssetCount += 1; + return `${prefix}${assetReference}?v=${version}${suffix}`; + } + ); + + if (versionedAssetCount === 0) { + throw new Error(`No versioned HiCAD assets found in ${indexPath}`); + } + + writeFileSync(indexPath, versionedSource); + return versionedAssetCount; +} + +const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : ""; +if (invokedPath === fileURLToPath(import.meta.url)) { + const outputDir = path.resolve( + process.argv[2] || "public/vendor/zoo-modeling-app" + ); + const assetCount = cacheBustZooModelingAppAssets(outputDir); + console.log(`Versioned ${assetCount} HiCAD entry assets in ${outputDir}`); +} diff --git a/scripts/vendor-zoo-modeling-app.mjs b/scripts/vendor-zoo-modeling-app.mjs index 33a0b12c5..dfeddebe8 100644 --- a/scripts/vendor-zoo-modeling-app.mjs +++ b/scripts/vendor-zoo-modeling-app.mjs @@ -13,6 +13,7 @@ import { import { cp } from "node:fs/promises"; import path from "node:path"; import { gzipSync } from "node:zlib"; +import { cacheBustZooModelingAppAssets } from "./cache-bust-zoo-modeling-app-assets.mjs"; const repoUrl = "https://github.com/KittyCAD/modeling-app.git"; const repoRef = @@ -338,6 +339,7 @@ async function main() { if (!existsSync(path.join(buildDir, "index.html"))) { throw new Error("Zoo Design Studio build did not produce index.html"); } + cacheBustZooModelingAppAssets(buildDir); rmSync(outputDir, { force: true, recursive: true }); mkdirSync(path.dirname(outputDir), { recursive: true });