chromium support
Release Firefox and Chromium extensions / Package and attach browser extensions (release) Successful in 54s
Release Firefox and Chromium extensions / Package and attach browser extensions (release) Successful in 54s
This commit is contained in:
+103
-20
@@ -5,7 +5,7 @@ const { mkdir, readFile, writeFile } = require("node:fs/promises");
|
||||
const path = require("node:path");
|
||||
const { deflateRawSync } = require("node:zlib");
|
||||
|
||||
const ARCHIVE_FILES = Object.freeze([
|
||||
const FIREFOX_ARCHIVE_FILES = Object.freeze([
|
||||
"background.js",
|
||||
"content.css",
|
||||
"content.js",
|
||||
@@ -23,6 +23,14 @@ const ARCHIVE_FILES = Object.freeze([
|
||||
"popup.js",
|
||||
"transliterate.js"
|
||||
]);
|
||||
const CHROMIUM_ARCHIVE_FILES = Object.freeze([
|
||||
...FIREFOX_ARCHIVE_FILES.map((relativePath) =>
|
||||
relativePath.endsWith(".svg") ? relativePath.replace(/\.svg$/, ".png") : relativePath
|
||||
),
|
||||
"icons/icon-128.png",
|
||||
"icons/icon-48.svg"
|
||||
]);
|
||||
const TARGETS = new Set(["firefox", "chromium"]);
|
||||
|
||||
const VERSION_PATTERN = /^(0|[1-9][0-9]{0,8})(\.(0|[1-9][0-9]{0,8})){0,3}$/;
|
||||
const UTF8_FLAG = 0x0800;
|
||||
@@ -46,6 +54,47 @@ function normalizeVersion(value) {
|
||||
return version;
|
||||
}
|
||||
|
||||
function createManifest(contents, version, target) {
|
||||
const manifest = JSON.parse(contents.toString("utf8"));
|
||||
manifest.version = version;
|
||||
|
||||
if (target === "firefox") {
|
||||
return manifest;
|
||||
}
|
||||
|
||||
if (version.split(".").some((part) => Number(part) > 65535)) {
|
||||
throw new Error(`Chromium extension version parts cannot exceed 65535: ${version}`);
|
||||
}
|
||||
|
||||
manifest.manifest_version = 3;
|
||||
manifest.minimum_chrome_version = "102";
|
||||
delete manifest.browser_specific_settings;
|
||||
manifest.host_permissions = manifest.permissions.filter(
|
||||
(permission) => permission === "<all_urls>" || permission.includes("://")
|
||||
);
|
||||
manifest.permissions = manifest.permissions.filter(
|
||||
(permission) => !manifest.host_permissions.includes(permission)
|
||||
);
|
||||
manifest.background = { service_worker: "background.js" };
|
||||
manifest.action = manifest.browser_action;
|
||||
delete manifest.browser_action;
|
||||
manifest.web_accessible_resources = [
|
||||
{
|
||||
resources: manifest.web_accessible_resources,
|
||||
matches: ["<all_urls>"]
|
||||
}
|
||||
];
|
||||
|
||||
for (const icons of [manifest.icons, manifest.action.default_icon]) {
|
||||
for (const size of Object.keys(icons)) {
|
||||
icons[size] = icons[size].replace(/\.svg$/, ".png");
|
||||
}
|
||||
}
|
||||
manifest.icons["128"] = "icons/icon-128.png";
|
||||
|
||||
return manifest;
|
||||
}
|
||||
|
||||
function crc32(buffer) {
|
||||
let crc = 0xffffffff;
|
||||
|
||||
@@ -122,19 +171,29 @@ function createZip(entries) {
|
||||
return Buffer.concat([...localRecords, centralDirectory, endRecord]);
|
||||
}
|
||||
|
||||
async function packageExtension({ rootDirectory, outputDirectory, version: requestedVersion }) {
|
||||
async function packageExtension({
|
||||
rootDirectory,
|
||||
outputDirectory,
|
||||
target = "firefox",
|
||||
version: requestedVersion
|
||||
}) {
|
||||
if (!TARGETS.has(target)) {
|
||||
throw new Error(`Unknown extension target: ${target}`);
|
||||
}
|
||||
|
||||
const packageMetadata = JSON.parse(
|
||||
await readFile(path.join(rootDirectory, "package.json"), "utf8")
|
||||
);
|
||||
const version = normalizeVersion(requestedVersion ?? packageMetadata.version);
|
||||
const archiveFiles =
|
||||
target === "firefox" ? FIREFOX_ARCHIVE_FILES : CHROMIUM_ARCHIVE_FILES;
|
||||
const entries = [];
|
||||
|
||||
for (const relativePath of ARCHIVE_FILES) {
|
||||
for (const relativePath of archiveFiles) {
|
||||
let contents = await readFile(path.join(rootDirectory, relativePath));
|
||||
|
||||
if (relativePath === "manifest.json") {
|
||||
const manifest = JSON.parse(contents.toString("utf8"));
|
||||
manifest.version = version;
|
||||
const manifest = createManifest(contents, version, target);
|
||||
contents = Buffer.from(`${JSON.stringify(manifest, null, 2)}\n`);
|
||||
}
|
||||
|
||||
@@ -142,7 +201,10 @@ async function packageExtension({ rootDirectory, outputDirectory, version: reque
|
||||
}
|
||||
|
||||
const archive = createZip(entries);
|
||||
const archiveName = `glagolify-${version}.xpi`;
|
||||
const archiveName =
|
||||
target === "firefox"
|
||||
? `glagolify-${version}.xpi`
|
||||
: `glagolify-${version}-chromium.zip`;
|
||||
const archivePath = path.join(outputDirectory, archiveName);
|
||||
const checksumPath = `${archivePath}.sha256`;
|
||||
const digest = createHash("sha256").update(archive).digest("hex");
|
||||
@@ -151,17 +213,22 @@ async function packageExtension({ rootDirectory, outputDirectory, version: reque
|
||||
await writeFile(archivePath, archive);
|
||||
await writeFile(checksumPath, `${digest} ${archiveName}\n`);
|
||||
|
||||
return { archiveName, archivePath, checksumPath, digest, version };
|
||||
return { archiveName, archivePath, checksumPath, digest, target, version };
|
||||
}
|
||||
|
||||
function parseArguments(arguments_) {
|
||||
let outputDirectory = "dist";
|
||||
let target = "all";
|
||||
let version;
|
||||
|
||||
for (let index = 0; index < arguments_.length; index += 1) {
|
||||
const argument = arguments_[index];
|
||||
|
||||
if (argument === "--version" || argument === "--output-dir") {
|
||||
if (
|
||||
argument === "--version" ||
|
||||
argument === "--output-dir" ||
|
||||
argument === "--target"
|
||||
) {
|
||||
const value = arguments_[index + 1];
|
||||
if (!value || value.startsWith("--")) {
|
||||
throw new Error(`${argument} requires a value.`);
|
||||
@@ -169,8 +236,10 @@ function parseArguments(arguments_) {
|
||||
|
||||
if (argument === "--version") {
|
||||
version = value;
|
||||
} else {
|
||||
} else if (argument === "--output-dir") {
|
||||
outputDirectory = value;
|
||||
} else {
|
||||
target = value;
|
||||
}
|
||||
index += 1;
|
||||
} else {
|
||||
@@ -178,22 +247,31 @@ function parseArguments(arguments_) {
|
||||
}
|
||||
}
|
||||
|
||||
return { outputDirectory, version };
|
||||
if (target !== "all" && !TARGETS.has(target)) {
|
||||
throw new Error(`Unknown extension target: ${target}`);
|
||||
}
|
||||
|
||||
return { outputDirectory, target, version };
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const rootDirectory = path.resolve(__dirname, "..");
|
||||
const options = parseArguments(process.argv.slice(2));
|
||||
const result = await packageExtension({
|
||||
rootDirectory,
|
||||
outputDirectory: path.resolve(rootDirectory, options.outputDirectory),
|
||||
version: options.version
|
||||
});
|
||||
const targets = options.target === "all" ? [...TARGETS] : [options.target];
|
||||
|
||||
process.stdout.write(
|
||||
`Created ${path.relative(rootDirectory, result.archivePath)} for version ${result.version}\n` +
|
||||
`SHA-256 ${result.digest}\n`
|
||||
);
|
||||
for (const target of targets) {
|
||||
const result = await packageExtension({
|
||||
rootDirectory,
|
||||
outputDirectory: path.resolve(rootDirectory, options.outputDirectory),
|
||||
target,
|
||||
version: options.version
|
||||
});
|
||||
|
||||
process.stdout.write(
|
||||
`Created ${path.relative(rootDirectory, result.archivePath)} for ${target} ` +
|
||||
`version ${result.version}\nSHA-256 ${result.digest}\n`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
@@ -203,4 +281,9 @@ if (require.main === module) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { ARCHIVE_FILES, normalizeVersion, packageExtension };
|
||||
module.exports = {
|
||||
CHROMIUM_ARCHIVE_FILES,
|
||||
FIREFOX_ARCHIVE_FILES,
|
||||
normalizeVersion,
|
||||
packageExtension
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user