UNPKG

webextensions-schema

Version:

Programmatically consume the WebExtensions Schema JSON files

131 lines (130 loc) 4.76 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); const request_1 = __importDefault(require("request")); const unzipper_1 = __importDefault(require("unzipper")); const strip_json_comments_1 = __importDefault(require("strip-json-comments")); class DownloadParse { constructor({ tag } = {}) { this.mozRepo = 'mozilla-unified'; this.mozArchiveURL = 'https://hg.mozilla.org/mozilla-unified/archive'; this.mozLatestFxURL = 'https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US'; this.outDir = path_1.default.join(__dirname, '..', '.schemas'); this.schemaTypes = ['browser', 'toolkit']; this.schemasDir = ['components', 'extensions', 'schemas']; this.schemas = { raw: {}, namespaces: {}, }; if (tag) { this.tag = tag; } } set tag(tag) { this._tag = tag; this.tagDir = path_1.default.join(this.outDir, `${this.mozRepo}-${tag}`); } get tag() { return this._tag; } async run() { if (!this.tag) { await this.fetchLatestStableTag(); } if (!(await this.tagDirExists())) { await this.downloadSchemas(); } await this.parseSchemas(); this.extractNamespaces(); return this; } getSchemas() { return this.schemas; } getTag() { return this.tag; } extractNamespaces() { Object.values(this.schemas.raw).forEach(schemaJson => { schemaJson.forEach(namespace => { if (!this.schemas.namespaces[namespace.namespace]) { this.schemas.namespaces[namespace.namespace] = []; } this.schemas.namespaces[namespace.namespace].push(namespace); }); }); } async parseSchemas() { const unordered = {}; await Promise.all(this.schemaTypes.map(async (type) => { const dir = path_1.default.join(this.tagDir, type, ...this.schemasDir); const files = await fs_1.promises.readdir(dir); await Promise.all(files.map(async (file) => { if (path_1.default.extname(file) !== '.json') { return; } const jsonBuffer = await fs_1.promises.readFile(path_1.default.join(dir, file)); const schema = JSON.parse(strip_json_comments_1.default(jsonBuffer.toString())); unordered[file] = schema; })); })); Object.keys(unordered) .sort() .forEach(file => { this.schemas.raw[file] = unordered[file]; }); } async downloadSchemas() { await Promise.all(this.schemaTypes.map((type) => this.downloadSchema(type))); } async downloadSchema(type) { return new Promise(resolve => { const url = this.getDownloadArchiveUrl(type); request_1.default.get(url).on('response', response => { if (response.statusCode !== 200) { throw new Error(`http status ${response.statusCode} while trying to download ${url} - probably invalid tag name`); } response .pipe(unzipper_1.default.Extract({ path: this.outDir })) .on('finish', resolve); }); }); } async tagDirExists() { try { await fs_1.promises.access(this.tagDir); return true; } catch (error) { return false; } } async fetchLatestStableTag() { return new Promise(resolve => { request_1.default .head({ followRedirect: false, url: this.mozLatestFxURL }) .on('response', response => { var _a; const [, release] = ((_a = response.headers.location) === null || _a === void 0 ? void 0 : _a.match(/\/pub\/firefox\/releases\/([^/]+)\//)) || []; if (!release) { throw new Error("Couldn't automatically resolve latest stable tag"); } this.tag = `FIREFOX_${release.replace(/\./g, '_')}_RELEASE`; resolve(); }); }); } getDownloadArchiveUrl(type) { return [ this.mozArchiveURL, `${this.tag}.zip`, type, ...this.schemasDir, ].join('/'); } } exports.DownloadParse = DownloadParse;