fix: declare and ship toolbar icons, so neither browser renders a puzzle piece (closes #371)
Neither manifest declared any icons, so both browsers showed a generic puzzle-piece -- the first thing seen on every browser start, and how a user tells a real extension from a look-alike. Both manifests now declare 16/32/48/128, and the PNGs ship inside each browser archive rather than being left at dist/ root, which is the trap that made a naive zip incomplete before. build.js reads which icons to copy from each manifest's own icons block, so the manifest is the single source of truth and a declared-but-absent size fails the build rather than shipping a dangling reference; the packager's reference-resolver covers them independently. Manifest values are constrained before being joined into a path. The artwork is original, generated from geometry rather than traced or fetched.
This commit was merged in pull request #376.
This commit is contained in:
49
build.js
49
build.js
@@ -51,6 +51,17 @@ const RECEIPT_ENV = "AUTISTMASK_BUILD_RECEIPT";
|
||||
// rather than writing a receipt that cannot be checked.
|
||||
const SAFE_EMITTED_PATH = /^dist\/[A-Za-z0-9._][A-Za-z0-9._/-]*$/;
|
||||
|
||||
// Where each browser directory's manifest comes from, and — through its
|
||||
// "icons" — which image files ship inside that directory.
|
||||
const MANIFEST_SOURCES = new Map([
|
||||
[DIST_CHROME, path.join(__dirname, "manifest", "chrome.json")],
|
||||
[DIST_FIREFOX, path.join(__dirname, "manifest", "firefox.json")],
|
||||
]);
|
||||
|
||||
// What an "icons" entry may name: a plain file under icons/, so a manifest
|
||||
// value is never joined into a path that leaves the repo.
|
||||
const ICON_REF_RE = /^icons\/[A-Za-z0-9._-]+\.png$/;
|
||||
|
||||
function ensureDir(dir) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
@@ -257,6 +268,42 @@ function copyEmitted(src, dest) {
|
||||
recordEmitted(dest);
|
||||
}
|
||||
|
||||
// Copy the icons one browser directory ships. The sizes come from the manifest
|
||||
// that will sit next to them, not from a second list here: a size the manifest
|
||||
// declares and icons/ does not hold fails the build, rather than shipping a
|
||||
// manifest whose reference resolves to nothing. Relative to the browser
|
||||
// directory, so nothing points up and out of it the way dist/styles.css does.
|
||||
function copyIcons(distDir) {
|
||||
const manifestPath = MANIFEST_SOURCES.get(distDir);
|
||||
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
||||
const refs = Object.values(manifest.icons || {});
|
||||
if (refs.length === 0) {
|
||||
throw new Error(
|
||||
`${repoRelative(manifestPath)} declares no icons, so the browser ` +
|
||||
`renders a generic placeholder for this extension`,
|
||||
);
|
||||
}
|
||||
for (const ref of refs) {
|
||||
if (!ICON_REF_RE.test(ref)) {
|
||||
throw new Error(
|
||||
`${repoRelative(manifestPath)} declares icon ` +
|
||||
`${JSON.stringify(ref)}, which is not a plain file under ` +
|
||||
`icons/`,
|
||||
);
|
||||
}
|
||||
const src = path.join(__dirname, ref);
|
||||
if (!fs.existsSync(src)) {
|
||||
throw new Error(
|
||||
`${repoRelative(manifestPath)} declares ${ref}, which is not ` +
|
||||
`in this tree`,
|
||||
);
|
||||
}
|
||||
const dest = path.join(distDir, ref);
|
||||
ensureDir(path.dirname(dest));
|
||||
copyEmitted(src, dest);
|
||||
}
|
||||
}
|
||||
|
||||
function sha256File(absPath) {
|
||||
return crypto
|
||||
.createHash("sha256")
|
||||
@@ -524,6 +571,8 @@ async function build() {
|
||||
tailwindOutput,
|
||||
path.join(distDir, "src", "popup", "styles.css"),
|
||||
);
|
||||
|
||||
copyIcons(distDir);
|
||||
}
|
||||
|
||||
// copy manifests
|
||||
|
||||
Reference in New Issue
Block a user