Files
shd.build/scripts/trim-static-icons.mjs
T
jb dd84dff055
Validate and deploy production / validate (push) Successful in 23s
Validate and deploy staging / validate (push) Successful in 50s
Validate and deploy production / deploy (push) Failing after 40s
Validate and deploy staging / deploy (push) Failing after 7s
feat: add community publishing and news syndication
2026-08-01 21:42:09 -04:00

45 lines
1.3 KiB
JavaScript

import sharp from 'sharp';
import { readdir, rename, unlink } from 'node:fs/promises';
import { join, resolve } from 'node:path';
const iconDirectory = resolve('./static');
const iconFiles = (await readdir(iconDirectory))
.filter((file) => file.toLocaleLowerCase().endsWith('.png'))
.sort((left, right) => left.localeCompare(right));
for (const file of iconFiles) {
const source = join(iconDirectory, file);
const temporary = join(iconDirectory, `.${file}.trimmed`);
const before = await sharp(source).metadata();
try {
const result = await sharp(source)
.trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } })
.extend({
top: 2,
right: 2,
bottom: 2,
left: 2,
background: { r: 0, g: 0, b: 0, alpha: 0 },
})
.png({ compressionLevel: 9, adaptiveFiltering: true })
.toFile(temporary);
if (!result.width || !result.height || result.channels !== 4) {
throw new Error(`${file} did not produce a valid transparent RGBA icon.`);
}
await rename(temporary, source);
console.log(
`${file}: ${before.width}x${before.height} -> ${result.width}x${result.height}`,
);
} catch (error) {
await unlink(temporary).catch(() => {});
throw error;
}
}
console.log(
`Trimmed ${iconFiles.length} static PNG icons with a 2px transparent safety margin.`,
);