webextension-store-meta
Version:
Get browser extension(webextension) item meta from Chrome Web Store, Firefox add-ons, and Microsoft Edge Add-ons.
292 lines • 9.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EdgeAddons = void 0;
const node_querystring_1 = require("node:querystring");
const domhandler_1 = require("domhandler");
const Parser_1 = require("htmlparser2/lib/Parser");
const dom_1 = require("../utils/dom");
const fetch_text_1 = require("../utils/fetch-text");
const parse_1 = require("../utils/parse");
class EdgeAddons {
id;
options;
qs;
_data = null;
_dom = null;
_url = null;
_cache = new Map();
constructor({ id, options, qs }) {
this.id = id;
this.options = options;
this.qs = (0, node_querystring_1.stringify)(typeof qs === "string" ? (0, node_querystring_1.parse)(qs.replace(/^\?/, "")) : qs || {});
}
static async load(options) {
const instance = new EdgeAddons(options);
await instance.load();
return instance;
}
async load() {
const apiUrl = `https://microsoftedge.microsoft.com/addons/getproductdetailsbycrxid/${this.id}${this.queryString}`;
try {
this._data = JSON.parse(await (0, fetch_text_1.fetchText)(apiUrl, this.options));
this._url = this.detailUrl;
this._dom = [];
return this;
}
catch (_) {
this._data = {};
}
try {
const html = await (0, fetch_text_1.fetchText)(`${this.detailUrl}${this.queryString}`, this.options);
const handler = new domhandler_1.DomHandler();
new Parser_1.Parser(handler).end(html);
this._dom = handler.dom;
this._url = this.detailUrl;
}
catch (_) {
this._dom = [];
this._url = null;
}
return this;
}
meta() {
return {
availability: this.availability(),
activeInstallCount: this.activeInstallCount(),
storeProductId: this.storeProductId(),
name: this.name(),
logoUrl: this.logoUrl(),
thumbnailUrl: this.thumbnailUrl(),
description: this.description(),
developer: this.developer(),
category: this.category(),
isInstalled: this.isInstalled(),
crxId: this.crxId(),
manifest: this.manifest(),
isHavingMatureContent: this.isHavingMatureContent(),
version: this.version(),
lastUpdateDate: this.lastUpdateDate(),
privacyUrl: this.privacyUrl(),
availabilityId: this.availabilityId(),
skuId: this.skuId(),
locale: this.locale(),
market: this.market(),
averageRating: this.averageRating(),
ratingCount: this.ratingCount(),
availableLanguages: this.availableLanguages(),
metadata: this.metadata(),
shortDescription: this.shortDescription(),
searchKeywords: this.searchKeywords(),
screenshots: this.screenshots(),
videos: this.videos(),
largePromotionImage: this.largePromotionImage(),
publisherWebsiteUri: this.publisherWebsiteUri(),
isBadgedAsFeatured: this.isBadgedAsFeatured(),
privacyData: this.privacyData(),
url: this.url(),
};
}
availability() {
return this._array("availability");
}
activeInstallCount() {
return this._number("activeInstallCount", () => this._parseMetaNumber("userInteractionCount"));
}
storeProductId() {
return this._string("storeProductId");
}
name() {
return this._string("name", () => this._title());
}
logoUrl() {
return this._urlString("logoUrl");
}
thumbnailUrl() {
return this._urlString("thumbnailUrl");
}
description() {
return this._string("description");
}
developer() {
return this._string("developer");
}
category() {
return this._string("category");
}
isInstalled() {
return this._boolean("isInstalled");
}
crxId() {
return this._string("crxId");
}
manifest() {
return this._string("manifest");
}
isHavingMatureContent() {
return this._boolean("isHavingMatureContent");
}
version() {
return this._string("version");
}
lastUpdateDate() {
return this._number("lastUpdateDate");
}
privacyUrl() {
return this._string("privacyUrl");
}
availabilityId() {
return this._string("availabilityId");
}
skuId() {
return this._string("skuId");
}
locale() {
return this._string("locale");
}
market() {
return this._string("market");
}
averageRating() {
return this._number("averageRating", () => this._parseMetaNumber("ratingValue"));
}
ratingCount() {
return this._number("ratingCount", () => this._parseMetaNumber("ratingCount"));
}
availableLanguages() {
return this._array("availableLanguages");
}
metadata() {
return this._object("metadata");
}
shortDescription() {
return this._string("shortDescription");
}
searchKeywords() {
return this._string("searchKeywords");
}
screenshots() {
return this._images("screenshots");
}
videos() {
return this._images("videos");
}
largePromotionImage() {
const value = this._value("largePromotionImage");
if (!(0, parse_1.isPlainObject)(value))
return null;
return normalizeImage(value);
}
publisherWebsiteUri() {
return this._string("publisherWebsiteUri");
}
isBadgedAsFeatured() {
return this._boolean("isBadgedAsFeatured");
}
privacyData() {
return this._object("privacyData");
}
url() {
if (!this._cache.has("url")) {
this._cache.set("url", this._url);
}
return this._cache.get("url") ?? null;
}
get queryString() {
return this.qs ? `?${this.qs}` : "";
}
get detailUrl() {
return `https://microsoftedge.microsoft.com/addons/detail/${this.id}`;
}
_value(key) {
if (!this._data) {
throw new Error("Item not loaded. Please run `await instance.load()` first.`");
}
return this._data[key] ?? null;
}
_string(key, fallback) {
if (!this._cache.has(key)) {
const value = this._value(key);
this._cache.set(key, typeof value === "string" && value !== ""
? value
: (fallback?.() ?? null));
}
return this._cache.get(key) ?? null;
}
_urlString(key) {
if (!this._cache.has(key)) {
const value = this._value(key);
this._cache.set(key, typeof value === "string" && value !== "" ? normalizeUrl(value) : null);
}
return this._cache.get(key) ?? null;
}
_number(key, fallback) {
if (!this._cache.has(key)) {
const value = this._value(key);
this._cache.set(key, typeof value === "number" ? value : (fallback?.() ?? null));
}
return this._cache.get(key) ?? null;
}
_boolean(key) {
if (!this._cache.has(key)) {
const value = this._value(key);
this._cache.set(key, typeof value === "boolean" ? value : null);
}
return this._cache.get(key) ?? null;
}
_array(key) {
if (!this._cache.has(key)) {
const value = this._value(key);
this._cache.set(key, Array.isArray(value) && value.every((item) => typeof item === "string")
? value
: null);
}
return this._cache.get(key) ?? null;
}
_images(key) {
if (!this._cache.has(key)) {
const value = this._value(key);
this._cache.set(key, Array.isArray(value)
? value.filter(parse_1.isPlainObject).map(normalizeImage)
: null);
}
return this._cache.get(key) ?? null;
}
_object(key) {
if (!this._cache.has(key)) {
const value = this._value(key);
this._cache.set(key, (0, parse_1.isPlainObject)(value) ? value : null);
}
return this._cache.get(key) ?? null;
}
_title() {
const title = (0, dom_1.getText)((0, dom_1.findOne)((el) => el.name === "title", this.dom));
return title.replace(/\s*-\s*Microsoft Edge Add-ons\s*$/, "") || null;
}
_parseMetaNumber(itemprop) {
const value = (0, dom_1.findOne)((el) => el.name === "meta" &&
el.attribs.itemprop?.toLowerCase() === itemprop.toLowerCase(), this.dom)?.attribs.content;
if (!value)
return null;
const number = Number(value.replace(/,/g, ""));
return Number.isNaN(number) ? null : number;
}
get dom() {
if (!this._dom) {
throw new Error("Item not loaded. Please run `await instance.load()` first.`");
}
return this._dom;
}
}
exports.EdgeAddons = EdgeAddons;
exports.default = EdgeAddons;
function normalizeUrl(url) {
return url.startsWith("//") ? `https:${url}` : url;
}
function normalizeImage(image) {
const result = { ...image };
if (typeof image.uri === "string") {
result.uri = normalizeUrl(image.uri);
}
return result;
}
//# sourceMappingURL=index.js.map