const fs = require("fs"); const path = require("path"); const { execSync } = require("child_process"); const esbuild = require("esbuild"); const DIST_CHROME = path.join(__dirname, "dist", "chrome"); const DIST_FIREFOX = path.join(__dirname, "dist", "firefox"); const SRC = path.join(__dirname, "src"); function ensureDir(dir) { fs.mkdirSync(dir, { recursive: true }); } function getBuildInfo() { const pkg = JSON.parse( fs.readFileSync(path.join(__dirname, "package.json"), "utf8"), ); let commitHash = "unknown"; try { commitHash = execSync("git rev-parse --short HEAD", { encoding: "utf8", }).trim(); } catch (_) { // not a git repo or git not available } let commitHashFull = "unknown"; try { commitHashFull = execSync("git rev-parse HEAD", { encoding: "utf8", }).trim(); } catch (_) { // not a git repo or git not available } return { version: pkg.version, license: pkg.license, author: pkg.author, commitHash, commitHashFull, buildDate: new Date().toISOString().slice(0, 10), }; } async function build() { console.log("Building AutistMask extension..."); const buildInfo = getBuildInfo(); console.log("Build info:", buildInfo); const define = { __BUILD_VERSION__: JSON.stringify(buildInfo.version), __BUILD_LICENSE__: JSON.stringify(buildInfo.license), __BUILD_AUTHOR__: JSON.stringify(buildInfo.author), __BUILD_COMMIT__: JSON.stringify(buildInfo.commitHash), __BUILD_COMMIT_FULL__: JSON.stringify(buildInfo.commitHashFull), __BUILD_DATE__: JSON.stringify(buildInfo.buildDate), }; // compile tailwind CSS console.log("Compiling Tailwind CSS..."); const tailwindInput = path.join(SRC, "popup", "styles", "main.css"); const tailwindOutput = path.join(__dirname, "dist", "styles.css"); ensureDir(path.join(__dirname, "dist")); execSync( `npx @tailwindcss/cli -i ${tailwindInput} -o ${tailwindOutput} --minify`, { stdio: "inherit" }, ); for (const distDir of [DIST_CHROME, DIST_FIREFOX]) { ensureDir(path.join(distDir, "src", "popup")); ensureDir(path.join(distDir, "src", "background")); ensureDir(path.join(distDir, "src", "content")); // bundle popup JS with esbuild (inlines ethers, libsodium, etc.) await esbuild.build({ entryPoints: [path.join(SRC, "popup", "index.js")], bundle: true, format: "iife", outfile: path.join(distDir, "src", "popup", "index.js"), platform: "browser", target: ["chrome110", "firefox110"], minify: true, define, }); // bundle background script await esbuild.build({ entryPoints: [path.join(SRC, "background", "index.js")], bundle: true, format: "iife", outfile: path.join(distDir, "src", "background", "index.js"), platform: "browser", target: ["chrome110", "firefox110"], minify: true, define, }); // bundle content script await esbuild.build({ entryPoints: [path.join(SRC, "content", "index.js")], bundle: true, format: "iife", outfile: path.join(distDir, "src", "content", "index.js"), platform: "browser", target: ["chrome110", "firefox110"], minify: true, define, }); // bundle inpage script (injected into page context, separate file) await esbuild.build({ entryPoints: [path.join(SRC, "content", "inpage.js")], bundle: true, format: "iife", outfile: path.join(distDir, "src", "content", "inpage.js"), platform: "browser", target: ["chrome110", "firefox110"], minify: true, define, }); // copy popup HTML fs.copyFileSync( path.join(SRC, "popup", "index.html"), path.join(distDir, "src", "popup", "index.html"), ); // place compiled CSS next to popup HTML fs.copyFileSync( tailwindOutput, path.join(distDir, "src", "popup", "styles.css"), ); } // copy manifests fs.copyFileSync( path.join(__dirname, "manifest", "chrome.json"), path.join(DIST_CHROME, "manifest.json"), ); fs.copyFileSync( path.join(__dirname, "manifest", "firefox.json"), path.join(DIST_FIREFOX, "manifest.json"), ); console.log("Build complete: dist/chrome/ and dist/firefox/"); } build();