import { writeFileSync } from 'node:fs'; import require$$0 from 'stream'; import require$$0$1 from 'fs'; import require$$2 from 'readline'; import require$$3 from 'url'; import require$$0$2 from 'path'; import require$$1 from 'child_process'; import { createRequire } from 'module'; import require$$1$1 from 'string_decoder'; import require$$3$1 from 'zlib'; import require$$0$3 from 'util'; import { isAbsolute as isAbsolute$1, resolve, parse as parse$4, join } from 'node:path'; import require$$0$4 from 'os'; import require$$0$5 from 'events'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var dist = {}; var sitemapItemStream = {}; var errors = {}; /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ /*! * Sitemap * Copyright(c) 2011 Eugene Kalinin * MIT Licensed */ Object.defineProperty(errors, "__esModule", { value: true }); errors.EmptySitemap = errors.EmptyStream = errors.InvalidVideoPriceCurrency = errors.InvalidVideoResolution = errors.InvalidVideoPriceType = errors.InvalidVideoRestrictionRelationship = errors.InvalidVideoRestriction = errors.InvalidVideoFamilyFriendly = errors.InvalidVideoCategory = errors.InvalidVideoTagCount = errors.InvalidVideoViewCount = errors.InvalidVideoTitle = errors.XMLLintUnavailable = errors.InvalidNewsAccessValue = errors.InvalidNewsFormat = errors.InvalidAttr = errors.InvalidAttrValue = errors.InvalidVideoRating = errors.InvalidVideoDescription = errors.InvalidVideoDuration = errors.InvalidVideoFormat = errors.UndefinedTargetFolder = errors.PriorityInvalidError = errors.ChangeFreqInvalidError = errors.NoConfigError = errors.NoURLError = void 0; /** * URL in SitemapItem does not exist */ class NoURLError extends Error { constructor(message) { super(message || 'URL is required'); this.name = 'NoURLError'; Error.captureStackTrace(this, NoURLError); } } errors.NoURLError = NoURLError; /** * Config was not passed to SitemapItem constructor */ class NoConfigError extends Error { constructor(message) { super(message || 'SitemapItem requires a configuration'); this.name = 'NoConfigError'; Error.captureStackTrace(this, NoConfigError); } } errors.NoConfigError = NoConfigError; /** * changefreq property in sitemap is invalid */ class ChangeFreqInvalidError extends Error { constructor(url, changefreq) { super(`${url}: changefreq "${changefreq}" is invalid`); this.name = 'ChangeFreqInvalidError'; Error.captureStackTrace(this, ChangeFreqInvalidError); } } errors.ChangeFreqInvalidError = ChangeFreqInvalidError; /** * priority property in sitemap is invalid */ class PriorityInvalidError extends Error { constructor(url, priority) { super(`${url}: priority "${priority}" must be a number between 0 and 1 inclusive`); this.name = 'PriorityInvalidError'; Error.captureStackTrace(this, PriorityInvalidError); } } errors.PriorityInvalidError = PriorityInvalidError; /** * SitemapIndex target Folder does not exists */ class UndefinedTargetFolder extends Error { constructor(message) { super(message || 'Target folder must exist'); this.name = 'UndefinedTargetFolder'; Error.captureStackTrace(this, UndefinedTargetFolder); } } errors.UndefinedTargetFolder = UndefinedTargetFolder; class InvalidVideoFormat extends Error { constructor(url) { super(`${url} video must include thumbnail_loc, title and description fields for videos`); this.name = 'InvalidVideoFormat'; Error.captureStackTrace(this, InvalidVideoFormat); } } errors.InvalidVideoFormat = InvalidVideoFormat; class InvalidVideoDuration extends Error { constructor(url, duration) { super(`${url} duration "${duration}" must be an integer of seconds between 0 and 28800`); this.name = 'InvalidVideoDuration'; Error.captureStackTrace(this, InvalidVideoDuration); } } errors.InvalidVideoDuration = InvalidVideoDuration; class InvalidVideoDescription extends Error { constructor(url, length) { const message = `${url}: video description is too long ${length} vs limit of 2048 characters.`; super(message); this.name = 'InvalidVideoDescription'; Error.captureStackTrace(this, InvalidVideoDescription); } } errors.InvalidVideoDescription = InvalidVideoDescription; class InvalidVideoRating extends Error { constructor(url, title, rating) { super(`${url}: video "${title}" rating "${rating}" must be between 0 and 5 inclusive`); this.name = 'InvalidVideoRating'; Error.captureStackTrace(this, InvalidVideoRating); } } errors.InvalidVideoRating = InvalidVideoRating; class InvalidAttrValue extends Error { // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(key, val, validator) { super('"' + val + '" tested against: ' + validator + ' is not a valid value for attr: "' + key + '"'); this.name = 'InvalidAttrValue'; Error.captureStackTrace(this, InvalidAttrValue); } } errors.InvalidAttrValue = InvalidAttrValue; // InvalidAttr is only thrown when attrbuilder is called incorrectly internally /* istanbul ignore next */ class InvalidAttr extends Error { constructor(key) { super('"' + key + '" is malformed'); this.name = 'InvalidAttr'; Error.captureStackTrace(this, InvalidAttr); } } errors.InvalidAttr = InvalidAttr; class InvalidNewsFormat extends Error { constructor(url) { super(`${url} News must include publication, publication name, publication language, title, and publication_date for news`); this.name = 'InvalidNewsFormat'; Error.captureStackTrace(this, InvalidNewsFormat); } } errors.InvalidNewsFormat = InvalidNewsFormat; class InvalidNewsAccessValue extends Error { constructor(url, access) { super(`${url} News access "${access}" must be either Registration, Subscription or not be present`); this.name = 'InvalidNewsAccessValue'; Error.captureStackTrace(this, InvalidNewsAccessValue); } } errors.InvalidNewsAccessValue = InvalidNewsAccessValue; class XMLLintUnavailable extends Error { constructor(message) { super(message || 'xmlLint is not installed. XMLLint is required to validate'); this.name = 'XMLLintUnavailable'; Error.captureStackTrace(this, XMLLintUnavailable); } } errors.XMLLintUnavailable = XMLLintUnavailable; class InvalidVideoTitle extends Error { constructor(url, length) { super(`${url}: video title is too long ${length} vs 100 character limit`); this.name = 'InvalidVideoTitle'; Error.captureStackTrace(this, InvalidVideoTitle); } } errors.InvalidVideoTitle = InvalidVideoTitle; class InvalidVideoViewCount extends Error { constructor(url, count) { super(`${url}: video view count must be positive, view count was ${count}`); this.name = 'InvalidVideoViewCount'; Error.captureStackTrace(this, InvalidVideoViewCount); } } errors.InvalidVideoViewCount = InvalidVideoViewCount; class InvalidVideoTagCount extends Error { constructor(url, count) { super(`${url}: video can have no more than 32 tags, this has ${count}`); this.name = 'InvalidVideoTagCount'; Error.captureStackTrace(this, InvalidVideoTagCount); } } errors.InvalidVideoTagCount = InvalidVideoTagCount; class InvalidVideoCategory extends Error { constructor(url, count) { super(`${url}: video category can only be 256 characters but was passed ${count}`); this.name = 'InvalidVideoCategory'; Error.captureStackTrace(this, InvalidVideoCategory); } } errors.InvalidVideoCategory = InvalidVideoCategory; class InvalidVideoFamilyFriendly extends Error { constructor(url, fam) { super(`${url}: video family friendly must be yes or no, was passed "${fam}"`); this.name = 'InvalidVideoFamilyFriendly'; Error.captureStackTrace(this, InvalidVideoFamilyFriendly); } } errors.InvalidVideoFamilyFriendly = InvalidVideoFamilyFriendly; class InvalidVideoRestriction extends Error { constructor(url, code) { super(`${url}: video restriction must be one or more two letter country codes. Was passed "${code}"`); this.name = 'InvalidVideoRestriction'; Error.captureStackTrace(this, InvalidVideoRestriction); } } errors.InvalidVideoRestriction = InvalidVideoRestriction; class InvalidVideoRestrictionRelationship extends Error { constructor(url, val) { super(`${url}: video restriction relationship must be either allow or deny. Was passed "${val}"`); this.name = 'InvalidVideoRestrictionRelationship'; Error.captureStackTrace(this, InvalidVideoRestrictionRelationship); } } errors.InvalidVideoRestrictionRelationship = InvalidVideoRestrictionRelationship; class InvalidVideoPriceType extends Error { constructor(url, priceType, price) { super(priceType === undefined && price === '' ? `${url}: video priceType is required when price is not provided` : `${url}: video price type "${priceType}" is not "rent" or "purchase"`); this.name = 'InvalidVideoPriceType'; Error.captureStackTrace(this, InvalidVideoPriceType); } } errors.InvalidVideoPriceType = InvalidVideoPriceType; class InvalidVideoResolution extends Error { constructor(url, resolution) { super(`${url}: video price resolution "${resolution}" is not hd or sd`); this.name = 'InvalidVideoResolution'; Error.captureStackTrace(this, InvalidVideoResolution); } } errors.InvalidVideoResolution = InvalidVideoResolution; class InvalidVideoPriceCurrency extends Error { constructor(url, currency) { super(`${url}: video price currency "${currency}" must be a three capital letter abbrieviation for the country currency`); this.name = 'InvalidVideoPriceCurrency'; Error.captureStackTrace(this, InvalidVideoPriceCurrency); } } errors.InvalidVideoPriceCurrency = InvalidVideoPriceCurrency; class EmptyStream extends Error { constructor() { super('You have ended the stream before anything was written. streamToPromise MUST be called before ending the stream.'); this.name = 'EmptyStream'; Error.captureStackTrace(this, EmptyStream); } } errors.EmptyStream = EmptyStream; class EmptySitemap extends Error { constructor() { super('You ended the stream without writing anything.'); this.name = 'EmptySitemap'; Error.captureStackTrace(this, EmptyStream); } } errors.EmptySitemap = EmptySitemap; var types = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.IndexTagNames = exports.TagNames = exports.ErrorLevel = exports.isAllowDeny = exports.EnumAllowDeny = exports.isValidYesNo = exports.EnumYesNo = exports.isValidChangeFreq = exports.CHANGEFREQ = exports.isResolution = exports.isPriceType = exports.validators = exports.EnumChangefreq = void 0; /** * How frequently the page is likely to change. This value provides general * information to search engines and may not correlate exactly to how often they crawl the page. Please note that the * value of this tag is considered a hint and not a command. See * for the acceptable * values */ var EnumChangefreq; (function (EnumChangefreq) { EnumChangefreq["DAILY"] = "daily"; EnumChangefreq["MONTHLY"] = "monthly"; EnumChangefreq["ALWAYS"] = "always"; EnumChangefreq["HOURLY"] = "hourly"; EnumChangefreq["WEEKLY"] = "weekly"; EnumChangefreq["YEARLY"] = "yearly"; EnumChangefreq["NEVER"] = "never"; })(EnumChangefreq = exports.EnumChangefreq || (exports.EnumChangefreq = {})); const allowDeny = /^(?:allow|deny)$/; exports.validators = { 'price:currency': /^[A-Z]{3}$/, 'price:type': /^(?:rent|purchase|RENT|PURCHASE)$/, 'price:resolution': /^(?:HD|hd|sd|SD)$/, 'platform:relationship': allowDeny, 'restriction:relationship': allowDeny, restriction: /^([A-Z]{2}( +[A-Z]{2})*)?$/, platform: /^((web|mobile|tv)( (web|mobile|tv))*)?$/, language: /^zh-cn|zh-tw|([a-z]{2,3})$/, genres: /^(PressRelease|Satire|Blog|OpEd|Opinion|UserGenerated)(, *(PressRelease|Satire|Blog|OpEd|Opinion|UserGenerated))*$/, stock_tickers: /^(\w+:\w+(, *\w+:\w+){0,4})?$/, }; function isPriceType(pt) { return exports.validators['price:type'].test(pt); } exports.isPriceType = isPriceType; function isResolution(res) { return exports.validators['price:resolution'].test(res); } exports.isResolution = isResolution; exports.CHANGEFREQ = Object.values(EnumChangefreq); function isValidChangeFreq(freq) { return exports.CHANGEFREQ.includes(freq); } exports.isValidChangeFreq = isValidChangeFreq; (function (EnumYesNo) { EnumYesNo["YES"] = "YES"; EnumYesNo["NO"] = "NO"; EnumYesNo["Yes"] = "Yes"; EnumYesNo["No"] = "No"; EnumYesNo["yes"] = "yes"; EnumYesNo["no"] = "no"; })(exports.EnumYesNo || (exports.EnumYesNo = {})); function isValidYesNo(yn) { return /^YES|NO|[Yy]es|[Nn]o$/.test(yn); } exports.isValidYesNo = isValidYesNo; (function (EnumAllowDeny) { EnumAllowDeny["ALLOW"] = "allow"; EnumAllowDeny["DENY"] = "deny"; })(exports.EnumAllowDeny || (exports.EnumAllowDeny = {})); function isAllowDeny(ad) { return allowDeny.test(ad); } exports.isAllowDeny = isAllowDeny; (function (ErrorLevel) { /** * Validation will be skipped and nothing logged or thrown. */ ErrorLevel["SILENT"] = "silent"; /** * If an invalid value is encountered, a console.warn will be called with details */ ErrorLevel["WARN"] = "warn"; /** * An Error will be thrown on encountering invalid data. */ ErrorLevel["THROW"] = "throw"; })(exports.ErrorLevel || (exports.ErrorLevel = {})); (function (TagNames) { TagNames["url"] = "url"; TagNames["loc"] = "loc"; TagNames["urlset"] = "urlset"; TagNames["lastmod"] = "lastmod"; TagNames["changefreq"] = "changefreq"; TagNames["priority"] = "priority"; TagNames["video:thumbnail_loc"] = "video:thumbnail_loc"; TagNames["video:video"] = "video:video"; TagNames["video:title"] = "video:title"; TagNames["video:description"] = "video:description"; TagNames["video:tag"] = "video:tag"; TagNames["video:duration"] = "video:duration"; TagNames["video:player_loc"] = "video:player_loc"; TagNames["video:content_loc"] = "video:content_loc"; TagNames["image:image"] = "image:image"; TagNames["image:loc"] = "image:loc"; TagNames["image:geo_location"] = "image:geo_location"; TagNames["image:license"] = "image:license"; TagNames["image:title"] = "image:title"; TagNames["image:caption"] = "image:caption"; TagNames["video:requires_subscription"] = "video:requires_subscription"; TagNames["video:publication_date"] = "video:publication_date"; TagNames["video:id"] = "video:id"; TagNames["video:restriction"] = "video:restriction"; TagNames["video:family_friendly"] = "video:family_friendly"; TagNames["video:view_count"] = "video:view_count"; TagNames["video:uploader"] = "video:uploader"; TagNames["video:expiration_date"] = "video:expiration_date"; TagNames["video:platform"] = "video:platform"; TagNames["video:price"] = "video:price"; TagNames["video:rating"] = "video:rating"; TagNames["video:category"] = "video:category"; TagNames["video:live"] = "video:live"; TagNames["video:gallery_loc"] = "video:gallery_loc"; TagNames["news:news"] = "news:news"; TagNames["news:publication"] = "news:publication"; TagNames["news:name"] = "news:name"; TagNames["news:access"] = "news:access"; TagNames["news:genres"] = "news:genres"; TagNames["news:publication_date"] = "news:publication_date"; TagNames["news:title"] = "news:title"; TagNames["news:keywords"] = "news:keywords"; TagNames["news:stock_tickers"] = "news:stock_tickers"; TagNames["news:language"] = "news:language"; TagNames["mobile:mobile"] = "mobile:mobile"; TagNames["xhtml:link"] = "xhtml:link"; TagNames["expires"] = "expires"; })(exports.TagNames || (exports.TagNames = {})); (function (IndexTagNames) { IndexTagNames["sitemap"] = "sitemap"; IndexTagNames["sitemapindex"] = "sitemapindex"; IndexTagNames["loc"] = "loc"; IndexTagNames["lastmod"] = "lastmod"; })(exports.IndexTagNames || (exports.IndexTagNames = {})); } (types)); var sitemapXml = {}; Object.defineProperty(sitemapXml, "__esModule", { value: true }); sitemapXml.element = sitemapXml.ctag = sitemapXml.otag = sitemapXml.text = void 0; const invalidXMLUnicodeRegex = // eslint-disable-next-line no-control-regex /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u0084\u0086-\u009F\uD800-\uDFFF\uFDD0-\uFDDF\u{1FFFE}-\u{1FFFF}\u{2FFFE}-\u{2FFFF}\u{3FFFE}-\u{3FFFF}\u{4FFFE}-\u{4FFFF}\u{5FFFE}-\u{5FFFF}\u{6FFFE}-\u{6FFFF}\u{7FFFE}-\u{7FFFF}\u{8FFFE}-\u{8FFFF}\u{9FFFE}-\u{9FFFF}\u{AFFFE}-\u{AFFFF}\u{BFFFE}-\u{BFFFF}\u{CFFFE}-\u{CFFFF}\u{DFFFE}-\u{DFFFF}\u{EFFFE}-\u{EFFFF}\u{FFFFE}-\u{FFFFF}\u{10FFFE}-\u{10FFFF}]/gu; const amp = /&/g; const lt = /`; } sitemapXml.otag = otag; function ctag(nodeName) { return ``; } sitemapXml.ctag = ctag; function element(nodeName, attrs, innerText) { if (typeof attrs === 'string') { return otag(nodeName) + text(attrs) + ctag(nodeName); } else if (innerText) { return otag(nodeName, attrs) + text(innerText) + ctag(nodeName); } else { return otag(nodeName, attrs, true); } } sitemapXml.element = element; Object.defineProperty(sitemapItemStream, "__esModule", { value: true }); sitemapItemStream.SitemapItemStream = void 0; const stream_1$9 = require$$0; const errors_1$2 = errors; const types_1$3 = types; const sitemap_xml_1 = sitemapXml; function attrBuilder(conf, keys) { if (typeof keys === 'string') { keys = [keys]; } const iv = {}; return keys.reduce((attrs, key) => { // eslint-disable-next-line if (conf[key] !== undefined) { const keyAr = key.split(':'); if (keyAr.length !== 2) { throw new errors_1$2.InvalidAttr(key); } attrs[keyAr[1]] = conf[key]; } return attrs; }, iv); } /** * Takes a stream of SitemapItemOptions and spits out xml for each * @example * // writes https://example.comhttps://example.com/2 * const smis = new SitemapItemStream({level: 'warn'}) * smis.pipe(writestream) * smis.write({url: 'https://example.com', img: [], video: [], links: []}) * smis.write({url: 'https://example.com/2', img: [], video: [], links: []}) * smis.end() * @param level - Error level */ class SitemapItemStream extends stream_1$9.Transform { constructor(opts = { level: types_1$3.ErrorLevel.WARN }) { opts.objectMode = true; super(opts); this.level = opts.level || types_1$3.ErrorLevel.WARN; } _transform(item, encoding, callback) { this.push((0, sitemap_xml_1.otag)(types_1$3.TagNames.url)); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames.loc, item.url)); if (item.lastmod) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames.lastmod, item.lastmod)); } if (item.changefreq) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames.changefreq, item.changefreq)); } if (item.priority !== undefined && item.priority !== null) { if (item.fullPrecisionPriority) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames.priority, item.priority.toString())); } else { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames.priority, item.priority.toFixed(1))); } } item.video.forEach((video) => { this.push((0, sitemap_xml_1.otag)(types_1$3.TagNames['video:video'])); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:thumbnail_loc'], video.thumbnail_loc)); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:title'], video.title)); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:description'], video.description)); if (video.content_loc) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:content_loc'], video.content_loc)); } if (video.player_loc) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:player_loc'], attrBuilder(video, [ 'player_loc:autoplay', 'player_loc:allow_embed', ]), video.player_loc)); } if (video.duration) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:duration'], video.duration.toString())); } if (video.expiration_date) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:expiration_date'], video.expiration_date)); } if (video.rating !== undefined) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:rating'], video.rating.toString())); } if (video.view_count !== undefined) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:view_count'], video.view_count.toString())); } if (video.publication_date) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:publication_date'], video.publication_date)); } for (const tag of video.tag) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:tag'], tag)); } if (video.category) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:category'], video.category)); } if (video.family_friendly) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:family_friendly'], video.family_friendly)); } if (video.restriction) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:restriction'], attrBuilder(video, 'restriction:relationship'), video.restriction)); } if (video.gallery_loc) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:gallery_loc'], { title: video['gallery_loc:title'] }, video.gallery_loc)); } if (video.price) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:price'], attrBuilder(video, [ 'price:resolution', 'price:currency', 'price:type', ]), video.price)); } if (video.requires_subscription) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:requires_subscription'], video.requires_subscription)); } if (video.uploader) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:uploader'], attrBuilder(video, 'uploader:info'), video.uploader)); } if (video.platform) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:platform'], attrBuilder(video, 'platform:relationship'), video.platform)); } if (video.live) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:live'], video.live)); } if (video.id) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['video:id'], { type: 'url' }, video.id)); } this.push((0, sitemap_xml_1.ctag)(types_1$3.TagNames['video:video'])); }); item.links.forEach((link) => { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['xhtml:link'], { rel: 'alternate', hreflang: link.lang || link.hreflang, href: link.url, })); }); if (item.expires) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames.expires, new Date(item.expires).toISOString())); } if (item.androidLink) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['xhtml:link'], { rel: 'alternate', href: item.androidLink, })); } if (item.ampLink) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['xhtml:link'], { rel: 'amphtml', href: item.ampLink, })); } if (item.news) { this.push((0, sitemap_xml_1.otag)(types_1$3.TagNames['news:news'])); this.push((0, sitemap_xml_1.otag)(types_1$3.TagNames['news:publication'])); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:name'], item.news.publication.name)); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:language'], item.news.publication.language)); this.push((0, sitemap_xml_1.ctag)(types_1$3.TagNames['news:publication'])); if (item.news.access) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:access'], item.news.access)); } if (item.news.genres) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:genres'], item.news.genres)); } this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:publication_date'], item.news.publication_date)); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:title'], item.news.title)); if (item.news.keywords) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:keywords'], item.news.keywords)); } if (item.news.stock_tickers) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['news:stock_tickers'], item.news.stock_tickers)); } this.push((0, sitemap_xml_1.ctag)(types_1$3.TagNames['news:news'])); } // Image handling item.img.forEach((image) => { this.push((0, sitemap_xml_1.otag)(types_1$3.TagNames['image:image'])); this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['image:loc'], image.url)); if (image.caption) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['image:caption'], image.caption)); } if (image.geoLocation) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['image:geo_location'], image.geoLocation)); } if (image.title) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['image:title'], image.title)); } if (image.license) { this.push((0, sitemap_xml_1.element)(types_1$3.TagNames['image:license'], image.license)); } this.push((0, sitemap_xml_1.ctag)(types_1$3.TagNames['image:image'])); }); this.push((0, sitemap_xml_1.ctag)(types_1$3.TagNames.url)); callback(); } } sitemapItemStream.SitemapItemStream = SitemapItemStream; var sitemapIndexStream = {}; var sitemapStream = {}; var utils$l = {}; Object.defineProperty(utils$l, "__esModule", { value: true }); utils$l.normalizeURL = utils$l.chunk = utils$l.lineSeparatedURLsToSitemapOptions = utils$l.ReadlineStream = utils$l.mergeStreams = utils$l.validateSMIOptions = void 0; /*! * Sitemap * Copyright(c) 2011 Eugene Kalinin * MIT Licensed */ const fs_1 = require$$0$1; const stream_1$8 = require$$0; const readline_1 = require$$2; const url_1 = require$$3; const types_1$2 = types; const errors_1$1 = errors; const types_2 = types; function validate(subject, name, url, level) { Object.keys(subject).forEach((key) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const val = subject[key]; if (types_2.validators[key] && !types_2.validators[key].test(val)) { if (level === types_1$2.ErrorLevel.THROW) { throw new errors_1$1.InvalidAttrValue(key, val, types_2.validators[key]); } else { console.warn(`${url}: ${name} key ${key} has invalid value: ${val}`); } } }); } function handleError(error, level) { if (level === types_1$2.ErrorLevel.THROW) { throw error; } else if (level === types_1$2.ErrorLevel.WARN) { console.warn(error.name, error.message); } } /** * Verifies all data passed in will comply with sitemap spec. * @param conf Options to validate * @param level logging level * @param errorHandler error handling func */ function validateSMIOptions(conf, level = types_1$2.ErrorLevel.WARN, errorHandler = handleError) { if (!conf) { throw new errors_1$1.NoConfigError(); } if (level === types_1$2.ErrorLevel.SILENT) { return conf; } const { url, changefreq, priority, news, video } = conf; if (!url) { errorHandler(new errors_1$1.NoURLError(), level); } if (changefreq) { if (!(0, types_1$2.isValidChangeFreq)(changefreq)) { errorHandler(new errors_1$1.ChangeFreqInvalidError(url, changefreq), level); } } if (priority) { if (!(priority >= 0.0 && priority <= 1.0)) { errorHandler(new errors_1$1.PriorityInvalidError(url, priority), level); } } if (news) { if (news.access && news.access !== 'Registration' && news.access !== 'Subscription') { errorHandler(new errors_1$1.InvalidNewsAccessValue(url, news.access), level); } if (!news.publication || !news.publication.name || !news.publication.language || !news.publication_date || !news.title) { errorHandler(new errors_1$1.InvalidNewsFormat(url), level); } validate(news, 'news', url, level); validate(news.publication, 'publication', url, level); } if (video) { video.forEach((vid) => { var _a; if (vid.duration !== undefined) { if (vid.duration < 0 || vid.duration > 28800) { errorHandler(new errors_1$1.InvalidVideoDuration(url, vid.duration), level); } } if (vid.rating !== undefined && (vid.rating < 0 || vid.rating > 5)) { errorHandler(new errors_1$1.InvalidVideoRating(url, vid.title, vid.rating), level); } if (typeof vid !== 'object' || !vid.thumbnail_loc || !vid.title || !vid.description) { // has to be an object and include required categories https://support.google.com/webmasters/answer/80471?hl=en&ref_topic=4581190 errorHandler(new errors_1$1.InvalidVideoFormat(url), level); } if (vid.title.length > 100) { errorHandler(new errors_1$1.InvalidVideoTitle(url, vid.title.length), level); } if (vid.description.length > 2048) { errorHandler(new errors_1$1.InvalidVideoDescription(url, vid.description.length), level); } if (vid.view_count !== undefined && vid.view_count < 0) { errorHandler(new errors_1$1.InvalidVideoViewCount(url, vid.view_count), level); } if (vid.tag.length > 32) { errorHandler(new errors_1$1.InvalidVideoTagCount(url, vid.tag.length), level); } if (vid.category !== undefined && ((_a = vid.category) === null || _a === void 0 ? void 0 : _a.length) > 256) { errorHandler(new errors_1$1.InvalidVideoCategory(url, vid.category.length), level); } if (vid.family_friendly !== undefined && !(0, types_1$2.isValidYesNo)(vid.family_friendly)) { errorHandler(new errors_1$1.InvalidVideoFamilyFriendly(url, vid.family_friendly), level); } if (vid.restriction) { if (!types_2.validators.restriction.test(vid.restriction)) { errorHandler(new errors_1$1.InvalidVideoRestriction(url, vid.restriction), level); } if (!vid['restriction:relationship'] || !(0, types_1$2.isAllowDeny)(vid['restriction:relationship'])) { errorHandler(new errors_1$1.InvalidVideoRestrictionRelationship(url, vid['restriction:relationship']), level); } } // TODO price element should be unbounded if ((vid.price === '' && vid['price:type'] === undefined) || (vid['price:type'] !== undefined && !(0, types_1$2.isPriceType)(vid['price:type']))) { errorHandler(new errors_1$1.InvalidVideoPriceType(url, vid['price:type'], vid.price), level); } if (vid['price:resolution'] !== undefined && !(0, types_1$2.isResolution)(vid['price:resolution'])) { errorHandler(new errors_1$1.InvalidVideoResolution(url, vid['price:resolution']), level); } if (vid['price:currency'] !== undefined && !types_2.validators['price:currency'].test(vid['price:currency'])) { errorHandler(new errors_1$1.InvalidVideoPriceCurrency(url, vid['price:currency']), level); } validate(vid, 'video', url, level); }); } return conf; } utils$l.validateSMIOptions = validateSMIOptions; /** * Combines multiple streams into one * @param streams the streams to combine */ function mergeStreams(streams, options) { let pass = new stream_1$8.PassThrough(options); let waiting = streams.length; for (const stream of streams) { pass = stream.pipe(pass, { end: false }); stream.once('end', () => --waiting === 0 && pass.emit('end')); } return pass; } utils$l.mergeStreams = mergeStreams; /** * Wraps node's ReadLine in a stream */ class ReadlineStream extends stream_1$8.Readable { constructor(options) { if (options.autoDestroy === undefined) { options.autoDestroy = true; } options.objectMode = true; super(options); this._source = (0, readline_1.createInterface)({ input: options.input, terminal: false, crlfDelay: Infinity, }); // Every time there's data, push it into the internal buffer. this._source.on('line', (chunk) => { // If push() returns false, then stop reading from source. if (!this.push(chunk)) this._source.pause(); }); // When the source ends, push the EOF-signaling `null` chunk. this._source.on('close', () => { this.push(null); }); } // _read() will be called when the stream wants to pull more data in. // The advisory size argument is ignored in this case. _read(size) { this._source.resume(); } } utils$l.ReadlineStream = ReadlineStream; /** * Takes a stream likely from fs.createReadStream('./path') and returns a stream * of sitemap items * @param stream a stream of line separated urls. * @param opts.isJSON is the stream line separated JSON. leave undefined to guess */ function lineSeparatedURLsToSitemapOptions(stream, { isJSON } = {}) { return new ReadlineStream({ input: stream }).pipe(new stream_1$8.Transform({ objectMode: true, // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types transform: (line, encoding, cb) => { if (isJSON || (isJSON === undefined && line[0] === '{')) { cb(null, JSON.parse(line)); } else { cb(null, line); } }, })); } utils$l.lineSeparatedURLsToSitemapOptions = lineSeparatedURLsToSitemapOptions; /** * Based on lodash's implementation of chunk. * * Copyright JS Foundation and other contributors * * Based on Underscore.js, copyright Jeremy Ashkenas, * DocumentCloud and Investigative Reporters & Editors * * This software consists of voluntary contributions made by many * individuals. For exact contribution history, see the revision history * available at https://github.com/lodash/lodash */ /* eslint-disable @typescript-eslint/no-explicit-any */ function chunk(array, size = 1) { size = Math.max(Math.trunc(size), 0); const length = array ? array.length : 0; if (!length || size < 1) { return []; } const result = Array(Math.ceil(length / size)); let index = 0, resIndex = 0; while (index < length) { result[resIndex++] = array.slice(index, (index += size)); } return result; } utils$l.chunk = chunk; function boolToYESNO(bool) { if (bool === undefined) { return bool; } if (typeof bool === 'boolean') { return bool ? types_1$2.EnumYesNo.yes : types_1$2.EnumYesNo.no; } return bool; } /** * Converts the passed in sitemap entry into one capable of being consumed by SitemapItem * @param {string | SitemapItemLoose} elem the string or object to be converted * @param {string} hostname * @returns SitemapItemOptions a strict sitemap item option */ function normalizeURL(elem, hostname, lastmodDateOnly = false) { // SitemapItem // create object with url property let smi = { img: [], video: [], links: [], url: '', }; let smiLoose; if (typeof elem === 'string') { smi.url = elem; smiLoose = { url: elem }; } else { smiLoose = elem; } smi.url = new url_1.URL(smiLoose.url, hostname).toString(); let img = []; if (smiLoose.img) { if (typeof smiLoose.img === 'string') { // string -> array of objects smiLoose.img = [{ url: smiLoose.img }]; } else if (!Array.isArray(smiLoose.img)) { // object -> array of objects smiLoose.img = [smiLoose.img]; } img = smiLoose.img.map((el) => (typeof el === 'string' ? { url: el } : el)); } // prepend hostname to all image urls smi.img = img.map((el) => ({ ...el, url: new url_1.URL(el.url, hostname).toString(), })); let links = []; if (smiLoose.links) { links = smiLoose.links; } smi.links = links.map((link) => { return { ...link, url: new url_1.URL(link.url, hostname).toString() }; }); if (smiLoose.video) { if (!Array.isArray(smiLoose.video)) { // make it an array smiLoose.video = [smiLoose.video]; } smi.video = smiLoose.video.map((video) => { const nv = { ...video, family_friendly: boolToYESNO(video.family_friendly), live: boolToYESNO(video.live), requires_subscription: boolToYESNO(video.requires_subscription), tag: [], rating: undefined, }; if (video.tag !== undefined) { nv.tag = !Array.isArray(video.tag) ? [video.tag] : video.tag; } if (video.rating !== undefined) { if (typeof video.rating === 'string') { nv.rating = parseFloat(video.rating); } else { nv.rating = video.rating; } } if (typeof video.view_count === 'string') { nv.view_count = parseInt(video.view_count, 10); } else if (typeof video.view_count === 'number') { nv.view_count = video.view_count; } return nv; }); } // If given a file to use for last modified date if (smiLoose.lastmodfile) { const { mtime } = (0, fs_1.statSync)(smiLoose.lastmodfile); smi.lastmod = new Date(mtime).toISOString(); // The date of last modification (YYYY-MM-DD) } else if (smiLoose.lastmodISO) { smi.lastmod = new Date(smiLoose.lastmodISO).toISOString(); } else if (smiLoose.lastmod) { smi.lastmod = new Date(smiLoose.lastmod).toISOString(); } if (lastmodDateOnly && smi.lastmod) { smi.lastmod = smi.lastmod.slice(0, 10); } delete smiLoose.lastmodfile; delete smiLoose.lastmodISO; smi = { ...smiLoose, ...smi }; return smi; } utils$l.normalizeURL = normalizeURL; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.streamToPromise = exports.SitemapStream = exports.closetag = exports.stylesheetInclude = void 0; const stream_1 = require$$0; const types_1 = types; const utils_1 = utils$l; const sitemap_item_stream_1 = sitemapItemStream; const errors_1 = errors; const xmlDec = ''; const stylesheetInclude = (url) => { return ``; }; exports.stylesheetInclude = stylesheetInclude; const urlsetTagStart = ' { let ns = xmlDec; if (xslURL) { ns += (0, exports.stylesheetInclude)(xslURL); } ns += urlsetTagStart; if (news) { ns += ' xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"'; } if (xhtml) { ns += ' xmlns:xhtml="http://www.w3.org/1999/xhtml"'; } if (image) { ns += ' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"'; } if (video) { ns += ' xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"'; } if (custom) { ns += ' ' + custom.join(' '); } return ns + '>'; }; exports.closetag = ''; const defaultXMLNS = { news: true, xhtml: true, image: true, video: true, }; const defaultStreamOpts = { xmlns: defaultXMLNS, }; /** * A [Transform](https://nodejs.org/api/stream.html#stream_implementing_a_transform_stream) * for turning a * [Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) * of either [SitemapItemOptions](#sitemap-item-options) or url strings into a * Sitemap. The readable stream it transforms **must** be in object mode. */ class SitemapStream extends stream_1.Transform { constructor(opts = defaultStreamOpts) { opts.objectMode = true; super(opts); this.hasHeadOutput = false; this.hostname = opts.hostname; this.level = opts.level || types_1.ErrorLevel.WARN; this.errorHandler = opts.errorHandler; this.smiStream = new sitemap_item_stream_1.SitemapItemStream({ level: opts.level }); this.smiStream.on('data', (data) => this.push(data)); this.lastmodDateOnly = opts.lastmodDateOnly || false; this.xmlNS = opts.xmlns || defaultXMLNS; this.xslUrl = opts.xslUrl; } _transform(item, encoding, callback) { if (!this.hasHeadOutput) { this.hasHeadOutput = true; this.push(getURLSetNs(this.xmlNS, this.xslUrl)); } if (!this.smiStream.write((0, utils_1.validateSMIOptions)((0, utils_1.normalizeURL)(item, this.hostname, this.lastmodDateOnly), this.level, this.errorHandler))) { this.smiStream.once('drain', callback); } else { process.nextTick(callback); } } _flush(cb) { if (!this.hasHeadOutput) { cb(new errors_1.EmptySitemap()); } else { this.push(exports.closetag); cb(); } } } exports.SitemapStream = SitemapStream; /** * Converts a readable stream into a promise that resolves with the concatenated data from the stream. * * The function listens for 'data' events from the stream, and when the stream ends, it resolves the promise with the concatenated data. If an error occurs while reading from the stream, the promise is rejected with the error. * * ⚠️ CAUTION: This function should not generally be used in production / when writing to files as it holds a copy of the entire file contents in memory until finished. * * @param {Readable} stream - The readable stream to convert to a promise. * @returns {Promise} A promise that resolves with the concatenated data from the stream as a Buffer, or rejects with an error if one occurred while reading from the stream. If the stream is empty, the promise is rejected with an EmptyStream error. * @throws {EmptyStream} If the stream is empty. */ function streamToPromise(stream) { return new Promise((resolve, reject) => { const drain = []; stream // Error propagation is not automatic // Bubble up errors on the read stream .on('error', reject) .pipe(new stream_1.Writable({ write(chunk, enc, next) { drain.push(chunk); next(); }, })) // This bubbles up errors when writing to the internal buffer // This is unlikely to happen, but we have this for completeness .on('error', reject) .on('finish', () => { if (!drain.length) { reject(new errors_1.EmptyStream()); } else { resolve(Buffer.concat(drain)); } }); }); } exports.streamToPromise = streamToPromise; } (sitemapStream)); (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.SitemapAndIndexStream = exports.SitemapIndexStream = exports.IndexTagNames = void 0; const stream_1 = require$$0; const types_1 = types; const sitemap_stream_1 = sitemapStream; const sitemap_xml_1 = sitemapXml; var IndexTagNames; (function (IndexTagNames) { IndexTagNames["sitemap"] = "sitemap"; IndexTagNames["loc"] = "loc"; IndexTagNames["lastmod"] = "lastmod"; })(IndexTagNames = exports.IndexTagNames || (exports.IndexTagNames = {})); const xmlDec = ''; const sitemapIndexTagStart = ''; const closetag = ''; const defaultStreamOpts = {}; /** * `SitemapIndexStream` is a Transform stream that takes `IndexItem`s or sitemap URL strings and outputs a stream of sitemap index XML. * * It automatically handles the XML declaration and the opening and closing tags for the sitemap index. * * ⚠️ CAUTION: This object is `readable` and must be read (e.g. piped to a file or to /dev/null) * before `finish` will be emitted. Failure to read the stream will result in hangs. * * @extends {Transform} */ class SitemapIndexStream extends stream_1.Transform { /** * `SitemapIndexStream` is a Transform stream that takes `IndexItem`s or sitemap URL strings and outputs a stream of sitemap index XML. * * It automatically handles the XML declaration and the opening and closing tags for the sitemap index. * * ⚠️ CAUTION: This object is `readable` and must be read (e.g. piped to a file or to /dev/null) * before `finish` will be emitted. Failure to read the stream will result in hangs. * * @param {SitemapIndexStreamOptions} [opts=defaultStreamOpts] - Stream options. */ constructor(opts = defaultStreamOpts) { var _a; opts.objectMode = true; super(opts); this.hasHeadOutput = false; this.lastmodDateOnly = opts.lastmodDateOnly || false; this.level = (_a = opts.level) !== null && _a !== void 0 ? _a : types_1.ErrorLevel.WARN; this.xslUrl = opts.xslUrl; } writeHeadOutput() { this.hasHeadOutput = true; let stylesheet = ''; if (this.xslUrl) { stylesheet = (0, sitemap_stream_1.stylesheetInclude)(this.xslUrl); } this.push(xmlDec + stylesheet + sitemapIndexTagStart); } _transform(item, encoding, callback) { if (!this.hasHeadOutput) { this.writeHeadOutput(); } this.push((0, sitemap_xml_1.otag)(IndexTagNames.sitemap)); if (typeof item === 'string') { this.push((0, sitemap_xml_1.element)(IndexTagNames.loc, item)); } else { this.push((0, sitemap_xml_1.element)(IndexTagNames.loc, item.url)); if (item.lastmod) { const lastmod = new Date(item.lastmod).toISOString(); this.push((0, sitemap_xml_1.element)(IndexTagNames.lastmod, this.lastmodDateOnly ? lastmod.slice(0, 10) : lastmod)); } } this.push((0, sitemap_xml_1.ctag)(IndexTagNames.sitemap)); callback(); } _flush(cb) { if (!this.hasHeadOutput) { this.writeHeadOutput(); } this.push(closetag); cb(); } } exports.SitemapIndexStream = SitemapIndexStream; /** * `SitemapAndIndexStream` is a Transform stream that takes in sitemap items, * writes them to sitemap files, adds the sitemap files to a sitemap index, * and creates new sitemap files when the count limit is reached. * * It waits for the target stream of the current sitemap file to finish before * moving on to the next if the target stream is returned by the `getSitemapStream` * callback in the 3rd position of the tuple. * * ⚠️ CAUTION: This object is `readable` and must be read (e.g. piped to a file or to /dev/null) * before `finish` will be emitted. Failure to read the stream will result in hangs. * * @extends {SitemapIndexStream} */ class SitemapAndIndexStream extends SitemapIndexStream { /** * `SitemapAndIndexStream` is a Transform stream that takes in sitemap items, * writes them to sitemap files, adds the sitemap files to a sitemap index, * and creates new sitemap files when the count limit is reached. * * It waits for the target stream of the current sitemap file to finish before * moving on to the next if the target stream is returned by the `getSitemapStream` * callback in the 3rd position of the tuple. * * ⚠️ CAUTION: This object is `readable` and must be read (e.g. piped to a file or to /dev/null) * before `finish` will be emitted. Failure to read the stream will result in hangs. * * @param {SitemapAndIndexStreamOptions} opts - Stream options. */ constructor(opts) { var _a; opts.objectMode = true; super(opts); this.itemsWritten = 0; this.getSitemapStream = opts.getSitemapStream; this.limit = (_a = opts.limit) !== null && _a !== void 0 ? _a : 45000; } _transform(item, encoding, callback) { if (this.itemsWritten % this.limit === 0) { if (this.currentSitemap) { const onFinish = new Promise((resolve, reject) => { var _a, _b, _c; (_a = this.currentSitemap) === null || _a === void 0 ? void 0 : _a.on('finish', resolve); (_b = this.currentSitemap) === null || _b === void 0 ? void 0 : _b.on('error', reject); (_c = this.currentSitemap) === null || _c === void 0 ? void 0 : _c.end(); }); const onPipelineFinish = this.currentSitemapPipeline ? new Promise((resolve, reject) => { var _a, _b; (_a = this.currentSitemapPipeline) === null || _a === void 0 ? void 0 : _a.on('finish', resolve); (_b = this.currentSitemapPipeline) === null || _b === void 0 ? void 0 : _b.on('error', reject); }) : Promise.resolve(); Promise.all([onFinish, onPipelineFinish]) .then(() => { this.createSitemap(encoding); this.writeItem(item, callback); }) .catch(callback); return; } else { this.createSitemap(encoding); } } this.writeItem(item, callback); } writeItem(item, callback) { if (!this.currentSitemap) { callback(new Error('No sitemap stream available')); return; } if (!this.currentSitemap.write(item)) { this.currentSitemap.once('drain', callback); } else { process.nextTick(callback); } // Increment the count of items written this.itemsWritten++; } /** * Called when the stream is finished. * If there is a current sitemap, we wait for it to finish before calling the callback. * * @param cb */ _flush(cb) { const onFinish = new Promise((resolve, reject) => { if (this.currentSitemap) { this.currentSitemap.on('finish', resolve); this.currentSitemap.on('error', reject); this.currentSitemap.end(); } else { resolve(); } }); const onPipelineFinish = new Promise((resolve, reject) => { if (this.currentSitemapPipeline) { this.currentSitemapPipeline.on('finish', resolve); this.currentSitemapPipeline.on('error', reject); // The pipeline (pipe target) will get it's end() call // from the sitemap stream ending. } else { resolve(); } }); Promise.all([onFinish, onPipelineFinish]) .then(() => { super._flush(cb); }) .catch((err) => { cb(err); }); } createSitemap(encoding) { const [idxItem, currentSitemap, currentSitemapPipeline] = this.getSitemapStream(this.itemsWritten / this.limit); currentSitemap.on('error', (err) => this.emit('error', err)); this.currentSitemap = currentSitemap; this.currentSitemapPipeline = currentSitemapPipeline; super._transform(idxItem, encoding, () => { // We are not too fussed about waiting for the index item to be written // we we'll wait for the file to finish at the end // and index file write volume tends to be small in comprarison to sitemap // writes. // noop }); } } exports.SitemapAndIndexStream = SitemapAndIndexStream; } (sitemapIndexStream)); var xmllint = {}; Object.defineProperty(xmllint, "__esModule", { value: true }); xmllint.xmlLint = void 0; const path_1 = require$$0$2; const child_process_1 = require$$1; const errors_1 = errors; /** * Verify the passed in xml is valid. Requires xmllib be installed * @param xml what you want validated * @return {Promise} resolves on valid rejects [error stderr] */ function xmlLint(xml) { const args = [ '--schema', (0, path_1.resolve)(__dirname, '..', '..', 'schema', 'all.xsd'), '--noout', '-', ]; if (typeof xml === 'string') { args[args.length - 1] = xml; } return new Promise((resolve, reject) => { (0, child_process_1.execFile)('which', ['xmllint'], (error, stdout, stderr) => { if (error) { reject([new errors_1.XMLLintUnavailable()]); return; } const xmllint = (0, child_process_1.execFile)('xmllint', args, (error, stdout, stderr) => { if (error) { reject([error, stderr]); } resolve(); }); if (xmllint.stdout) { xmllint.stdout.unpipe(); if (typeof xml !== 'string' && xml && xmllint.stdin) { xml.pipe(xmllint.stdin); } } }); }); } xmllint.xmlLint = xmlLint; var sitemapParser = {}; var require$1 = ( true ? /* @__PURE__ */ createRequire(import.meta.url) : require ); var sax = {}; (function (exports) { (function (sax) { // wrapper for non-node envs sax.parser = function (strict, opt) { return new SAXParser(strict, opt) }; sax.SAXParser = SAXParser; sax.SAXStream = SAXStream; sax.createStream = createStream; // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), // since that's the earliest that a buffer overrun could occur. This way, checks are // as rare as required, but as often as necessary to ensure never crossing this bound. // Furthermore, buffers are only tested at most once per write(), so passing a very // large string into write() might have undesirable effects, but this is manageable by // the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme // edge case, result in creating at most one complete copy of the string passed in. // Set to Infinity to have unlimited buffers. sax.MAX_BUFFER_LENGTH = 64 * 1024; var buffers = [ 'comment', 'sgmlDecl', 'textNode', 'tagName', 'doctype', 'procInstName', 'procInstBody', 'entity', 'attribName', 'attribValue', 'cdata', 'script' ]; sax.EVENTS = [ 'text', 'processinginstruction', 'sgmldeclaration', 'doctype', 'comment', 'opentagstart', 'attribute', 'opentag', 'closetag', 'opencdata', 'cdata', 'closecdata', 'error', 'end', 'ready', 'script', 'opennamespace', 'closenamespace' ]; function SAXParser (strict, opt) { if (!(this instanceof SAXParser)) { return new SAXParser(strict, opt) } var parser = this; clearBuffers(parser); parser.q = parser.c = ''; parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH; parser.opt = opt || {}; parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags; parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase'; parser.tags = []; parser.closed = parser.closedRoot = parser.sawRoot = false; parser.tag = parser.error = null; parser.strict = !!strict; parser.noscript = !!(strict || parser.opt.noscript); parser.state = S.BEGIN; parser.strictEntities = parser.opt.strictEntities; parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES); parser.attribList = []; // namespaces form a prototype chain. // it always points at the current tag, // which protos to its parent tag. if (parser.opt.xmlns) { parser.ns = Object.create(rootNS); } // disallow unquoted attribute values if not otherwise configured // and strict mode is true if (parser.opt.unquotedAttributeValues === undefined) { parser.opt.unquotedAttributeValues = !strict; } // mostly just for error reporting parser.trackPosition = parser.opt.position !== false; if (parser.trackPosition) { parser.position = parser.line = parser.column = 0; } emit(parser, 'onready'); } if (!Object.create) { Object.create = function (o) { function F () {} F.prototype = o; var newf = new F(); return newf }; } if (!Object.keys) { Object.keys = function (o) { var a = []; for (var i in o) if (o.hasOwnProperty(i)) a.push(i); return a }; } function checkBufferLength (parser) { var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10); var maxActual = 0; for (var i = 0, l = buffers.length; i < l; i++) { var len = parser[buffers[i]].length; if (len > maxAllowed) { // Text/cdata nodes can get big, and since they're buffered, // we can get here under normal conditions. // Avoid issues by emitting the text node now, // so at least it won't get any bigger. switch (buffers[i]) { case 'textNode': closeText(parser); break case 'cdata': emitNode(parser, 'oncdata', parser.cdata); parser.cdata = ''; break case 'script': emitNode(parser, 'onscript', parser.script); parser.script = ''; break default: error(parser, 'Max buffer length exceeded: ' + buffers[i]); } } maxActual = Math.max(maxActual, len); } // schedule the next check for the earliest possible buffer overrun. var m = sax.MAX_BUFFER_LENGTH - maxActual; parser.bufferCheckPosition = m + parser.position; } function clearBuffers (parser) { for (var i = 0, l = buffers.length; i < l; i++) { parser[buffers[i]] = ''; } } function flushBuffers (parser) { closeText(parser); if (parser.cdata !== '') { emitNode(parser, 'oncdata', parser.cdata); parser.cdata = ''; } if (parser.script !== '') { emitNode(parser, 'onscript', parser.script); parser.script = ''; } } SAXParser.prototype = { end: function () { end(this); }, write: write, resume: function () { this.error = null; return this }, close: function () { return this.write(null) }, flush: function () { flushBuffers(this); } }; var Stream; try { Stream = require$1('stream').Stream; } catch (ex) { Stream = function () {}; } if (!Stream) Stream = function () {}; var streamWraps = sax.EVENTS.filter(function (ev) { return ev !== 'error' && ev !== 'end' }); function createStream (strict, opt) { return new SAXStream(strict, opt) } function SAXStream (strict, opt) { if (!(this instanceof SAXStream)) { return new SAXStream(strict, opt) } Stream.apply(this); this._parser = new SAXParser(strict, opt); this.writable = true; this.readable = true; var me = this; this._parser.onend = function () { me.emit('end'); }; this._parser.onerror = function (er) { me.emit('error', er); // if didn't throw, then means error was handled. // go ahead and clear error, so we can write again. me._parser.error = null; }; this._decoder = null; streamWraps.forEach(function (ev) { Object.defineProperty(me, 'on' + ev, { get: function () { return me._parser['on' + ev] }, set: function (h) { if (!h) { me.removeAllListeners(ev); me._parser['on' + ev] = h; return h } me.on(ev, h); }, enumerable: true, configurable: false }); }); } SAXStream.prototype = Object.create(Stream.prototype, { constructor: { value: SAXStream } }); SAXStream.prototype.write = function (data) { if (typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function' && Buffer.isBuffer(data)) { if (!this._decoder) { var SD = require$$1$1.StringDecoder; this._decoder = new SD('utf8'); } data = this._decoder.write(data); } this._parser.write(data.toString()); this.emit('data', data); return true }; SAXStream.prototype.end = function (chunk) { if (chunk && chunk.length) { this.write(chunk); } this._parser.end(); return true }; SAXStream.prototype.on = function (ev, handler) { var me = this; if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) { me._parser['on' + ev] = function () { var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments); args.splice(0, 0, ev); me.emit.apply(me, args); }; } return Stream.prototype.on.call(me, ev, handler) }; // this really needs to be replaced with character classes. // XML allows all manner of ridiculous numbers and digits. var CDATA = '[CDATA['; var DOCTYPE = 'DOCTYPE'; var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'; var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'; var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE }; // http://www.w3.org/TR/REC-xml/#NT-NameStartChar // This implementation works on strings, a single character at a time // as such, it cannot ever support astral-plane characters (10000-EFFFF) // without a significant breaking change to either this parser, or the // JavaScript language. Implementation of an emoji-capable xml parser // is left as an exercise for the reader. var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/; var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/; function isWhitespace (c) { return c === ' ' || c === '\n' || c === '\r' || c === '\t' } function isQuote (c) { return c === '"' || c === '\'' } function isAttribEnd (c) { return c === '>' || isWhitespace(c) } function isMatch (regex, c) { return regex.test(c) } function notMatch (regex, c) { return !isMatch(regex, c) } var S = 0; sax.STATE = { BEGIN: S++, // leading byte order mark or whitespace BEGIN_WHITESPACE: S++, // leading whitespace TEXT: S++, // general stuff TEXT_ENTITY: S++, // & and such. OPEN_WAKA: S++, // < SGML_DECL: S++, // SCRIPT: S++, //