diff --git a/.github/workflows/deploy-web.yml b/.github/workflows/deploy-web.yml index dcee214..5a462c3 100644 --- a/.github/workflows/deploy-web.yml +++ b/.github/workflows/deploy-web.yml @@ -7,6 +7,7 @@ on: paths: - "packages/web/**" - "packages/core/**" + - "docs/privacy-policy.md" - ".github/workflows/deploy-web.yml" - "pnpm-lock.yaml" # Allow manual re-deploy from the Actions UI. diff --git a/packages/web/package.json b/packages/web/package.json index 7acf174..69dac66 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -6,6 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc --noEmit && vite build", + "postbuild": "node ./scripts/build-privacy.mjs", "preview": "vite preview", "typecheck": "tsc --noEmit", "test": "vitest run", @@ -27,6 +28,7 @@ "@vitejs/plugin-react": "^4.3.0", "autoprefixer": "^10.4.0", "jsdom": "^25.0.0", + "marked": "^18.0.5", "postcss": "^8.4.0", "tailwindcss": "^3.4.0", "vite": "^5.4.0", diff --git a/packages/web/scripts/build-privacy.mjs b/packages/web/scripts/build-privacy.mjs new file mode 100644 index 0000000..041b762 --- /dev/null +++ b/packages/web/scripts/build-privacy.mjs @@ -0,0 +1,57 @@ +// Render docs/privacy-policy.md (the single source of truth) into +// dist/privacy.html so the Pages deploy serves it at /privacy.html — the +// URL the Chrome Web Store / AMO listings point at. Runs as postbuild. +import { readFileSync, writeFileSync, existsSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { marked } from "marked"; + +const here = dirname(fileURLToPath(import.meta.url)); +const mdPath = resolve(here, "../../../docs/privacy-policy.md"); +const outPath = resolve(here, "../dist/privacy.html"); + +if (!existsSync(mdPath)) throw new Error(`privacy policy source not found: ${mdPath}`); +if (!existsSync(dirname(outPath))) throw new Error(`dist/ not found — run vite build first`); + +const body = marked.parse(readFileSync(mdPath, "utf8"), { async: false }); + +// Palette mirrors the web UI (tailwind.config.ts): +// ink #0a0a0f, mist #16161e, fog #23232e, cyan #22d3ee, magenta #e879f9. +const html = ` + + + + + +gitmarks — privacy policy + + + +${body} + + + +`; + +writeFileSync(outPath, html); +console.log("[web] rendered privacy policy to dist/privacy.html"); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 50e10c5..484e9d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -130,6 +130,9 @@ importers: jsdom: specifier: ^25.0.0 version: 25.0.1 + marked: + specifier: ^18.0.5 + version: 18.0.5 postcss: specifier: ^8.4.0 version: 8.5.15 @@ -1194,6 +1197,11 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + marked@18.0.5: + resolution: {integrity: sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==} + engines: {node: '>= 20'} + hasBin: true + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -2637,6 +2645,8 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + marked@18.0.5: {} + math-intrinsics@1.1.0: {} merge2@1.4.1: {}