#!/usr/bin/env node /** * Replace the __BUILD_VERSION__ placeholder in the built sw.js with a * deterministic version string : the short git SHA + the build timestamp. * * Why : the service worker uses CACHE_VERSION to namespace caches and * prune stale ones at activate. If __BUILD_VERSION__ stays literal, * every deploy ships the same `veza-platform-__BUILD_VERSION__` cache * name and pre-existing browser caches never get invalidated. * * v1.0.9 W4 Day 16. */ import { readFile, writeFile } from 'node:fs/promises'; import { execSync } from 'node:child_process'; import { resolve } from 'node:path'; async function main() { const target = process.env.SW_PATH || resolve(process.cwd(), 'dist/sw.js'); let sha = 'dev'; try { sha = execSync('git rev-parse --short HEAD', { stdio: ['pipe', 'pipe', 'ignore'] }) .toString() .trim(); } catch { // Not a git checkout (e.g. CI building a tarball) — fall back to env var. sha = process.env.GITHUB_SHA?.slice(0, 7) || process.env.CI_COMMIT_SHA?.slice(0, 7) || 'dev'; } const ts = new Date().toISOString().replace(/[-:.TZ]/g, '').slice(0, 12); // YYYYMMDDHHMM const version = `${ts}-${sha}`; let content; try { content = await readFile(target, 'utf8'); } catch (err) { if (err.code === 'ENOENT') { console.warn(`[stamp-sw-version] ${target} not found — skipping (run vite build first).`); return; } throw err; } if (!content.includes('__BUILD_VERSION__')) { console.warn( `[stamp-sw-version] no __BUILD_VERSION__ placeholder in ${target} — already stamped or sw.js was rewritten without one.`, ); return; } const stamped = content.replaceAll('__BUILD_VERSION__', version); await writeFile(target, stamped, 'utf8'); console.log(`[stamp-sw-version] sw.js stamped with ${version}`); } main().catch((err) => { console.error('[stamp-sw-version] failed:', err); process.exit(1); });