Skip to content

Instantly share code, notes, and snippets.

@MarZab
Created August 21, 2018 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MarZab/251cff66797b76b632d59cb88fdcc8a9 to your computer and use it in GitHub Desktop.
Save MarZab/251cff66797b76b632d59cb88fdcc8a9 to your computer and use it in GitHub Desktop.
WebExtensions (web-ext) update manifest for self-hosted updates
/**
* Create updates.json for offline automatic updates
* https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Updates
*
* Usage:
* node update-dist.js [path to .xpi files] [path to update.json] [url prefix to .xpi files]
*
* Author:
* marko@zabreznik.net
*/
const path = require("path");
const fs = require("fs");
const crypto = require("crypto");
const StreamZip = require("node-stream-zip");
const [_0, _1, _distPath, _updatePath, _distUrlPrefix] = process.argv;
async function getManifest(file) {
return await new Promise(resolve => {
const zip = new StreamZip({ file });
zip.on("ready", () => {
const data = zip.entryDataSync("manifest.json");
let manifest = JSON.parse(data.toString());
zip.close();
resolve(manifest);
});
});
}
async function updateUpdate(distPath, updatePath) {
let updateConfig = require(updatePath);
const files = fs.readdirSync(distPath).filter(x => x.endsWith(".xpi"));
for (const file of files) {
const filePath = path.join(distPath, file);
const manifest = await getManifest(filePath);
const applicationId = manifest.applications.gecko.id;
const version = manifest.version;
if (applicationId in updateConfig.addons) {
if (
updateConfig.addons[applicationId]["updates"].filter(
x => version === x.version
).length < 1
) {
// compute hash
const updateHash = await new Promise((resolve, reject) => {
let hash = crypto.createHash("sha512");
let stream = fs.createReadStream(filePath);
stream.on('error', err => reject(err));
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => resolve(hash.digest('hex')));
});
updateConfig.addons[applicationId]["updates"].push({
version: version,
update_link: _distUrlPrefix + file,
applications: manifest.applications,
update_hash: "sha512:" + updateHash
});
console.log(`added version ${applicationId}:${version}`);
}
} else {
console.log(`${applicationId} not in ${updatePath}`);
}
}
fs.writeFileSync(updatePath, JSON.stringify(updateConfig, null, "\t"));
}
updateUpdate(path.resolve(_distPath), path.resolve(_updatePath));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment