"use strict"; // License: MIT import { ALLOWED_SCHEMES } from "./constants"; import { TRANSFERABLE_PROPERTIES } from "./constants"; const OPTIONPROPS = Object.freeze([ "referrer", "usableReferrer", "description", "title", "fileName", "batch", "idx", "mask", "fromMetalink", "startDate", "hashes", "private", "postData", "cleanRequest", "paused" ]); function maybeAssign(options: any, what: any) { const type = typeof this[what]; if (type === "number" || type === "string" || type === "boolean") { return; } if (type === "object" && this[what]) { return; } let val; if (what in options) { val = options[what]; } this[what] = val; } export class Item { public url: string; public usable: string; public referrer: string; public usableReferrer: string; constructor(raw: any, options?: any) { Object.assign(this, raw); OPTIONPROPS.forEach(maybeAssign.bind(this, options || {})); this.usable = Item.makeUsable(this.url, this.usable); this.usableReferrer = Item.makeUsable(this.referrer, this.usableReferrer); } static makeUsable(unusable: string, usable: string | boolean) { if (usable === true) { return unusable; } if (usable) { return usable; } try { return decodeURIComponent(unusable); } catch (ex) { return unusable; } } toString() { return ``; } } export class Finisher { public referrer: string; public usableReferrer: string; constructor(options: any) { this.referrer = options.baseURL; this.usableReferrer = Item.makeUsable( options.baseURL, options.usable || null); } finish(item: any) { if (!ALLOWED_SCHEMES.has(new URL(item.url).protocol)) { return null; } return new Item(item, this); } } function transfer(e: any, other: any) { for (const p of TRANSFERABLE_PROPERTIES) { if (!other[p] && e[p]) { other[p] = e[p]; } } } export function makeUniqueItems(items: any[][], mapping?: Function) { const known = new Map(); const unique = []; for (const itemlist of items) { for (const e of itemlist) { const other = known.get(e.url); if (other) { transfer(e, other); continue; } const finished = mapping ? mapping(e) : e; if (!finished) { continue; } known.set(finished.url, finished); unique.push(finished); } } return unique; }