mirror of
https://github.com/TautvydasDerzinskas/Thingport.git
synced 2026-10-21 14:12:25 -05:00
80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
// Packages built extensions for store upload (run a build first -- the npm zip scripts do):
|
|
//
|
|
// tsx scripts/zip.ts chrome firefox edge sources
|
|
//
|
|
// -> dist/zips/thingport-grab-<target>.zip with manifest.json at the root, and
|
|
// thingport-grab-sources.zip, the source AMO asks for to reproduce the build.
|
|
|
|
import { existsSync } from "node:fs";
|
|
import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { zipSync, type Zippable } from "fflate";
|
|
import { TARGETS, isTarget } from "./manifest";
|
|
|
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const OUT = path.join(ROOT, "dist", "zips");
|
|
// Fixed timestamp for byte-identical zips.
|
|
const MTIME = new Date("2020-01-01T00:00:00Z");
|
|
const SOURCE_ENTRIES = [
|
|
"package.json",
|
|
"package-lock.json",
|
|
"tsconfig.json",
|
|
".oxlintrc.json",
|
|
"README.md",
|
|
"scripts",
|
|
"src",
|
|
"public",
|
|
];
|
|
const IGNORED = new Set([".DS_Store", "Thumbs.db"]);
|
|
|
|
async function collect(dir: string, base: string, files: Zippable): Promise<void> {
|
|
for (const entry of (await readdir(dir, { withFileTypes: true })).toSorted((a, b) => a.name.localeCompare(b.name))) {
|
|
if (IGNORED.has(entry.name)) continue;
|
|
const full = path.join(dir, entry.name);
|
|
const rel = path.posix.join(base, entry.name);
|
|
if (entry.isDirectory()) await collect(full, rel, files);
|
|
else files[rel] = [await readFile(full), { mtime: MTIME }];
|
|
}
|
|
}
|
|
|
|
async function writeZip(name: string, files: Zippable): Promise<void> {
|
|
await mkdir(OUT, { recursive: true });
|
|
const out = path.join(OUT, name);
|
|
await writeFile(out, zipSync(files, { level: 9 }));
|
|
console.log(
|
|
`${path.relative(ROOT, out)} ${((await stat(out)).size / 1024).toFixed(1)} KB, ${Object.keys(files).length} files`,
|
|
);
|
|
}
|
|
|
|
async function zipTarget(target: string): Promise<void> {
|
|
const dir = path.join(ROOT, "dist", target);
|
|
if (!existsSync(path.join(dir, "manifest.json")))
|
|
throw new Error(`dist/${target} isn't built -- run \`npm run build:${target}\` first`);
|
|
const files: Zippable = {};
|
|
await collect(dir, "", files);
|
|
await writeZip(`thingport-grab-${target}.zip`, files);
|
|
}
|
|
|
|
async function zipSources(): Promise<void> {
|
|
const files: Zippable = {};
|
|
for (const entry of SOURCE_ENTRIES) {
|
|
const full = path.join(ROOT, entry);
|
|
if ((await stat(full)).isDirectory()) await collect(full, entry, files);
|
|
else files[entry] = [await readFile(full), { mtime: MTIME }];
|
|
}
|
|
await writeZip("thingport-grab-sources.zip", files);
|
|
}
|
|
|
|
const requested = process.argv.slice(2);
|
|
const valid = [...TARGETS, "sources"];
|
|
const unknown = requested.filter((arg) => !valid.includes(arg));
|
|
if (!requested.length || unknown.length) {
|
|
console.error(`Usage: tsx scripts/zip.ts <${valid.join("|")}>...`);
|
|
process.exit(1);
|
|
}
|
|
for (const target of requested) {
|
|
if (target === "sources") await zipSources();
|
|
else if (isTarget(target)) await zipTarget(target);
|
|
}
|