Files
BridgeSwarm/scripts/pack-extension.js
T
Raven Scott 83af298eb5
CI / Build & Test (push) Successful in 8m7s
Updates and add examples host
2026-07-26 23:50:17 -04:00

118 lines
3.7 KiB
JavaScript

/**
* Pack the browser extension into a zip (Chrome) and .xpi (Firefox).
* Zip contains manifest.json (Chrome, with "key").
* XPI contains manifest_firefox.json as manifest.json (no "key").
* Output: releases/BridgeSwarm-<version>.zip, releases/BridgeSwarm-<version>.xpi
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const archiver = require('archiver');
const REPO_ROOT = path.resolve(__dirname, '..');
const EXT_DIR = path.join(REPO_ROOT, 'extension');
const RELEASES_DIR = path.join(REPO_ROOT, 'releases');
const EXCLUDE_NAMES = new Set(['protomux-entry.cjs']);
const EXCLUDE_EXTS = new Set(['.map']);
function getVersion() {
const manifestPath = path.join(EXT_DIR, 'manifest.json');
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
if (!manifest.version) throw new Error('extension/manifest.json missing version');
return manifest.version;
}
function listExtensionFiles(dir, base = dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
const files = [];
for (const e of entries) {
const full = path.join(dir, e.name);
const rel = path.relative(base, full).replace(/\\/g, '/');
if (e.isDirectory()) {
files.push(...listExtensionFiles(full, base));
} else {
const ext = path.extname(e.name);
if (EXCLUDE_NAMES.has(e.name) || EXCLUDE_EXTS.has(ext)) continue;
files.push({ full, rel });
}
}
return files;
}
function createZip(version) {
const zipPath = path.join(RELEASES_DIR, `BridgeSwarm-${version}.zip`);
const output = fs.createWriteStream(zipPath);
const archive = archiver('zip', { zlib: { level: 9 } });
return new Promise((resolve, reject) => {
output.on('close', () => resolve(zipPath));
archive.on('error', reject);
archive.pipe(output);
const files = listExtensionFiles(EXT_DIR).filter(({ rel }) => rel !== 'manifest_firefox.json');
for (const { full, rel } of files) {
archive.file(full, { name: rel });
}
archive.finalize();
});
}
function createXpi(version) {
const firefoxManifestPath = path.join(EXT_DIR, 'manifest_firefox.json');
if (!fs.existsSync(firefoxManifestPath)) {
throw new Error('extension/manifest_firefox.json missing — run scripts/generate-extension-id.js');
}
const xpiPath = path.join(RELEASES_DIR, `BridgeSwarm-${version}.xpi`);
const output = fs.createWriteStream(xpiPath);
const archive = archiver('zip', { zlib: { level: 9 } });
return new Promise((resolve, reject) => {
output.on('close', () => resolve(xpiPath));
archive.on('error', reject);
archive.pipe(output);
const files = listExtensionFiles(EXT_DIR).filter(
({ rel }) => rel !== 'manifest.json' && rel !== 'manifest_firefox.json'
);
for (const { full, rel } of files) {
archive.file(full, { name: rel });
}
archive.file(firefoxManifestPath, { name: 'manifest.json' });
archive.finalize();
});
}
async function main() {
const version = getVersion();
console.log('BridgeSwarm version from manifest:', version);
console.log('Syncing examples into extension...');
execSync('node scripts/sync-examples.js', { cwd: REPO_ROOT, stdio: 'inherit' });
console.log('Running npm run build:protomux...');
execSync('npm run build:protomux', { cwd: REPO_ROOT, stdio: 'inherit' });
if (!fs.existsSync(RELEASES_DIR)) {
fs.mkdirSync(RELEASES_DIR, { recursive: true });
console.log('Created releases/');
}
try {
console.log('Creating Chrome zip...');
const zipPath = await createZip(version);
console.log('Written:', zipPath);
console.log('Creating Firefox xpi...');
const xpiPath = await createXpi(version);
console.log('Written:', xpiPath);
} catch (err) {
console.error(err);
process.exit(1);
}
}
main();