export const id = 593; export const ids = [593]; export const modules = { /***/ 4340: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {PassThrough: PassThroughStream} = __webpack_require__(2781); module.exports = options => { options = {...options}; const {array} = options; let {encoding} = options; const isBuffer = encoding === 'buffer'; let objectMode = false; if (array) { objectMode = !(encoding || isBuffer); } else { encoding = encoding || 'utf8'; } if (isBuffer) { encoding = null; } const stream = new PassThroughStream({objectMode}); if (encoding) { stream.setEncoding(encoding); } let length = 0; const chunks = []; stream.on('data', chunk => { chunks.push(chunk); if (objectMode) { length = chunks.length; } else { length += chunk.length; } }); stream.getBufferedValue = () => { if (array) { return chunks; } return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); }; stream.getBufferedLength = () => length; return stream; }; /***/ }), /***/ 7040: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {constants: BufferConstants} = __webpack_require__(4300); const stream = __webpack_require__(2781); const {promisify} = __webpack_require__(3837); const bufferStream = __webpack_require__(4340); const streamPipelinePromisified = promisify(stream.pipeline); class MaxBufferError extends Error { constructor() { super('maxBuffer exceeded'); this.name = 'MaxBufferError'; } } async function getStream(inputStream, options) { if (!inputStream) { throw new Error('Expected a stream'); } options = { maxBuffer: Infinity, ...options }; const {maxBuffer} = options; const stream = bufferStream(options); await new Promise((resolve, reject) => { const rejectPromise = error => { // Don't retrieve an oversized buffer. if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) { error.bufferedData = stream.getBufferedValue(); } reject(error); }; (async () => { try { await streamPipelinePromisified(inputStream, stream); resolve(); } catch (error) { rejectPromise(error); } })(); stream.on('data', () => { if (stream.getBufferedLength() > maxBuffer) { rejectPromise(new MaxBufferError()); } }); }); return stream.getBufferedValue(); } module.exports = getStream; module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); module.exports.MaxBufferError = MaxBufferError; /***/ }), /***/ 2391: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {Transform, PassThrough} = __webpack_require__(2781); const zlib = __webpack_require__(9796); const mimicResponse = __webpack_require__(3877); module.exports = response => { const contentEncoding = (response.headers['content-encoding'] || '').toLowerCase(); if (!['gzip', 'deflate', 'br'].includes(contentEncoding)) { return response; } // TODO: Remove this when targeting Node.js 12. const isBrotli = contentEncoding === 'br'; if (isBrotli && typeof zlib.createBrotliDecompress !== 'function') { response.destroy(new Error('Brotli is not supported on Node.js < 12')); return response; } let isEmpty = true; const checker = new Transform({ transform(data, _encoding, callback) { isEmpty = false; callback(null, data); }, flush(callback) { callback(); } }); const finalStream = new PassThrough({ autoDestroy: false, destroy(error, callback) { response.destroy(); callback(error); } }); const decompressStream = isBrotli ? zlib.createBrotliDecompress() : zlib.createUnzip(); decompressStream.once('error', error => { if (isEmpty && !response.readable) { finalStream.end(); return; } finalStream.destroy(error); }); mimicResponse(response, finalStream); response.pipe(checker).pipe(decompressStream).pipe(finalStream); return finalStream; }; /***/ }), /***/ 3877: /***/ ((module) => { // We define these manually to ensure they're always copied // even if they would move up the prototype chain // https://nodejs.org/api/http.html#http_class_http_incomingmessage const knownProperties = [ 'aborted', 'complete', 'headers', 'httpVersion', 'httpVersionMinor', 'httpVersionMajor', 'method', 'rawHeaders', 'rawTrailers', 'setTimeout', 'socket', 'statusCode', 'statusMessage', 'trailers', 'url' ]; module.exports = (fromStream, toStream) => { if (toStream._readableState.autoDestroy) { throw new Error('The second stream must have the `autoDestroy` option set to `false`'); } const fromProperties = new Set(Object.keys(fromStream).concat(knownProperties)); const properties = {}; for (const property of fromProperties) { // Don't overwrite existing properties. if (property in toStream) { continue; } properties[property] = { get() { const value = fromStream[property]; const isFunction = typeof value === 'function'; return isFunction ? value.bind(fromStream) : value; }, set(value) { fromStream[property] = value; }, enumerable: true, configurable: false }; } Object.defineProperties(toStream, properties); fromStream.once('aborted', () => { toStream.destroy(); toStream.emit('aborted'); }); fromStream.once('close', () => { if (fromStream.complete) { if (toStream.readable) { toStream.once('end', () => { toStream.emit('close'); }); } else { toStream.emit('close'); } } else { toStream.emit('close'); } }); return toStream; }; /***/ }), /***/ 6214: /***/ ((module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); function isTLSSocket(socket) { return socket.encrypted; } const deferToConnect = (socket, fn) => { let listeners; if (typeof fn === 'function') { const connect = fn; listeners = { connect }; } else { listeners = fn; } const hasConnectListener = typeof listeners.connect === 'function'; const hasSecureConnectListener = typeof listeners.secureConnect === 'function'; const hasCloseListener = typeof listeners.close === 'function'; const onConnect = () => { if (hasConnectListener) { listeners.connect(); } if (isTLSSocket(socket) && hasSecureConnectListener) { if (socket.authorized) { listeners.secureConnect(); } else if (!socket.authorizationError) { socket.once('secureConnect', listeners.secureConnect); } } if (hasCloseListener) { socket.once('close', listeners.close); } }; if (socket.writable && !socket.connecting) { onConnect(); } else if (socket.connecting) { socket.once('connect', onConnect); } else if (socket.destroyed && hasCloseListener) { listeners.close(socket._hadError); } }; exports["default"] = deferToConnect; // For CommonJS default export support module.exports = deferToConnect; module.exports["default"] = deferToConnect; /***/ }), /***/ 5066: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {PassThrough: PassThroughStream} = __webpack_require__(2781); module.exports = options => { options = {...options}; const {array} = options; let {encoding} = options; const isBuffer = encoding === 'buffer'; let objectMode = false; if (array) { objectMode = !(encoding || isBuffer); } else { encoding = encoding || 'utf8'; } if (isBuffer) { encoding = null; } const stream = new PassThroughStream({objectMode}); if (encoding) { stream.setEncoding(encoding); } let length = 0; const chunks = []; stream.on('data', chunk => { chunks.push(chunk); if (objectMode) { length = chunks.length; } else { length += chunk.length; } }); stream.getBufferedValue = () => { if (array) { return chunks; } return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); }; stream.getBufferedLength = () => length; return stream; }; /***/ }), /***/ 6741: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {constants: BufferConstants} = __webpack_require__(4300); const stream = __webpack_require__(2781); const {promisify} = __webpack_require__(3837); const bufferStream = __webpack_require__(5066); const streamPipelinePromisified = promisify(stream.pipeline); class MaxBufferError extends Error { constructor() { super('maxBuffer exceeded'); this.name = 'MaxBufferError'; } } async function getStream(inputStream, options) { if (!inputStream) { throw new Error('Expected a stream'); } options = { maxBuffer: Infinity, ...options }; const {maxBuffer} = options; const stream = bufferStream(options); await new Promise((resolve, reject) => { const rejectPromise = error => { // Don't retrieve an oversized buffer. if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) { error.bufferedData = stream.getBufferedValue(); } reject(error); }; (async () => { try { await streamPipelinePromisified(inputStream, stream); resolve(); } catch (error) { rejectPromise(error); } })(); stream.on('data', () => { if (stream.getBufferedLength() > maxBuffer) { rejectPromise(new MaxBufferError()); } }); }); return stream.getBufferedValue(); } module.exports = getStream; module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); module.exports.MaxBufferError = MaxBufferError; /***/ }), /***/ 1002: /***/ ((module) => { // rfc7231 6.1 const statusCodeCacheableByDefault = new Set([ 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501, ]); // This implementation does not understand partial responses (206) const understoodStatuses = new Set([ 200, 203, 204, 300, 301, 302, 303, 307, 308, 404, 405, 410, 414, 501, ]); const errorStatusCodes = new Set([ 500, 502, 503, 504, ]); const hopByHopHeaders = { date: true, // included, because we add Age update Date connection: true, 'keep-alive': true, 'proxy-authenticate': true, 'proxy-authorization': true, te: true, trailer: true, 'transfer-encoding': true, upgrade: true, }; const excludedFromRevalidationUpdate = { // Since the old body is reused, it doesn't make sense to change properties of the body 'content-length': true, 'content-encoding': true, 'transfer-encoding': true, 'content-range': true, }; function toNumberOrZero(s) { const n = parseInt(s, 10); return isFinite(n) ? n : 0; } // RFC 5861 function isErrorResponse(response) { // consider undefined response as faulty if(!response) { return true } return errorStatusCodes.has(response.status); } function parseCacheControl(header) { const cc = {}; if (!header) return cc; // TODO: When there is more than one value present for a given directive (e.g., two Expires header fields, multiple Cache-Control: max-age directives), // the directive's value is considered invalid. Caches are encouraged to consider responses that have invalid freshness information to be stale const parts = header.trim().split(/\s*,\s*/); // TODO: lame parsing for (const part of parts) { const [k, v] = part.split(/\s*=\s*/, 2); cc[k] = v === undefined ? true : v.replace(/^"|"$/g, ''); // TODO: lame unquoting } return cc; } function formatCacheControl(cc) { let parts = []; for (const k in cc) { const v = cc[k]; parts.push(v === true ? k : k + '=' + v); } if (!parts.length) { return undefined; } return parts.join(', '); } module.exports = class CachePolicy { constructor( req, res, { shared, cacheHeuristic, immutableMinTimeToLive, ignoreCargoCult, _fromObject, } = {} ) { if (_fromObject) { this._fromObject(_fromObject); return; } if (!res || !res.headers) { throw Error('Response headers missing'); } this._assertRequestHasHeaders(req); this._responseTime = this.now(); this._isShared = shared !== false; this._cacheHeuristic = undefined !== cacheHeuristic ? cacheHeuristic : 0.1; // 10% matches IE this._immutableMinTtl = undefined !== immutableMinTimeToLive ? immutableMinTimeToLive : 24 * 3600 * 1000; this._status = 'status' in res ? res.status : 200; this._resHeaders = res.headers; this._rescc = parseCacheControl(res.headers['cache-control']); this._method = 'method' in req ? req.method : 'GET'; this._url = req.url; this._host = req.headers.host; this._noAuthorization = !req.headers.authorization; this._reqHeaders = res.headers.vary ? req.headers : null; // Don't keep all request headers if they won't be used this._reqcc = parseCacheControl(req.headers['cache-control']); // Assume that if someone uses legacy, non-standard uncecessary options they don't understand caching, // so there's no point stricly adhering to the blindly copy&pasted directives. if ( ignoreCargoCult && 'pre-check' in this._rescc && 'post-check' in this._rescc ) { delete this._rescc['pre-check']; delete this._rescc['post-check']; delete this._rescc['no-cache']; delete this._rescc['no-store']; delete this._rescc['must-revalidate']; this._resHeaders = Object.assign({}, this._resHeaders, { 'cache-control': formatCacheControl(this._rescc), }); delete this._resHeaders.expires; delete this._resHeaders.pragma; } // When the Cache-Control header field is not present in a request, caches MUST consider the no-cache request pragma-directive // as having the same effect as if "Cache-Control: no-cache" were present (see Section 5.2.1). if ( res.headers['cache-control'] == null && /no-cache/.test(res.headers.pragma) ) { this._rescc['no-cache'] = true; } } now() { return Date.now(); } storable() { // The "no-store" request directive indicates that a cache MUST NOT store any part of either this request or any response to it. return !!( !this._reqcc['no-store'] && // A cache MUST NOT store a response to any request, unless: // The request method is understood by the cache and defined as being cacheable, and ('GET' === this._method || 'HEAD' === this._method || ('POST' === this._method && this._hasExplicitExpiration())) && // the response status code is understood by the cache, and understoodStatuses.has(this._status) && // the "no-store" cache directive does not appear in request or response header fields, and !this._rescc['no-store'] && // the "private" response directive does not appear in the response, if the cache is shared, and (!this._isShared || !this._rescc.private) && // the Authorization header field does not appear in the request, if the cache is shared, (!this._isShared || this._noAuthorization || this._allowsStoringAuthenticated()) && // the response either: // contains an Expires header field, or (this._resHeaders.expires || // contains a max-age response directive, or // contains a s-maxage response directive and the cache is shared, or // contains a public response directive. this._rescc['max-age'] || (this._isShared && this._rescc['s-maxage']) || this._rescc.public || // has a status code that is defined as cacheable by default statusCodeCacheableByDefault.has(this._status)) ); } _hasExplicitExpiration() { // 4.2.1 Calculating Freshness Lifetime return ( (this._isShared && this._rescc['s-maxage']) || this._rescc['max-age'] || this._resHeaders.expires ); } _assertRequestHasHeaders(req) { if (!req || !req.headers) { throw Error('Request headers missing'); } } satisfiesWithoutRevalidation(req) { this._assertRequestHasHeaders(req); // When presented with a request, a cache MUST NOT reuse a stored response, unless: // the presented request does not contain the no-cache pragma (Section 5.4), nor the no-cache cache directive, // unless the stored response is successfully validated (Section 4.3), and const requestCC = parseCacheControl(req.headers['cache-control']); if (requestCC['no-cache'] || /no-cache/.test(req.headers.pragma)) { return false; } if (requestCC['max-age'] && this.age() > requestCC['max-age']) { return false; } if ( requestCC['min-fresh'] && this.timeToLive() < 1000 * requestCC['min-fresh'] ) { return false; } // the stored response is either: // fresh, or allowed to be served stale if (this.stale()) { const allowsStale = requestCC['max-stale'] && !this._rescc['must-revalidate'] && (true === requestCC['max-stale'] || requestCC['max-stale'] > this.age() - this.maxAge()); if (!allowsStale) { return false; } } return this._requestMatches(req, false); } _requestMatches(req, allowHeadMethod) { // The presented effective request URI and that of the stored response match, and return ( (!this._url || this._url === req.url) && this._host === req.headers.host && // the request method associated with the stored response allows it to be used for the presented request, and (!req.method || this._method === req.method || (allowHeadMethod && 'HEAD' === req.method)) && // selecting header fields nominated by the stored response (if any) match those presented, and this._varyMatches(req) ); } _allowsStoringAuthenticated() { // following Cache-Control response directives (Section 5.2.2) have such an effect: must-revalidate, public, and s-maxage. return ( this._rescc['must-revalidate'] || this._rescc.public || this._rescc['s-maxage'] ); } _varyMatches(req) { if (!this._resHeaders.vary) { return true; } // A Vary header field-value of "*" always fails to match if (this._resHeaders.vary === '*') { return false; } const fields = this._resHeaders.vary .trim() .toLowerCase() .split(/\s*,\s*/); for (const name of fields) { if (req.headers[name] !== this._reqHeaders[name]) return false; } return true; } _copyWithoutHopByHopHeaders(inHeaders) { const headers = {}; for (const name in inHeaders) { if (hopByHopHeaders[name]) continue; headers[name] = inHeaders[name]; } // 9.1. Connection if (inHeaders.connection) { const tokens = inHeaders.connection.trim().split(/\s*,\s*/); for (const name of tokens) { delete headers[name]; } } if (headers.warning) { const warnings = headers.warning.split(/,/).filter(warning => { return !/^\s*1[0-9][0-9]/.test(warning); }); if (!warnings.length) { delete headers.warning; } else { headers.warning = warnings.join(',').trim(); } } return headers; } responseHeaders() { const headers = this._copyWithoutHopByHopHeaders(this._resHeaders); const age = this.age(); // A cache SHOULD generate 113 warning if it heuristically chose a freshness // lifetime greater than 24 hours and the response's age is greater than 24 hours. if ( age > 3600 * 24 && !this._hasExplicitExpiration() && this.maxAge() > 3600 * 24 ) { headers.warning = (headers.warning ? `${headers.warning}, ` : '') + '113 - "rfc7234 5.5.4"'; } headers.age = `${Math.round(age)}`; headers.date = new Date(this.now()).toUTCString(); return headers; } /** * Value of the Date response header or current time if Date was invalid * @return timestamp */ date() { const serverDate = Date.parse(this._resHeaders.date); if (isFinite(serverDate)) { return serverDate; } return this._responseTime; } /** * Value of the Age header, in seconds, updated for the current time. * May be fractional. * * @return Number */ age() { let age = this._ageValue(); const residentTime = (this.now() - this._responseTime) / 1000; return age + residentTime; } _ageValue() { return toNumberOrZero(this._resHeaders.age); } /** * Value of applicable max-age (or heuristic equivalent) in seconds. This counts since response's `Date`. * * For an up-to-date value, see `timeToLive()`. * * @return Number */ maxAge() { if (!this.storable() || this._rescc['no-cache']) { return 0; } // Shared responses with cookies are cacheable according to the RFC, but IMHO it'd be unwise to do so by default // so this implementation requires explicit opt-in via public header if ( this._isShared && (this._resHeaders['set-cookie'] && !this._rescc.public && !this._rescc.immutable) ) { return 0; } if (this._resHeaders.vary === '*') { return 0; } if (this._isShared) { if (this._rescc['proxy-revalidate']) { return 0; } // if a response includes the s-maxage directive, a shared cache recipient MUST ignore the Expires field. if (this._rescc['s-maxage']) { return toNumberOrZero(this._rescc['s-maxage']); } } // If a response includes a Cache-Control field with the max-age directive, a recipient MUST ignore the Expires field. if (this._rescc['max-age']) { return toNumberOrZero(this._rescc['max-age']); } const defaultMinTtl = this._rescc.immutable ? this._immutableMinTtl : 0; const serverDate = this.date(); if (this._resHeaders.expires) { const expires = Date.parse(this._resHeaders.expires); // A cache recipient MUST interpret invalid date formats, especially the value "0", as representing a time in the past (i.e., "already expired"). if (Number.isNaN(expires) || expires < serverDate) { return 0; } return Math.max(defaultMinTtl, (expires - serverDate) / 1000); } if (this._resHeaders['last-modified']) { const lastModified = Date.parse(this._resHeaders['last-modified']); if (isFinite(lastModified) && serverDate > lastModified) { return Math.max( defaultMinTtl, ((serverDate - lastModified) / 1000) * this._cacheHeuristic ); } } return defaultMinTtl; } timeToLive() { const age = this.maxAge() - this.age(); const staleIfErrorAge = age + toNumberOrZero(this._rescc['stale-if-error']); const staleWhileRevalidateAge = age + toNumberOrZero(this._rescc['stale-while-revalidate']); return Math.max(0, age, staleIfErrorAge, staleWhileRevalidateAge) * 1000; } stale() { return this.maxAge() <= this.age(); } _useStaleIfError() { return this.maxAge() + toNumberOrZero(this._rescc['stale-if-error']) > this.age(); } useStaleWhileRevalidate() { return this.maxAge() + toNumberOrZero(this._rescc['stale-while-revalidate']) > this.age(); } static fromObject(obj) { return new this(undefined, undefined, { _fromObject: obj }); } _fromObject(obj) { if (this._responseTime) throw Error('Reinitialized'); if (!obj || obj.v !== 1) throw Error('Invalid serialization'); this._responseTime = obj.t; this._isShared = obj.sh; this._cacheHeuristic = obj.ch; this._immutableMinTtl = obj.imm !== undefined ? obj.imm : 24 * 3600 * 1000; this._status = obj.st; this._resHeaders = obj.resh; this._rescc = obj.rescc; this._method = obj.m; this._url = obj.u; this._host = obj.h; this._noAuthorization = obj.a; this._reqHeaders = obj.reqh; this._reqcc = obj.reqcc; } toObject() { return { v: 1, t: this._responseTime, sh: this._isShared, ch: this._cacheHeuristic, imm: this._immutableMinTtl, st: this._status, resh: this._resHeaders, rescc: this._rescc, m: this._method, u: this._url, h: this._host, a: this._noAuthorization, reqh: this._reqHeaders, reqcc: this._reqcc, }; } /** * Headers for sending to the origin server to revalidate stale response. * Allows server to return 304 to allow reuse of the previous response. * * Hop by hop headers are always stripped. * Revalidation headers may be added or removed, depending on request. */ revalidationHeaders(incomingReq) { this._assertRequestHasHeaders(incomingReq); const headers = this._copyWithoutHopByHopHeaders(incomingReq.headers); // This implementation does not understand range requests delete headers['if-range']; if (!this._requestMatches(incomingReq, true) || !this.storable()) { // revalidation allowed via HEAD // not for the same resource, or wasn't allowed to be cached anyway delete headers['if-none-match']; delete headers['if-modified-since']; return headers; } /* MUST send that entity-tag in any cache validation request (using If-Match or If-None-Match) if an entity-tag has been provided by the origin server. */ if (this._resHeaders.etag) { headers['if-none-match'] = headers['if-none-match'] ? `${headers['if-none-match']}, ${this._resHeaders.etag}` : this._resHeaders.etag; } // Clients MAY issue simple (non-subrange) GET requests with either weak validators or strong validators. Clients MUST NOT use weak validators in other forms of request. const forbidsWeakValidators = headers['accept-ranges'] || headers['if-match'] || headers['if-unmodified-since'] || (this._method && this._method != 'GET'); /* SHOULD send the Last-Modified value in non-subrange cache validation requests (using If-Modified-Since) if only a Last-Modified value has been provided by the origin server. Note: This implementation does not understand partial responses (206) */ if (forbidsWeakValidators) { delete headers['if-modified-since']; if (headers['if-none-match']) { const etags = headers['if-none-match'] .split(/,/) .filter(etag => { return !/^\s*W\//.test(etag); }); if (!etags.length) { delete headers['if-none-match']; } else { headers['if-none-match'] = etags.join(',').trim(); } } } else if ( this._resHeaders['last-modified'] && !headers['if-modified-since'] ) { headers['if-modified-since'] = this._resHeaders['last-modified']; } return headers; } /** * Creates new CachePolicy with information combined from the previews response, * and the new revalidation response. * * Returns {policy, modified} where modified is a boolean indicating * whether the response body has been modified, and old cached body can't be used. * * @return {Object} {policy: CachePolicy, modified: Boolean} */ revalidatedPolicy(request, response) { this._assertRequestHasHeaders(request); if(this._useStaleIfError() && isErrorResponse(response)) { // I consider the revalidation request unsuccessful return { modified: false, matches: false, policy: this, }; } if (!response || !response.headers) { throw Error('Response headers missing'); } // These aren't going to be supported exactly, since one CachePolicy object // doesn't know about all the other cached objects. let matches = false; if (response.status !== undefined && response.status != 304) { matches = false; } else if ( response.headers.etag && !/^\s*W\//.test(response.headers.etag) ) { // "All of the stored responses with the same strong validator are selected. // If none of the stored responses contain the same strong validator, // then the cache MUST NOT use the new response to update any stored responses." matches = this._resHeaders.etag && this._resHeaders.etag.replace(/^\s*W\//, '') === response.headers.etag; } else if (this._resHeaders.etag && response.headers.etag) { // "If the new response contains a weak validator and that validator corresponds // to one of the cache's stored responses, // then the most recent of those matching stored responses is selected for update." matches = this._resHeaders.etag.replace(/^\s*W\//, '') === response.headers.etag.replace(/^\s*W\//, ''); } else if (this._resHeaders['last-modified']) { matches = this._resHeaders['last-modified'] === response.headers['last-modified']; } else { // If the new response does not include any form of validator (such as in the case where // a client generates an If-Modified-Since request from a source other than the Last-Modified // response header field), and there is only one stored response, and that stored response also // lacks a validator, then that stored response is selected for update. if ( !this._resHeaders.etag && !this._resHeaders['last-modified'] && !response.headers.etag && !response.headers['last-modified'] ) { matches = true; } } if (!matches) { return { policy: new this.constructor(request, response), // Client receiving 304 without body, even if it's invalid/mismatched has no option // but to reuse a cached body. We don't have a good way to tell clients to do // error recovery in such case. modified: response.status != 304, matches: false, }; } // use other header fields provided in the 304 (Not Modified) response to replace all instances // of the corresponding header fields in the stored response. const headers = {}; for (const k in this._resHeaders) { headers[k] = k in response.headers && !excludedFromRevalidationUpdate[k] ? response.headers[k] : this._resHeaders[k]; } const newResponse = Object.assign({}, response, { status: this._status, method: this._method, headers, }); return { policy: new this.constructor(request, newResponse, { shared: this._isShared, cacheHeuristic: this._cacheHeuristic, immutableMinTimeToLive: this._immutableMinTtl, }), modified: false, matches: true, }; } }; /***/ }), /***/ 9898: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { // See https://github.com/facebook/jest/issues/2549 // eslint-disable-next-line node/prefer-global/url const {URL} = __webpack_require__(7310); const EventEmitter = __webpack_require__(2361); const tls = __webpack_require__(4404); const http2 = __webpack_require__(5158); const QuickLRU = __webpack_require__(9273); const delayAsyncDestroy = __webpack_require__(9237); const kCurrentStreamCount = Symbol('currentStreamCount'); const kRequest = Symbol('request'); const kOriginSet = Symbol('cachedOriginSet'); const kGracefullyClosing = Symbol('gracefullyClosing'); const kLength = Symbol('length'); const nameKeys = [ // Not an Agent option actually 'createConnection', // `http2.connect()` options 'maxDeflateDynamicTableSize', 'maxSettings', 'maxSessionMemory', 'maxHeaderListPairs', 'maxOutstandingPings', 'maxReservedRemoteStreams', 'maxSendHeaderBlockLength', 'paddingStrategy', 'peerMaxConcurrentStreams', 'settings', // `tls.connect()` source options 'family', 'localAddress', 'rejectUnauthorized', // `tls.connect()` secure context options 'pskCallback', 'minDHSize', // `tls.connect()` destination options // - `servername` is automatically validated, skip it // - `host` and `port` just describe the destination server, 'path', 'socket', // `tls.createSecureContext()` options 'ca', 'cert', 'sigalgs', 'ciphers', 'clientCertEngine', 'crl', 'dhparam', 'ecdhCurve', 'honorCipherOrder', 'key', 'privateKeyEngine', 'privateKeyIdentifier', 'maxVersion', 'minVersion', 'pfx', 'secureOptions', 'secureProtocol', 'sessionIdContext', 'ticketKeys' ]; const getSortedIndex = (array, value, compare) => { let low = 0; let high = array.length; while (low < high) { const mid = (low + high) >>> 1; if (compare(array[mid], value)) { low = mid + 1; } else { high = mid; } } return low; }; const compareSessions = (a, b) => a.remoteSettings.maxConcurrentStreams > b.remoteSettings.maxConcurrentStreams; // See https://tools.ietf.org/html/rfc8336 const closeCoveredSessions = (where, session) => { // Clients SHOULD NOT emit new requests on any connection whose Origin // Set is a proper subset of another connection's Origin Set, and they // SHOULD close it once all outstanding requests are satisfied. for (let index = 0; index < where.length; index++) { const coveredSession = where[index]; if ( // Unfortunately `.every()` returns true for an empty array coveredSession[kOriginSet].length > 0 // The set is a proper subset when its length is less than the other set. && coveredSession[kOriginSet].length < session[kOriginSet].length // And the other set includes all elements of the subset. && coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) // Makes sure that the session can handle all requests from the covered session. && (coveredSession[kCurrentStreamCount] + session[kCurrentStreamCount]) <= session.remoteSettings.maxConcurrentStreams ) { // This allows pending requests to finish and prevents making new requests. gracefullyClose(coveredSession); } } }; // This is basically inverted `closeCoveredSessions(...)`. const closeSessionIfCovered = (where, coveredSession) => { for (let index = 0; index < where.length; index++) { const session = where[index]; if ( coveredSession[kOriginSet].length > 0 && coveredSession[kOriginSet].length < session[kOriginSet].length && coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) && (coveredSession[kCurrentStreamCount] + session[kCurrentStreamCount]) <= session.remoteSettings.maxConcurrentStreams ) { gracefullyClose(coveredSession); return true; } } return false; }; const gracefullyClose = session => { session[kGracefullyClosing] = true; if (session[kCurrentStreamCount] === 0) { session.close(); } }; class Agent extends EventEmitter { constructor({timeout = 0, maxSessions = Number.POSITIVE_INFINITY, maxEmptySessions = 10, maxCachedTlsSessions = 100} = {}) { super(); // SESSIONS[NORMALIZED_OPTIONS] = []; this.sessions = {}; // The queue for creating new sessions. It looks like this: // QUEUE[NORMALIZED_OPTIONS][NORMALIZED_ORIGIN] = ENTRY_FUNCTION // // It's faster when there are many origins. If there's only one, then QUEUE[`${options}:${origin}`] is faster. // I guess object creation / deletion is causing the slowdown. // // The entry function has `listeners`, `completed` and `destroyed` properties. // `listeners` is an array of objects containing `resolve` and `reject` functions. // `completed` is a boolean. It's set to true after ENTRY_FUNCTION is executed. // `destroyed` is a boolean. If it's set to true, the session will be destroyed if hasn't connected yet. this.queue = {}; // Each session will use this timeout value. this.timeout = timeout; // Max sessions in total this.maxSessions = maxSessions; // Max empty sessions in total this.maxEmptySessions = maxEmptySessions; this._emptySessionCount = 0; this._sessionCount = 0; // We don't support push streams by default. this.settings = { enablePush: false, initialWindowSize: 1024 * 1024 * 32 // 32MB, see https://github.com/nodejs/node/issues/38426 }; // Reusing TLS sessions increases performance. this.tlsSessionCache = new QuickLRU({maxSize: maxCachedTlsSessions}); } get protocol() { return 'https:'; } normalizeOptions(options) { let normalized = ''; for (let index = 0; index < nameKeys.length; index++) { const key = nameKeys[index]; normalized += ':'; if (options && options[key] !== undefined) { normalized += options[key]; } } return normalized; } _processQueue() { if (this._sessionCount >= this.maxSessions) { this.closeEmptySessions(this.maxSessions - this._sessionCount + 1); return; } // eslint-disable-next-line guard-for-in for (const normalizedOptions in this.queue) { // eslint-disable-next-line guard-for-in for (const normalizedOrigin in this.queue[normalizedOptions]) { const item = this.queue[normalizedOptions][normalizedOrigin]; // The entry function can be run only once. if (!item.completed) { item.completed = true; item(); } } } } _isBetterSession(thisStreamCount, thatStreamCount) { return thisStreamCount > thatStreamCount; } _accept(session, listeners, normalizedOrigin, options) { let index = 0; while (index < listeners.length && session[kCurrentStreamCount] < session.remoteSettings.maxConcurrentStreams) { // We assume `resolve(...)` calls `request(...)` *directly*, // otherwise the session will get overloaded. listeners[index].resolve(session); index++; } listeners.splice(0, index); if (listeners.length > 0) { this.getSession(normalizedOrigin, options, listeners); listeners.length = 0; } } getSession(origin, options, listeners) { return new Promise((resolve, reject) => { if (Array.isArray(listeners) && listeners.length > 0) { listeners = [...listeners]; // Resolve the current promise ASAP, we're just moving the listeners. // They will be executed at a different time. resolve(); } else { listeners = [{resolve, reject}]; } try { // Parse origin if (typeof origin === 'string') { origin = new URL(origin); } else if (!(origin instanceof URL)) { throw new TypeError('The `origin` argument needs to be a string or an URL object'); } if (options) { // Validate servername const {servername} = options; const {hostname} = origin; if (servername && hostname !== servername) { throw new Error(`Origin ${hostname} differs from servername ${servername}`); } } } catch (error) { for (let index = 0; index < listeners.length; index++) { listeners[index].reject(error); } return; } const normalizedOptions = this.normalizeOptions(options); const normalizedOrigin = origin.origin; if (normalizedOptions in this.sessions) { const sessions = this.sessions[normalizedOptions]; let maxConcurrentStreams = -1; let currentStreamsCount = -1; let optimalSession; // We could just do this.sessions[normalizedOptions].find(...) but that isn't optimal. // Additionally, we are looking for session which has biggest current pending streams count. // // |------------| |------------| |------------| |------------| // | Session: A | | Session: B | | Session: C | | Session: D | // | Pending: 5 |-| Pending: 8 |-| Pending: 9 |-| Pending: 4 | // | Max: 10 | | Max: 10 | | Max: 9 | | Max: 5 | // |------------| |------------| |------------| |------------| // ^ // | // pick this one -- // for (let index = 0; index < sessions.length; index++) { const session = sessions[index]; const sessionMaxConcurrentStreams = session.remoteSettings.maxConcurrentStreams; if (sessionMaxConcurrentStreams < maxConcurrentStreams) { break; } if (!session[kOriginSet].includes(normalizedOrigin)) { continue; } const sessionCurrentStreamsCount = session[kCurrentStreamCount]; if ( sessionCurrentStreamsCount >= sessionMaxConcurrentStreams || session[kGracefullyClosing] // Unfortunately the `close` event isn't called immediately, // so `session.destroyed` is `true`, but `session.closed` is `false`. || session.destroyed ) { continue; } // We only need set this once. if (!optimalSession) { maxConcurrentStreams = sessionMaxConcurrentStreams; } // Either get the session which has biggest current stream count or the lowest. if (this._isBetterSession(sessionCurrentStreamsCount, currentStreamsCount)) { optimalSession = session; currentStreamsCount = sessionCurrentStreamsCount; } } if (optimalSession) { this._accept(optimalSession, listeners, normalizedOrigin, options); return; } } if (normalizedOptions in this.queue) { if (normalizedOrigin in this.queue[normalizedOptions]) { // There's already an item in the queue, just attach ourselves to it. this.queue[normalizedOptions][normalizedOrigin].listeners.push(...listeners); return; } } else { this.queue[normalizedOptions] = { [kLength]: 0 }; } // The entry must be removed from the queue IMMEDIATELY when: // 1. the session connects successfully, // 2. an error occurs. const removeFromQueue = () => { // Our entry can be replaced. We cannot remove the new one. if (normalizedOptions in this.queue && this.queue[normalizedOptions][normalizedOrigin] === entry) { delete this.queue[normalizedOptions][normalizedOrigin]; if (--this.queue[normalizedOptions][kLength] === 0) { delete this.queue[normalizedOptions]; } } }; // The main logic is here const entry = async () => { this._sessionCount++; const name = `${normalizedOrigin}:${normalizedOptions}`; let receivedSettings = false; let socket; try { const computedOptions = {...options}; if (computedOptions.settings === undefined) { computedOptions.settings = this.settings; } if (computedOptions.session === undefined) { computedOptions.session = this.tlsSessionCache.get(name); } const createConnection = computedOptions.createConnection || this.createConnection; // A hacky workaround to enable async `createConnection` socket = await createConnection.call(this, origin, computedOptions); computedOptions.createConnection = () => socket; const session = http2.connect(origin, computedOptions); session[kCurrentStreamCount] = 0; session[kGracefullyClosing] = false; // Node.js return https://false:443 instead of https://1.1.1.1:443 const getOriginSet = () => { const {socket} = session; let originSet; if (socket.servername === false) { socket.servername = socket.remoteAddress; originSet = session.originSet; socket.servername = false; } else { originSet = session.originSet; } return originSet; }; const isFree = () => session[kCurrentStreamCount] < session.remoteSettings.maxConcurrentStreams; session.socket.once('session', tlsSession => { this.tlsSessionCache.set(name, tlsSession); }); session.once('error', error => { // Listeners are empty when the session successfully connected. for (let index = 0; index < listeners.length; index++) { listeners[index].reject(error); } // The connection got broken, purge the cache. this.tlsSessionCache.delete(name); }); session.setTimeout(this.timeout, () => { // Terminates all streams owned by this session. session.destroy(); }); session.once('close', () => { this._sessionCount--; if (receivedSettings) { // Assumes session `close` is emitted after request `close` this._emptySessionCount--; // This cannot be moved to the stream logic, // because there may be a session that hadn't made a single request. const where = this.sessions[normalizedOptions]; if (where.length === 1) { delete this.sessions[normalizedOptions]; } else { where.splice(where.indexOf(session), 1); } } else { // Broken connection removeFromQueue(); const error = new Error('Session closed without receiving a SETTINGS frame'); error.code = 'HTTP2WRAPPER_NOSETTINGS'; for (let index = 0; index < listeners.length; index++) { listeners[index].reject(error); } } // There may be another session awaiting. this._processQueue(); }); // Iterates over the queue and processes listeners. const processListeners = () => { const queue = this.queue[normalizedOptions]; if (!queue) { return; } const originSet = session[kOriginSet]; for (let index = 0; index < originSet.length; index++) { const origin = originSet[index]; if (origin in queue) { const {listeners, completed} = queue[origin]; let index = 0; // Prevents session overloading. while (index < listeners.length && isFree()) { // We assume `resolve(...)` calls `request(...)` *directly*, // otherwise the session will get overloaded. listeners[index].resolve(session); index++; } queue[origin].listeners.splice(0, index); if (queue[origin].listeners.length === 0 && !completed) { delete queue[origin]; if (--queue[kLength] === 0) { delete this.queue[normalizedOptions]; break; } } // We're no longer free, no point in continuing. if (!isFree()) { break; } } } }; // The Origin Set cannot shrink. No need to check if it suddenly became covered by another one. session.on('origin', () => { session[kOriginSet] = getOriginSet() || []; session[kGracefullyClosing] = false; closeSessionIfCovered(this.sessions[normalizedOptions], session); if (session[kGracefullyClosing] || !isFree()) { return; } processListeners(); if (!isFree()) { return; } // Close covered sessions (if possible). closeCoveredSessions(this.sessions[normalizedOptions], session); }); session.once('remoteSettings', () => { // The Agent could have been destroyed already. if (entry.destroyed) { const error = new Error('Agent has been destroyed'); for (let index = 0; index < listeners.length; index++) { listeners[index].reject(error); } session.destroy(); return; } // See https://github.com/nodejs/node/issues/38426 if (session.setLocalWindowSize) { session.setLocalWindowSize(1024 * 1024 * 4); // 4 MB } session[kOriginSet] = getOriginSet() || []; if (session.socket.encrypted) { const mainOrigin = session[kOriginSet][0]; if (mainOrigin !== normalizedOrigin) { const error = new Error(`Requested origin ${normalizedOrigin} does not match server ${mainOrigin}`); for (let index = 0; index < listeners.length; index++) { listeners[index].reject(error); } session.destroy(); return; } } removeFromQueue(); { const where = this.sessions; if (normalizedOptions in where) { const sessions = where[normalizedOptions]; sessions.splice(getSortedIndex(sessions, session, compareSessions), 0, session); } else { where[normalizedOptions] = [session]; } } receivedSettings = true; this._emptySessionCount++; this.emit('session', session); this._accept(session, listeners, normalizedOrigin, options); if (session[kCurrentStreamCount] === 0 && this._emptySessionCount > this.maxEmptySessions) { this.closeEmptySessions(this._emptySessionCount - this.maxEmptySessions); } // `session.remoteSettings.maxConcurrentStreams` might get increased session.on('remoteSettings', () => { if (!isFree()) { return; } processListeners(); if (!isFree()) { return; } // In case the Origin Set changes closeCoveredSessions(this.sessions[normalizedOptions], session); }); }); // Shim `session.request()` in order to catch all streams session[kRequest] = session.request; session.request = (headers, streamOptions) => { if (session[kGracefullyClosing]) { throw new Error('The session is gracefully closing. No new streams are allowed.'); } const stream = session[kRequest](headers, streamOptions); // The process won't exit until the session is closed or all requests are gone. session.ref(); if (session[kCurrentStreamCount]++ === 0) { this._emptySessionCount--; } stream.once('close', () => { if (--session[kCurrentStreamCount] === 0) { this._emptySessionCount++; session.unref(); if (this._emptySessionCount > this.maxEmptySessions || session[kGracefullyClosing]) { session.close(); return; } } if (session.destroyed || session.closed) { return; } if (isFree() && !closeSessionIfCovered(this.sessions[normalizedOptions], session)) { closeCoveredSessions(this.sessions[normalizedOptions], session); processListeners(); if (session[kCurrentStreamCount] === 0) { this._processQueue(); } } }); return stream; }; } catch (error) { removeFromQueue(); this._sessionCount--; for (let index = 0; index < listeners.length; index++) { listeners[index].reject(error); } } }; entry.listeners = listeners; entry.completed = false; entry.destroyed = false; this.queue[normalizedOptions][normalizedOrigin] = entry; this.queue[normalizedOptions][kLength]++; this._processQueue(); }); } request(origin, options, headers, streamOptions) { return new Promise((resolve, reject) => { this.getSession(origin, options, [{ reject, resolve: session => { try { const stream = session.request(headers, streamOptions); // Do not throw before `request(...)` has been awaited delayAsyncDestroy(stream); resolve(stream); } catch (error) { reject(error); } } }]); }); } async createConnection(origin, options) { return Agent.connect(origin, options); } static connect(origin, options) { options.ALPNProtocols = ['h2']; const port = origin.port || 443; const host = origin.hostname; if (typeof options.servername === 'undefined') { options.servername = host; } const socket = tls.connect(port, host, options); if (options.socket) { socket._peername = { family: undefined, address: undefined, port }; } return socket; } closeEmptySessions(maxCount = Number.POSITIVE_INFINITY) { let closedCount = 0; const {sessions} = this; // eslint-disable-next-line guard-for-in for (const key in sessions) { const thisSessions = sessions[key]; for (let index = 0; index < thisSessions.length; index++) { const session = thisSessions[index]; if (session[kCurrentStreamCount] === 0) { closedCount++; session.close(); if (closedCount >= maxCount) { return closedCount; } } } } return closedCount; } destroy(reason) { const {sessions, queue} = this; // eslint-disable-next-line guard-for-in for (const key in sessions) { const thisSessions = sessions[key]; for (let index = 0; index < thisSessions.length; index++) { thisSessions[index].destroy(reason); } } // eslint-disable-next-line guard-for-in for (const normalizedOptions in queue) { const entries = queue[normalizedOptions]; // eslint-disable-next-line guard-for-in for (const normalizedOrigin in entries) { entries[normalizedOrigin].destroyed = true; } } // New requests should NOT attach to destroyed sessions this.queue = {}; this.tlsSessionCache.clear(); } get emptySessionCount() { return this._emptySessionCount; } get pendingSessionCount() { return this._sessionCount - this._emptySessionCount; } get sessionCount() { return this._sessionCount; } } Agent.kCurrentStreamCount = kCurrentStreamCount; Agent.kGracefullyClosing = kGracefullyClosing; module.exports = { Agent, globalAgent: new Agent() }; /***/ }), /***/ 7167: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { // See https://github.com/facebook/jest/issues/2549 // eslint-disable-next-line node/prefer-global/url const {URL, urlToHttpOptions} = __webpack_require__(7310); const http = __webpack_require__(3685); const https = __webpack_require__(5687); const resolveALPN = __webpack_require__(6624); const QuickLRU = __webpack_require__(9273); const {Agent, globalAgent} = __webpack_require__(9898); const Http2ClientRequest = __webpack_require__(9632); const calculateServerName = __webpack_require__(1982); const delayAsyncDestroy = __webpack_require__(9237); const cache = new QuickLRU({maxSize: 100}); const queue = new Map(); const installSocket = (agent, socket, options) => { socket._httpMessage = {shouldKeepAlive: true}; const onFree = () => { agent.emit('free', socket, options); }; socket.on('free', onFree); const onClose = () => { agent.removeSocket(socket, options); }; socket.on('close', onClose); const onTimeout = () => { const {freeSockets} = agent; for (const sockets of Object.values(freeSockets)) { if (sockets.includes(socket)) { socket.destroy(); return; } } }; socket.on('timeout', onTimeout); const onRemove = () => { agent.removeSocket(socket, options); socket.off('close', onClose); socket.off('free', onFree); socket.off('timeout', onTimeout); socket.off('agentRemove', onRemove); }; socket.on('agentRemove', onRemove); agent.emit('free', socket, options); }; const createResolveProtocol = (cache, queue = new Map(), connect = undefined) => { return async options => { const name = `${options.host}:${options.port}:${options.ALPNProtocols.sort()}`; if (!cache.has(name)) { if (queue.has(name)) { const result = await queue.get(name); return {alpnProtocol: result.alpnProtocol}; } const {path} = options; options.path = options.socketPath; const resultPromise = resolveALPN(options, connect); queue.set(name, resultPromise); try { const result = await resultPromise; cache.set(name, result.alpnProtocol); queue.delete(name); options.path = path; return result; } catch (error) { queue.delete(name); options.path = path; throw error; } } return {alpnProtocol: cache.get(name)}; }; }; const defaultResolveProtocol = createResolveProtocol(cache, queue); module.exports = async (input, options, callback) => { if (typeof input === 'string') { input = urlToHttpOptions(new URL(input)); } else if (input instanceof URL) { input = urlToHttpOptions(input); } else { input = {...input}; } if (typeof options === 'function' || options === undefined) { // (options, callback) callback = options; options = input; } else { // (input, options, callback) options = Object.assign(input, options); } options.ALPNProtocols = options.ALPNProtocols || ['h2', 'http/1.1']; if (!Array.isArray(options.ALPNProtocols) || options.ALPNProtocols.length === 0) { throw new Error('The `ALPNProtocols` option must be an Array with at least one entry'); } options.protocol = options.protocol || 'https:'; const isHttps = options.protocol === 'https:'; options.host = options.hostname || options.host || 'localhost'; options.session = options.tlsSession; options.servername = options.servername || calculateServerName((options.headers && options.headers.host) || options.host); options.port = options.port || (isHttps ? 443 : 80); options._defaultAgent = isHttps ? https.globalAgent : http.globalAgent; const resolveProtocol = options.resolveProtocol || defaultResolveProtocol; // Note: We don't support `h2session` here let {agent} = options; if (agent !== undefined && agent !== false && agent.constructor.name !== 'Object') { throw new Error('The `options.agent` can be only an object `http`, `https` or `http2` properties'); } if (isHttps) { options.resolveSocket = true; let {socket, alpnProtocol, timeout} = await resolveProtocol(options); if (timeout) { if (socket) { socket.destroy(); } const error = new Error(`Timed out resolving ALPN: ${options.timeout} ms`); error.code = 'ETIMEDOUT'; error.ms = options.timeout; throw error; } // We can't accept custom `createConnection` because the API is different for HTTP/2 if (socket && options.createConnection) { socket.destroy(); socket = undefined; } delete options.resolveSocket; const isHttp2 = alpnProtocol === 'h2'; if (agent) { agent = isHttp2 ? agent.http2 : agent.https; options.agent = agent; } if (agent === undefined) { agent = isHttp2 ? globalAgent : https.globalAgent; } if (socket) { if (agent === false) { socket.destroy(); } else { const defaultCreateConnection = (isHttp2 ? Agent : https.Agent).prototype.createConnection; if (agent.createConnection === defaultCreateConnection) { if (isHttp2) { options._reuseSocket = socket; } else { installSocket(agent, socket, options); } } else { socket.destroy(); } } } if (isHttp2) { return delayAsyncDestroy(new Http2ClientRequest(options, callback)); } } else if (agent) { options.agent = agent.http; } return delayAsyncDestroy(http.request(options, callback)); }; module.exports.protocolCache = cache; module.exports.resolveProtocol = defaultResolveProtocol; module.exports.createResolveProtocol = createResolveProtocol; /***/ }), /***/ 9632: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { // See https://github.com/facebook/jest/issues/2549 // eslint-disable-next-line node/prefer-global/url const {URL, urlToHttpOptions} = __webpack_require__(7310); const http2 = __webpack_require__(5158); const {Writable} = __webpack_require__(2781); const {Agent, globalAgent} = __webpack_require__(9898); const IncomingMessage = __webpack_require__(2575); const proxyEvents = __webpack_require__(1818); const { ERR_INVALID_ARG_TYPE, ERR_INVALID_PROTOCOL, ERR_HTTP_HEADERS_SENT } = __webpack_require__(7087); const validateHeaderName = __webpack_require__(4592); const validateHeaderValue = __webpack_require__(3549); const proxySocketHandler = __webpack_require__(9404); const { HTTP2_HEADER_STATUS, HTTP2_HEADER_METHOD, HTTP2_HEADER_PATH, HTTP2_HEADER_AUTHORITY, HTTP2_METHOD_CONNECT } = http2.constants; const kHeaders = Symbol('headers'); const kOrigin = Symbol('origin'); const kSession = Symbol('session'); const kOptions = Symbol('options'); const kFlushedHeaders = Symbol('flushedHeaders'); const kJobs = Symbol('jobs'); const kPendingAgentPromise = Symbol('pendingAgentPromise'); class ClientRequest extends Writable { constructor(input, options, callback) { super({ autoDestroy: false, emitClose: false }); if (typeof input === 'string') { input = urlToHttpOptions(new URL(input)); } else if (input instanceof URL) { input = urlToHttpOptions(input); } else { input = {...input}; } if (typeof options === 'function' || options === undefined) { // (options, callback) callback = options; options = input; } else { // (input, options, callback) options = Object.assign(input, options); } if (options.h2session) { this[kSession] = options.h2session; if (this[kSession].destroyed) { throw new Error('The session has been closed already'); } this.protocol = this[kSession].socket.encrypted ? 'https:' : 'http:'; } else if (options.agent === false) { this.agent = new Agent({maxEmptySessions: 0}); } else if (typeof options.agent === 'undefined' || options.agent === null) { this.agent = globalAgent; } else if (typeof options.agent.request === 'function') { this.agent = options.agent; } else { throw new ERR_INVALID_ARG_TYPE('options.agent', ['http2wrapper.Agent-like Object', 'undefined', 'false'], options.agent); } if (this.agent) { this.protocol = this.agent.protocol; } if (options.protocol && options.protocol !== this.protocol) { throw new ERR_INVALID_PROTOCOL(options.protocol, this.protocol); } if (!options.port) { options.port = options.defaultPort || (this.agent && this.agent.defaultPort) || 443; } options.host = options.hostname || options.host || 'localhost'; // Unused delete options.hostname; const {timeout} = options; options.timeout = undefined; this[kHeaders] = Object.create(null); this[kJobs] = []; this[kPendingAgentPromise] = undefined; this.socket = null; this.connection = null; this.method = options.method || 'GET'; if (!(this.method === 'CONNECT' && (options.path === '/' || options.path === undefined))) { this.path = options.path; } this.res = null; this.aborted = false; this.reusedSocket = false; const {headers} = options; if (headers) { // eslint-disable-next-line guard-for-in for (const header in headers) { this.setHeader(header, headers[header]); } } if (options.auth && !('authorization' in this[kHeaders])) { this[kHeaders].authorization = 'Basic ' + Buffer.from(options.auth).toString('base64'); } options.session = options.tlsSession; options.path = options.socketPath; this[kOptions] = options; // Clients that generate HTTP/2 requests directly SHOULD use the :authority pseudo-header field instead of the Host header field. this[kOrigin] = new URL(`${this.protocol}//${options.servername || options.host}:${options.port}`); // A socket is being reused const reuseSocket = options._reuseSocket; if (reuseSocket) { options.createConnection = (...args) => { if (reuseSocket.destroyed) { return this.agent.createConnection(...args); } return reuseSocket; }; // eslint-disable-next-line promise/prefer-await-to-then this.agent.getSession(this[kOrigin], this[kOptions]).catch(() => {}); } if (timeout) { this.setTimeout(timeout); } if (callback) { this.once('response', callback); } this[kFlushedHeaders] = false; } get method() { return this[kHeaders][HTTP2_HEADER_METHOD]; } set method(value) { if (value) { this[kHeaders][HTTP2_HEADER_METHOD] = value.toUpperCase(); } } get path() { const header = this.method === 'CONNECT' ? HTTP2_HEADER_AUTHORITY : HTTP2_HEADER_PATH; return this[kHeaders][header]; } set path(value) { if (value) { const header = this.method === 'CONNECT' ? HTTP2_HEADER_AUTHORITY : HTTP2_HEADER_PATH; this[kHeaders][header] = value; } } get host() { return this[kOrigin].hostname; } set host(_value) { // Do nothing as this is read only. } get _mustNotHaveABody() { return this.method === 'GET' || this.method === 'HEAD' || this.method === 'DELETE'; } _write(chunk, encoding, callback) { // https://github.com/nodejs/node/blob/654df09ae0c5e17d1b52a900a545f0664d8c7627/lib/internal/http2/util.js#L148-L156 if (this._mustNotHaveABody) { callback(new Error('The GET, HEAD and DELETE methods must NOT have a body')); /* istanbul ignore next: Node.js 12 throws directly */ return; } this.flushHeaders(); const callWrite = () => this._request.write(chunk, encoding, callback); if (this._request) { callWrite(); } else { this[kJobs].push(callWrite); } } _final(callback) { this.flushHeaders(); const callEnd = () => { // For GET, HEAD and DELETE and CONNECT if (this._mustNotHaveABody || this.method === 'CONNECT') { callback(); return; } this._request.end(callback); }; if (this._request) { callEnd(); } else { this[kJobs].push(callEnd); } } abort() { if (this.res && this.res.complete) { return; } if (!this.aborted) { process.nextTick(() => this.emit('abort')); } this.aborted = true; this.destroy(); } async _destroy(error, callback) { if (this.res) { this.res._dump(); } if (this._request) { this._request.destroy(); } else { process.nextTick(() => { this.emit('close'); }); } try { await this[kPendingAgentPromise]; } catch (internalError) { if (this.aborted) { error = internalError; } } callback(error); } async flushHeaders() { if (this[kFlushedHeaders] || this.destroyed) { return; } this[kFlushedHeaders] = true; const isConnectMethod = this.method === HTTP2_METHOD_CONNECT; // The real magic is here const onStream = stream => { this._request = stream; if (this.destroyed) { stream.destroy(); return; } // Forwards `timeout`, `continue`, `close` and `error` events to this instance. if (!isConnectMethod) { // TODO: Should we proxy `close` here? proxyEvents(stream, this, ['timeout', 'continue']); } stream.once('error', error => { this.destroy(error); }); stream.once('aborted', () => { const {res} = this; if (res) { res.aborted = true; res.emit('aborted'); res.destroy(); } else { this.destroy(new Error('The server aborted the HTTP/2 stream')); } }); const onResponse = (headers, flags, rawHeaders) => { // If we were to emit raw request stream, it would be as fast as the native approach. // Note that wrapping the raw stream in a Proxy instance won't improve the performance (already tested it). const response = new IncomingMessage(this.socket, stream.readableHighWaterMark); this.res = response; // Undocumented, but it is used by `cacheable-request` response.url = `${this[kOrigin].origin}${this.path}`; response.req = this; response.statusCode = headers[HTTP2_HEADER_STATUS]; response.headers = headers; response.rawHeaders = rawHeaders; response.once('end', () => { response.complete = true; // Has no effect, just be consistent with the Node.js behavior response.socket = null; response.connection = null; }); if (isConnectMethod) { response.upgrade = true; // The HTTP1 API says the socket is detached here, // but we can't do that so we pass the original HTTP2 request. if (this.emit('connect', response, stream, Buffer.alloc(0))) { this.emit('close'); } else { // No listeners attached, destroy the original request. stream.destroy(); } } else { // Forwards data stream.on('data', chunk => { if (!response._dumped && !response.push(chunk)) { stream.pause(); } }); stream.once('end', () => { if (!this.aborted) { response.push(null); } }); if (!this.emit('response', response)) { // No listeners attached, dump the response. response._dump(); } } }; // This event tells we are ready to listen for the data. stream.once('response', onResponse); // Emits `information` event stream.once('headers', headers => this.emit('information', {statusCode: headers[HTTP2_HEADER_STATUS]})); stream.once('trailers', (trailers, flags, rawTrailers) => { const {res} = this; // https://github.com/nodejs/node/issues/41251 if (res === null) { onResponse(trailers, flags, rawTrailers); return; } // Assigns trailers to the response object. res.trailers = trailers; res.rawTrailers = rawTrailers; }); stream.once('close', () => { const {aborted, res} = this; if (res) { if (aborted) { res.aborted = true; res.emit('aborted'); res.destroy(); } const finish = () => { res.emit('close'); this.destroy(); this.emit('close'); }; if (res.readable) { res.once('end', finish); } else { finish(); } return; } if (!this.destroyed) { this.destroy(new Error('The HTTP/2 stream has been early terminated')); this.emit('close'); return; } this.destroy(); this.emit('close'); }); this.socket = new Proxy(stream, proxySocketHandler); for (const job of this[kJobs]) { job(); } this.emit('socket', this.socket); }; if (!(HTTP2_HEADER_AUTHORITY in this[kHeaders]) && !isConnectMethod) { this[kHeaders][HTTP2_HEADER_AUTHORITY] = this[kOrigin].host; } // Makes a HTTP2 request if (this[kSession]) { try { onStream(this[kSession].request(this[kHeaders])); } catch (error) { this.destroy(error); } } else { this.reusedSocket = true; try { const promise = this.agent.request(this[kOrigin], this[kOptions], this[kHeaders]); this[kPendingAgentPromise] = promise; onStream(await promise); this[kPendingAgentPromise] = false; } catch (error) { this[kPendingAgentPromise] = false; this.destroy(error); } } } get connection() { return this.socket; } set connection(value) { this.socket = value; } getHeaderNames() { return Object.keys(this[kHeaders]); } hasHeader(name) { if (typeof name !== 'string') { throw new ERR_INVALID_ARG_TYPE('name', 'string', name); } return Boolean(this[kHeaders][name.toLowerCase()]); } getHeader(name) { if (typeof name !== 'string') { throw new ERR_INVALID_ARG_TYPE('name', 'string', name); } return this[kHeaders][name.toLowerCase()]; } get headersSent() { return this[kFlushedHeaders]; } removeHeader(name) { if (typeof name !== 'string') { throw new ERR_INVALID_ARG_TYPE('name', 'string', name); } if (this.headersSent) { throw new ERR_HTTP_HEADERS_SENT('remove'); } delete this[kHeaders][name.toLowerCase()]; } setHeader(name, value) { if (this.headersSent) { throw new ERR_HTTP_HEADERS_SENT('set'); } validateHeaderName(name); validateHeaderValue(name, value); const lowercased = name.toLowerCase(); if (lowercased === 'connection') { if (value.toLowerCase() === 'keep-alive') { return; } throw new Error(`Invalid 'connection' header: ${value}`); } if (lowercased === 'host' && this.method === 'CONNECT') { this[kHeaders][HTTP2_HEADER_AUTHORITY] = value; } else { this[kHeaders][lowercased] = value; } } setNoDelay() { // HTTP2 sockets cannot be malformed, do nothing. } setSocketKeepAlive() { // HTTP2 sockets cannot be malformed, do nothing. } setTimeout(ms, callback) { const applyTimeout = () => this._request.setTimeout(ms, callback); if (this._request) { applyTimeout(); } else { this[kJobs].push(applyTimeout); } return this; } get maxHeadersCount() { if (!this.destroyed && this._request) { return this._request.session.localSettings.maxHeaderListSize; } return undefined; } set maxHeadersCount(_value) { // Updating HTTP2 settings would affect all requests, do nothing. } } module.exports = ClientRequest; /***/ }), /***/ 2575: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {Readable} = __webpack_require__(2781); class IncomingMessage extends Readable { constructor(socket, highWaterMark) { super({ emitClose: false, autoDestroy: true, highWaterMark }); this.statusCode = null; this.statusMessage = ''; this.httpVersion = '2.0'; this.httpVersionMajor = 2; this.httpVersionMinor = 0; this.headers = {}; this.trailers = {}; this.req = null; this.aborted = false; this.complete = false; this.upgrade = null; this.rawHeaders = []; this.rawTrailers = []; this.socket = socket; this._dumped = false; } get connection() { return this.socket; } set connection(value) { this.socket = value; } _destroy(error, callback) { if (!this.readableEnded) { this.aborted = true; } // See https://github.com/nodejs/node/issues/35303 callback(); this.req._request.destroy(error); } setTimeout(ms, callback) { this.req.setTimeout(ms, callback); return this; } _dump() { if (!this._dumped) { this._dumped = true; this.removeAllListeners('data'); this.resume(); } } _read() { if (this.req) { this.req._request.resume(); } } } module.exports = IncomingMessage; /***/ }), /***/ 4645: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const http2 = __webpack_require__(5158); const { Agent, globalAgent } = __webpack_require__(9898); const ClientRequest = __webpack_require__(9632); const IncomingMessage = __webpack_require__(2575); const auto = __webpack_require__(7167); const { HttpOverHttp2, HttpsOverHttp2 } = __webpack_require__(8795); const Http2OverHttp2 = __webpack_require__(8553); const { Http2OverHttp, Http2OverHttps } = __webpack_require__(9794); const validateHeaderName = __webpack_require__(4592); const validateHeaderValue = __webpack_require__(3549); const request = (url, options, callback) => new ClientRequest(url, options, callback); const get = (url, options, callback) => { // eslint-disable-next-line unicorn/prevent-abbreviations const req = new ClientRequest(url, options, callback); req.end(); return req; }; module.exports = { ...http2, ClientRequest, IncomingMessage, Agent, globalAgent, request, get, auto, proxies: { HttpOverHttp2, HttpsOverHttp2, Http2OverHttp2, Http2OverHttp, Http2OverHttps }, validateHeaderName, validateHeaderValue }; /***/ }), /***/ 7885: /***/ ((module) => { module.exports = self => { const {username, password} = self.proxyOptions.url; if (username || password) { const data = `${username}:${password}`; const authorization = `Basic ${Buffer.from(data).toString('base64')}`; return { 'proxy-authorization': authorization, authorization }; } return {}; }; /***/ }), /***/ 8795: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const tls = __webpack_require__(4404); const http = __webpack_require__(3685); const https = __webpack_require__(5687); const JSStreamSocket = __webpack_require__(1564); const {globalAgent} = __webpack_require__(9898); const UnexpectedStatusCodeError = __webpack_require__(6203); const initialize = __webpack_require__(1089); const getAuthorizationHeaders = __webpack_require__(7885); const createConnection = (self, options, callback) => { (async () => { try { const {proxyOptions} = self; const {url, headers, raw} = proxyOptions; const stream = await globalAgent.request(url, proxyOptions, { ...getAuthorizationHeaders(self), ...headers, ':method': 'CONNECT', ':authority': `${options.host}:${options.port}` }); stream.once('error', callback); stream.once('response', headers => { const statusCode = headers[':status']; if (statusCode !== 200) { callback(new UnexpectedStatusCodeError(statusCode)); return; } const encrypted = self instanceof https.Agent; if (raw && encrypted) { options.socket = stream; const secureStream = tls.connect(options); secureStream.once('close', () => { stream.destroy(); }); callback(null, secureStream); return; } const socket = new JSStreamSocket(stream); socket.encrypted = false; socket._handle.getpeername = out => { out.family = undefined; out.address = undefined; out.port = undefined; }; callback(null, socket); }); } catch (error) { callback(error); } })(); }; class HttpOverHttp2 extends http.Agent { constructor(options) { super(options); initialize(this, options.proxyOptions); } createConnection(options, callback) { createConnection(this, options, callback); } } class HttpsOverHttp2 extends https.Agent { constructor(options) { super(options); initialize(this, options.proxyOptions); } createConnection(options, callback) { createConnection(this, options, callback); } } module.exports = { HttpOverHttp2, HttpsOverHttp2 }; /***/ }), /***/ 9794: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const http = __webpack_require__(3685); const https = __webpack_require__(5687); const Http2OverHttpX = __webpack_require__(1857); const getAuthorizationHeaders = __webpack_require__(7885); const getStream = request => new Promise((resolve, reject) => { const onConnect = (response, socket, head) => { socket.unshift(head); request.off('error', reject); resolve([socket, response.statusCode]); }; request.once('error', reject); request.once('connect', onConnect); }); class Http2OverHttp extends Http2OverHttpX { async _getProxyStream(authority) { const {proxyOptions} = this; const {url, headers} = this.proxyOptions; const network = url.protocol === 'https:' ? https : http; // `new URL('https://localhost/httpbin.org:443')` results in // a `/httpbin.org:443` path, which has an invalid leading slash. const request = network.request({ ...proxyOptions, hostname: url.hostname, port: url.port, path: authority, headers: { ...getAuthorizationHeaders(this), ...headers, host: authority }, method: 'CONNECT' }).end(); return getStream(request); } } module.exports = { Http2OverHttp, Http2OverHttps: Http2OverHttp }; /***/ }), /***/ 8553: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {globalAgent} = __webpack_require__(9898); const Http2OverHttpX = __webpack_require__(1857); const getAuthorizationHeaders = __webpack_require__(7885); const getStatusCode = stream => new Promise((resolve, reject) => { stream.once('error', reject); stream.once('response', headers => { stream.off('error', reject); resolve(headers[':status']); }); }); class Http2OverHttp2 extends Http2OverHttpX { async _getProxyStream(authority) { const {proxyOptions} = this; const headers = { ...getAuthorizationHeaders(this), ...proxyOptions.headers, ':method': 'CONNECT', ':authority': authority }; const stream = await globalAgent.request(proxyOptions.url, proxyOptions, headers); const statusCode = await getStatusCode(stream); return [stream, statusCode]; } } module.exports = Http2OverHttp2; /***/ }), /***/ 1857: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {Agent} = __webpack_require__(9898); const JSStreamSocket = __webpack_require__(1564); const UnexpectedStatusCodeError = __webpack_require__(6203); const initialize = __webpack_require__(1089); class Http2OverHttpX extends Agent { constructor(options) { super(options); initialize(this, options.proxyOptions); } async createConnection(origin, options) { const authority = `${origin.hostname}:${origin.port || 443}`; const [stream, statusCode] = await this._getProxyStream(authority); if (statusCode !== 200) { throw new UnexpectedStatusCodeError(statusCode); } if (this.proxyOptions.raw) { options.socket = stream; } else { const socket = new JSStreamSocket(stream); socket.encrypted = false; socket._handle.getpeername = out => { out.family = undefined; out.address = undefined; out.port = undefined; }; return socket; } return super.createConnection(origin, options); } } module.exports = Http2OverHttpX; /***/ }), /***/ 1089: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { // See https://github.com/facebook/jest/issues/2549 // eslint-disable-next-line node/prefer-global/url const {URL} = __webpack_require__(7310); const checkType = __webpack_require__(3453); module.exports = (self, proxyOptions) => { checkType('proxyOptions', proxyOptions, ['object']); checkType('proxyOptions.headers', proxyOptions.headers, ['object', 'undefined']); checkType('proxyOptions.raw', proxyOptions.raw, ['boolean', 'undefined']); checkType('proxyOptions.url', proxyOptions.url, [URL, 'string']); const url = new URL(proxyOptions.url); self.proxyOptions = { raw: true, ...proxyOptions, headers: {...proxyOptions.headers}, url }; }; /***/ }), /***/ 6203: /***/ ((module) => { class UnexpectedStatusCodeError extends Error { constructor(statusCode) { super(`The proxy server rejected the request with status code ${statusCode}`); this.statusCode = statusCode; } } module.exports = UnexpectedStatusCodeError; /***/ }), /***/ 1982: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {isIP} = __webpack_require__(1808); const assert = __webpack_require__(9491); const getHost = host => { if (host[0] === '[') { const idx = host.indexOf(']'); assert(idx !== -1); return host.slice(1, idx); } const idx = host.indexOf(':'); if (idx === -1) { return host; } return host.slice(0, idx); }; module.exports = host => { const servername = getHost(host); if (isIP(servername)) { return ''; } return servername; }; /***/ }), /***/ 3453: /***/ ((module) => { const checkType = (name, value, types) => { const valid = types.some(type => { const typeofType = typeof type; if (typeofType === 'string') { return typeof value === type; } return value instanceof type; }); if (!valid) { const names = types.map(type => typeof type === 'string' ? type : type.name); throw new TypeError(`Expected '${name}' to be a type of ${names.join(' or ')}, got ${typeof value}`); } }; module.exports = checkType; /***/ }), /***/ 9237: /***/ ((module) => { module.exports = stream => { if (stream.listenerCount('error') !== 0) { return stream; } stream.__destroy = stream._destroy; stream._destroy = (...args) => { const callback = args.pop(); stream.__destroy(...args, async error => { await Promise.resolve(); callback(error); }); }; const onError = error => { // eslint-disable-next-line promise/prefer-await-to-then Promise.resolve().then(() => { stream.emit('error', error); }); }; stream.once('error', onError); // eslint-disable-next-line promise/prefer-await-to-then Promise.resolve().then(() => { stream.off('error', onError); }); return stream; }; /***/ }), /***/ 7087: /***/ ((module) => { /* istanbul ignore file: https://github.com/nodejs/node/blob/master/lib/internal/errors.js */ const makeError = (Base, key, getMessage) => { module.exports[key] = class NodeError extends Base { constructor(...args) { super(typeof getMessage === 'string' ? getMessage : getMessage(args)); this.name = `${super.name} [${key}]`; this.code = key; } }; }; makeError(TypeError, 'ERR_INVALID_ARG_TYPE', args => { const type = args[0].includes('.') ? 'property' : 'argument'; let valid = args[1]; const isManyTypes = Array.isArray(valid); if (isManyTypes) { valid = `${valid.slice(0, -1).join(', ')} or ${valid.slice(-1)}`; } return `The "${args[0]}" ${type} must be ${isManyTypes ? 'one of' : 'of'} type ${valid}. Received ${typeof args[2]}`; }); makeError(TypeError, 'ERR_INVALID_PROTOCOL', args => `Protocol "${args[0]}" not supported. Expected "${args[1]}"` ); makeError(Error, 'ERR_HTTP_HEADERS_SENT', args => `Cannot ${args[0]} headers after they are sent to the client` ); makeError(TypeError, 'ERR_INVALID_HTTP_TOKEN', args => `${args[0]} must be a valid HTTP token [${args[1]}]` ); makeError(TypeError, 'ERR_HTTP_INVALID_HEADER_VALUE', args => `Invalid value "${args[0]} for header "${args[1]}"` ); makeError(TypeError, 'ERR_INVALID_CHAR', args => `Invalid character in ${args[0]} [${args[1]}]` ); makeError( Error, 'ERR_HTTP2_NO_SOCKET_MANIPULATION', 'HTTP/2 sockets should not be directly manipulated (e.g. read and written)' ); /***/ }), /***/ 1199: /***/ ((module) => { module.exports = header => { switch (header) { case ':method': case ':scheme': case ':authority': case ':path': return true; default: return false; } }; /***/ }), /***/ 1564: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const stream = __webpack_require__(2781); const tls = __webpack_require__(4404); // Really awesome hack. const JSStreamSocket = (new tls.TLSSocket(new stream.PassThrough()))._handle._parentWrap.constructor; module.exports = JSStreamSocket; /***/ }), /***/ 1818: /***/ ((module) => { module.exports = (from, to, events) => { for (const event of events) { from.on(event, (...args) => to.emit(event, ...args)); } }; /***/ }), /***/ 9404: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {ERR_HTTP2_NO_SOCKET_MANIPULATION} = __webpack_require__(7087); /* istanbul ignore file */ /* https://github.com/nodejs/node/blob/6eec858f34a40ffa489c1ec54bb24da72a28c781/lib/internal/http2/compat.js#L195-L272 */ const proxySocketHandler = { has(stream, property) { // Replaced [kSocket] with .socket const reference = stream.session === undefined ? stream : stream.session.socket; return (property in stream) || (property in reference); }, get(stream, property) { switch (property) { case 'on': case 'once': case 'end': case 'emit': case 'destroy': return stream[property].bind(stream); case 'writable': case 'destroyed': return stream[property]; case 'readable': if (stream.destroyed) { return false; } return stream.readable; case 'setTimeout': { const {session} = stream; if (session !== undefined) { return session.setTimeout.bind(session); } return stream.setTimeout.bind(stream); } case 'write': case 'read': case 'pause': case 'resume': throw new ERR_HTTP2_NO_SOCKET_MANIPULATION(); default: { // Replaced [kSocket] with .socket const reference = stream.session === undefined ? stream : stream.session.socket; const value = reference[property]; return typeof value === 'function' ? value.bind(reference) : value; } } }, getPrototypeOf(stream) { if (stream.session !== undefined) { // Replaced [kSocket] with .socket return Reflect.getPrototypeOf(stream.session.socket); } return Reflect.getPrototypeOf(stream); }, set(stream, property, value) { switch (property) { case 'writable': case 'readable': case 'destroyed': case 'on': case 'once': case 'end': case 'emit': case 'destroy': stream[property] = value; return true; case 'setTimeout': { const {session} = stream; if (session === undefined) { stream.setTimeout = value; } else { session.setTimeout = value; } return true; } case 'write': case 'read': case 'pause': case 'resume': throw new ERR_HTTP2_NO_SOCKET_MANIPULATION(); default: { // Replaced [kSocket] with .socket const reference = stream.session === undefined ? stream : stream.session.socket; reference[property] = value; return true; } } } }; module.exports = proxySocketHandler; /***/ }), /***/ 4592: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const {ERR_INVALID_HTTP_TOKEN} = __webpack_require__(7087); const isRequestPseudoHeader = __webpack_require__(1199); const isValidHttpToken = /^[\^`\-\w!#$%&*+.|~]+$/; module.exports = name => { if (typeof name !== 'string' || (!isValidHttpToken.test(name) && !isRequestPseudoHeader(name))) { throw new ERR_INVALID_HTTP_TOKEN('Header name', name); } }; /***/ }), /***/ 3549: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const { ERR_HTTP_INVALID_HEADER_VALUE, ERR_INVALID_CHAR } = __webpack_require__(7087); const isInvalidHeaderValue = /[^\t\u0020-\u007E\u0080-\u00FF]/; module.exports = (name, value) => { if (typeof value === 'undefined') { throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name); } if (isInvalidHeaderValue.test(value)) { throw new ERR_INVALID_CHAR('header content', name); } }; /***/ }), /***/ 2820: /***/ ((__unused_webpack_module, exports) => { //TODO: handle reviver/dehydrate function like normal //and handle indentation, like normal. //if anyone needs this... please send pull request. exports.stringify = function stringify (o) { if('undefined' == typeof o) return o if(o && Buffer.isBuffer(o)) return JSON.stringify(':base64:' + o.toString('base64')) if(o && o.toJSON) o = o.toJSON() if(o && 'object' === typeof o) { var s = '' var array = Array.isArray(o) s = array ? '[' : '{' var first = true for(var k in o) { var ignore = 'function' == typeof o[k] || (!array && 'undefined' === typeof o[k]) if(Object.hasOwnProperty.call(o, k) && !ignore) { if(!first) s += ',' first = false if (array) { if(o[k] == undefined) s += 'null' else s += stringify(o[k]) } else if (o[k] !== void(0)) { s += stringify(k) + ':' + stringify(o[k]) } } } s += array ? ']' : '}' return s } else if ('string' === typeof o) { return JSON.stringify(/^:/.test(o) ? ':' + o : o) } else if ('undefined' === typeof o) { return 'null'; } else return JSON.stringify(o) } exports.parse = function (s) { return JSON.parse(s, function (key, value) { if('string' === typeof value) { if(/^:base64:/.test(value)) return Buffer.from(value.substring(8), 'base64') else return /^:/.test(value) ? value.substring(1) : value } return value }) } /***/ }), /***/ 1531: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const EventEmitter = __webpack_require__(2361); const JSONB = __webpack_require__(2820); const loadStore = options => { const adapters = { redis: '@keyv/redis', rediss: '@keyv/redis', mongodb: '@keyv/mongo', mongo: '@keyv/mongo', sqlite: '@keyv/sqlite', postgresql: '@keyv/postgres', postgres: '@keyv/postgres', mysql: '@keyv/mysql', etcd: '@keyv/etcd', offline: '@keyv/offline', tiered: '@keyv/tiered', }; if (options.adapter || options.uri) { const adapter = options.adapter || /^[^:+]*/.exec(options.uri)[0]; return new (require(adapters[adapter]))(options); } return new Map(); }; const iterableAdapters = [ 'sqlite', 'postgres', 'mysql', 'mongo', 'redis', 'tiered', ]; class Keyv extends EventEmitter { constructor(uri, {emitErrors = true, ...options} = {}) { super(); this.opts = { namespace: 'keyv', serialize: JSONB.stringify, deserialize: JSONB.parse, ...((typeof uri === 'string') ? {uri} : uri), ...options, }; if (!this.opts.store) { const adapterOptions = {...this.opts}; this.opts.store = loadStore(adapterOptions); } if (this.opts.compression) { const compression = this.opts.compression; this.opts.serialize = compression.serialize.bind(compression); this.opts.deserialize = compression.deserialize.bind(compression); } if (typeof this.opts.store.on === 'function' && emitErrors) { this.opts.store.on('error', error => this.emit('error', error)); } this.opts.store.namespace = this.opts.namespace; const generateIterator = iterator => async function * () { for await (const [key, raw] of typeof iterator === 'function' ? iterator(this.opts.store.namespace) : iterator) { const data = this.opts.deserialize(raw); if (this.opts.store.namespace && !key.includes(this.opts.store.namespace)) { continue; } if (typeof data.expires === 'number' && Date.now() > data.expires) { this.delete(key); continue; } yield [this._getKeyUnprefix(key), data.value]; } }; // Attach iterators if (typeof this.opts.store[Symbol.iterator] === 'function' && this.opts.store instanceof Map) { this.iterator = generateIterator(this.opts.store); } else if (typeof this.opts.store.iterator === 'function' && this.opts.store.opts && this._checkIterableAdaptar()) { this.iterator = generateIterator(this.opts.store.iterator.bind(this.opts.store)); } } _checkIterableAdaptar() { return iterableAdapters.includes(this.opts.store.opts.dialect) || iterableAdapters.findIndex(element => this.opts.store.opts.url.includes(element)) >= 0; } _getKeyPrefix(key) { return `${this.opts.namespace}:${key}`; } _getKeyPrefixArray(keys) { return keys.map(key => `${this.opts.namespace}:${key}`); } _getKeyUnprefix(key) { return key .split(':') .splice(1) .join(':'); } get(key, options) { const {store} = this.opts; const isArray = Array.isArray(key); const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key); if (isArray && store.getMany === undefined) { const promises = []; for (const key of keyPrefixed) { promises.push(Promise.resolve() .then(() => store.get(key)) .then(data => (typeof data === 'string') ? this.opts.deserialize(data) : (this.opts.compression ? this.opts.deserialize(data) : data)) .then(data => { if (data === undefined || data === null) { return undefined; } if (typeof data.expires === 'number' && Date.now() > data.expires) { return this.delete(key).then(() => undefined); } return (options && options.raw) ? data : data.value; }), ); } return Promise.allSettled(promises) .then(values => { const data = []; for (const value of values) { data.push(value.value); } return data; }); } return Promise.resolve() .then(() => isArray ? store.getMany(keyPrefixed) : store.get(keyPrefixed)) .then(data => (typeof data === 'string') ? this.opts.deserialize(data) : (this.opts.compression ? this.opts.deserialize(data) : data)) .then(data => { if (data === undefined || data === null) { return undefined; } if (isArray) { const result = []; for (let row of data) { if ((typeof row === 'string')) { row = this.opts.deserialize(row); } if (row === undefined || row === null) { result.push(undefined); continue; } if (typeof row.expires === 'number' && Date.now() > row.expires) { this.delete(key).then(() => undefined); result.push(undefined); } else { result.push((options && options.raw) ? row : row.value); } } return result; } if (typeof data.expires === 'number' && Date.now() > data.expires) { return this.delete(key).then(() => undefined); } return (options && options.raw) ? data : data.value; }); } set(key, value, ttl) { const keyPrefixed = this._getKeyPrefix(key); if (typeof ttl === 'undefined') { ttl = this.opts.ttl; } if (ttl === 0) { ttl = undefined; } const {store} = this.opts; return Promise.resolve() .then(() => { const expires = (typeof ttl === 'number') ? (Date.now() + ttl) : null; if (typeof value === 'symbol') { this.emit('error', 'symbol cannot be serialized'); } value = {value, expires}; return this.opts.serialize(value); }) .then(value => store.set(keyPrefixed, value, ttl)) .then(() => true); } delete(key) { const {store} = this.opts; if (Array.isArray(key)) { const keyPrefixed = this._getKeyPrefixArray(key); if (store.deleteMany === undefined) { const promises = []; for (const key of keyPrefixed) { promises.push(store.delete(key)); } return Promise.allSettled(promises) .then(values => values.every(x => x.value === true)); } return Promise.resolve() .then(() => store.deleteMany(keyPrefixed)); } const keyPrefixed = this._getKeyPrefix(key); return Promise.resolve() .then(() => store.delete(keyPrefixed)); } clear() { const {store} = this.opts; return Promise.resolve() .then(() => store.clear()); } has(key) { const keyPrefixed = this._getKeyPrefix(key); const {store} = this.opts; return Promise.resolve() .then(async () => { if (typeof store.has === 'function') { return store.has(keyPrefixed); } const value = await store.get(keyPrefixed); return value !== undefined; }); } disconnect() { const {store} = this.opts; if (typeof store.disconnect === 'function') { return store.disconnect(); } } } module.exports = Keyv; /***/ }), /***/ 9273: /***/ ((module) => { class QuickLRU { constructor(options = {}) { if (!(options.maxSize && options.maxSize > 0)) { throw new TypeError('`maxSize` must be a number greater than 0'); } this.maxSize = options.maxSize; this.onEviction = options.onEviction; this.cache = new Map(); this.oldCache = new Map(); this._size = 0; } _set(key, value) { this.cache.set(key, value); this._size++; if (this._size >= this.maxSize) { this._size = 0; if (typeof this.onEviction === 'function') { for (const [key, value] of this.oldCache.entries()) { this.onEviction(key, value); } } this.oldCache = this.cache; this.cache = new Map(); } } get(key) { if (this.cache.has(key)) { return this.cache.get(key); } if (this.oldCache.has(key)) { const value = this.oldCache.get(key); this.oldCache.delete(key); this._set(key, value); return value; } } set(key, value) { if (this.cache.has(key)) { this.cache.set(key, value); } else { this._set(key, value); } return this; } has(key) { return this.cache.has(key) || this.oldCache.has(key); } peek(key) { if (this.cache.has(key)) { return this.cache.get(key); } if (this.oldCache.has(key)) { return this.oldCache.get(key); } } delete(key) { const deleted = this.cache.delete(key); if (deleted) { this._size--; } return this.oldCache.delete(key) || deleted; } clear() { this.cache.clear(); this.oldCache.clear(); this._size = 0; } * keys() { for (const [key] of this) { yield key; } } * values() { for (const [, value] of this) { yield value; } } * [Symbol.iterator]() { for (const item of this.cache) { yield item; } for (const item of this.oldCache) { const [key] = item; if (!this.cache.has(key)) { yield item; } } } get size() { let oldCacheSize = 0; for (const key of this.oldCache.keys()) { if (!this.cache.has(key)) { oldCacheSize++; } } return Math.min(this._size + oldCacheSize, this.maxSize); } } module.exports = QuickLRU; /***/ }), /***/ 6624: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const tls = __webpack_require__(4404); module.exports = (options = {}, connect = tls.connect) => new Promise((resolve, reject) => { let timeout = false; let socket; const callback = async () => { await socketPromise; socket.off('timeout', onTimeout); socket.off('error', reject); if (options.resolveSocket) { resolve({alpnProtocol: socket.alpnProtocol, socket, timeout}); if (timeout) { await Promise.resolve(); socket.emit('timeout'); } } else { socket.destroy(); resolve({alpnProtocol: socket.alpnProtocol, timeout}); } }; const onTimeout = async () => { timeout = true; callback(); }; const socketPromise = (async () => { try { socket = await connect(options, callback); socket.on('error', reject); socket.once('timeout', onTimeout); } catch (error) { reject(error); } })(); }); /***/ }), /***/ 593: /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "AbortError": () => (/* reexport */ AbortError), "CacheError": () => (/* reexport */ CacheError), "CancelError": () => (/* reexport */ types_CancelError), "HTTPError": () => (/* reexport */ HTTPError), "MaxRedirectsError": () => (/* reexport */ MaxRedirectsError), "Options": () => (/* reexport */ Options), "ParseError": () => (/* reexport */ ParseError), "ReadError": () => (/* reexport */ ReadError), "RequestError": () => (/* reexport */ RequestError), "RetryError": () => (/* reexport */ RetryError), "TimeoutError": () => (/* reexport */ TimeoutError), "UploadError": () => (/* reexport */ UploadError), "calculateRetryDelay": () => (/* reexport */ calculate_retry_delay), "create": () => (/* reexport */ source_create), "default": () => (/* binding */ got_dist_source), "got": () => (/* binding */ got), "isResponseOk": () => (/* reexport */ isResponseOk), "parseBody": () => (/* reexport */ parseBody), "parseLinkHeader": () => (/* reexport */ parseLinkHeader) }); ;// CONCATENATED MODULE: ./node_modules/@sindresorhus/is/dist/index.js const typedArrayTypeNames = [ 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array', ]; function isTypedArrayName(name) { return typedArrayTypeNames.includes(name); } const objectTypeNames = [ 'Function', 'Generator', 'AsyncGenerator', 'GeneratorFunction', 'AsyncGeneratorFunction', 'AsyncFunction', 'Observable', 'Array', 'Buffer', 'Blob', 'Object', 'RegExp', 'Date', 'Error', 'Map', 'Set', 'WeakMap', 'WeakSet', 'WeakRef', 'ArrayBuffer', 'SharedArrayBuffer', 'DataView', 'Promise', 'URL', 'FormData', 'URLSearchParams', 'HTMLElement', 'NaN', ...typedArrayTypeNames, ]; function isObjectTypeName(name) { return objectTypeNames.includes(name); } const primitiveTypeNames = [ 'null', 'undefined', 'string', 'number', 'bigint', 'boolean', 'symbol', ]; function isPrimitiveTypeName(name) { return primitiveTypeNames.includes(name); } // eslint-disable-next-line @typescript-eslint/ban-types function isOfType(type) { return (value) => typeof value === type; } const { toString: dist_toString } = Object.prototype; const getObjectType = (value) => { const objectTypeName = dist_toString.call(value).slice(8, -1); if (/HTML\w+Element/.test(objectTypeName) && is.domElement(value)) { return 'HTMLElement'; } if (isObjectTypeName(objectTypeName)) { return objectTypeName; } return undefined; }; const isObjectOfType = (type) => (value) => getObjectType(value) === type; function is(value) { if (value === null) { return 'null'; } switch (typeof value) { case 'undefined': return 'undefined'; case 'string': return 'string'; case 'number': return Number.isNaN(value) ? 'NaN' : 'number'; case 'boolean': return 'boolean'; case 'function': return 'Function'; case 'bigint': return 'bigint'; case 'symbol': return 'symbol'; default: } if (is.observable(value)) { return 'Observable'; } if (is.array(value)) { return 'Array'; } if (is.buffer(value)) { return 'Buffer'; } const tagType = getObjectType(value); if (tagType) { return tagType; } if (value instanceof String || value instanceof Boolean || value instanceof Number) { throw new TypeError('Please don\'t use object wrappers for primitive types'); } return 'Object'; } is.undefined = isOfType('undefined'); is.string = isOfType('string'); const isNumberType = isOfType('number'); is.number = (value) => isNumberType(value) && !is.nan(value); is.bigint = isOfType('bigint'); // eslint-disable-next-line @typescript-eslint/ban-types is.function_ = isOfType('function'); // eslint-disable-next-line @typescript-eslint/ban-types is.null_ = (value) => value === null; is.class_ = (value) => is.function_(value) && value.toString().startsWith('class '); is.boolean = (value) => value === true || value === false; is.symbol = isOfType('symbol'); is.numericString = (value) => is.string(value) && !is.emptyStringOrWhitespace(value) && !Number.isNaN(Number(value)); is.array = (value, assertion) => { if (!Array.isArray(value)) { return false; } if (!is.function_(assertion)) { return true; } return value.every(element => assertion(element)); }; // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call is.buffer = (value) => value?.constructor?.isBuffer?.(value) ?? false; is.blob = (value) => isObjectOfType('Blob')(value); is.nullOrUndefined = (value) => is.null_(value) || is.undefined(value); // eslint-disable-line @typescript-eslint/ban-types is.object = (value) => !is.null_(value) && (typeof value === 'object' || is.function_(value)); // eslint-disable-line @typescript-eslint/ban-types is.iterable = (value) => is.function_(value?.[Symbol.iterator]); is.asyncIterable = (value) => is.function_(value?.[Symbol.asyncIterator]); is.generator = (value) => is.iterable(value) && is.function_(value?.next) && is.function_(value?.throw); is.asyncGenerator = (value) => is.asyncIterable(value) && is.function_(value.next) && is.function_(value.throw); is.nativePromise = (value) => isObjectOfType('Promise')(value); const hasPromiseApi = (value) => is.function_(value?.then) && is.function_(value?.catch); is.promise = (value) => is.nativePromise(value) || hasPromiseApi(value); is.generatorFunction = isObjectOfType('GeneratorFunction'); is.asyncGeneratorFunction = (value) => getObjectType(value) === 'AsyncGeneratorFunction'; is.asyncFunction = (value) => getObjectType(value) === 'AsyncFunction'; // eslint-disable-next-line no-prototype-builtins, @typescript-eslint/ban-types is.boundFunction = (value) => is.function_(value) && !value.hasOwnProperty('prototype'); is.regExp = isObjectOfType('RegExp'); is.date = isObjectOfType('Date'); is.error = isObjectOfType('Error'); is.map = (value) => isObjectOfType('Map')(value); is.set = (value) => isObjectOfType('Set')(value); is.weakMap = (value) => isObjectOfType('WeakMap')(value); // eslint-disable-line @typescript-eslint/ban-types is.weakSet = (value) => isObjectOfType('WeakSet')(value); // eslint-disable-line @typescript-eslint/ban-types is.weakRef = (value) => isObjectOfType('WeakRef')(value); // eslint-disable-line @typescript-eslint/ban-types is.int8Array = isObjectOfType('Int8Array'); is.uint8Array = isObjectOfType('Uint8Array'); is.uint8ClampedArray = isObjectOfType('Uint8ClampedArray'); is.int16Array = isObjectOfType('Int16Array'); is.uint16Array = isObjectOfType('Uint16Array'); is.int32Array = isObjectOfType('Int32Array'); is.uint32Array = isObjectOfType('Uint32Array'); is.float32Array = isObjectOfType('Float32Array'); is.float64Array = isObjectOfType('Float64Array'); is.bigInt64Array = isObjectOfType('BigInt64Array'); is.bigUint64Array = isObjectOfType('BigUint64Array'); is.arrayBuffer = isObjectOfType('ArrayBuffer'); is.sharedArrayBuffer = isObjectOfType('SharedArrayBuffer'); is.dataView = isObjectOfType('DataView'); is.enumCase = (value, targetEnum) => Object.values(targetEnum).includes(value); is.directInstanceOf = (instance, class_) => Object.getPrototypeOf(instance) === class_.prototype; is.urlInstance = (value) => isObjectOfType('URL')(value); is.urlString = (value) => { if (!is.string(value)) { return false; } try { new URL(value); // eslint-disable-line no-new return true; } catch { return false; } }; // Example: `is.truthy = (value: unknown): value is (not false | not 0 | not '' | not undefined | not null) => Boolean(value);` is.truthy = (value) => Boolean(value); // eslint-disable-line unicorn/prefer-native-coercion-functions // Example: `is.falsy = (value: unknown): value is (not true | 0 | '' | undefined | null) => Boolean(value);` is.falsy = (value) => !value; is.nan = (value) => Number.isNaN(value); is.primitive = (value) => is.null_(value) || isPrimitiveTypeName(typeof value); is.integer = (value) => Number.isInteger(value); is.safeInteger = (value) => Number.isSafeInteger(value); is.plainObject = (value) => { // From: https://github.com/sindresorhus/is-plain-obj/blob/main/index.js if (typeof value !== 'object' || value === null) { return false; } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const prototype = Object.getPrototypeOf(value); return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value); }; is.typedArray = (value) => isTypedArrayName(getObjectType(value)); const isValidLength = (value) => is.safeInteger(value) && value >= 0; is.arrayLike = (value) => !is.nullOrUndefined(value) && !is.function_(value) && isValidLength(value.length); is.inRange = (value, range) => { if (is.number(range)) { return value >= Math.min(0, range) && value <= Math.max(range, 0); } if (is.array(range) && range.length === 2) { return value >= Math.min(...range) && value <= Math.max(...range); } throw new TypeError(`Invalid range: ${JSON.stringify(range)}`); }; // eslint-disable-next-line @typescript-eslint/naming-convention const NODE_TYPE_ELEMENT = 1; // eslint-disable-next-line @typescript-eslint/naming-convention const DOM_PROPERTIES_TO_CHECK = [ 'innerHTML', 'ownerDocument', 'style', 'attributes', 'nodeValue', ]; is.domElement = (value) => is.object(value) && value.nodeType === NODE_TYPE_ELEMENT && is.string(value.nodeName) && !is.plainObject(value) && DOM_PROPERTIES_TO_CHECK.every(property => property in value); is.observable = (value) => { if (!value) { return false; } // eslint-disable-next-line no-use-extend-native/no-use-extend-native, @typescript-eslint/no-unsafe-call if (value === value[Symbol.observable]?.()) { return true; } // eslint-disable-next-line @typescript-eslint/no-unsafe-call if (value === value['@@observable']?.()) { return true; } return false; }; is.nodeStream = (value) => is.object(value) && is.function_(value.pipe) && !is.observable(value); is.infinite = (value) => value === Number.POSITIVE_INFINITY || value === Number.NEGATIVE_INFINITY; const isAbsoluteMod2 = (remainder) => (value) => is.integer(value) && Math.abs(value % 2) === remainder; is.evenInteger = isAbsoluteMod2(0); is.oddInteger = isAbsoluteMod2(1); is.emptyArray = (value) => is.array(value) && value.length === 0; is.nonEmptyArray = (value) => is.array(value) && value.length > 0; is.emptyString = (value) => is.string(value) && value.length === 0; const isWhiteSpaceString = (value) => is.string(value) && !/\S/.test(value); is.emptyStringOrWhitespace = (value) => is.emptyString(value) || isWhiteSpaceString(value); // TODO: Use `not ''` when the `not` operator is available. is.nonEmptyString = (value) => is.string(value) && value.length > 0; // TODO: Use `not ''` when the `not` operator is available. is.nonEmptyStringAndNotWhitespace = (value) => is.string(value) && !is.emptyStringOrWhitespace(value); // eslint-disable-next-line unicorn/no-array-callback-reference is.emptyObject = (value) => is.object(value) && !is.map(value) && !is.set(value) && Object.keys(value).length === 0; // TODO: Use `not` operator here to remove `Map` and `Set` from type guard: // - https://github.com/Microsoft/TypeScript/pull/29317 // eslint-disable-next-line unicorn/no-array-callback-reference is.nonEmptyObject = (value) => is.object(value) && !is.map(value) && !is.set(value) && Object.keys(value).length > 0; is.emptySet = (value) => is.set(value) && value.size === 0; is.nonEmptySet = (value) => is.set(value) && value.size > 0; // eslint-disable-next-line unicorn/no-array-callback-reference is.emptyMap = (value) => is.map(value) && value.size === 0; // eslint-disable-next-line unicorn/no-array-callback-reference is.nonEmptyMap = (value) => is.map(value) && value.size > 0; // `PropertyKey` is any value that can be used as an object key (string, number, or symbol) is.propertyKey = (value) => is.any([is.string, is.number, is.symbol], value); is.formData = (value) => isObjectOfType('FormData')(value); is.urlSearchParams = (value) => isObjectOfType('URLSearchParams')(value); const predicateOnArray = (method, predicate, values) => { if (!is.function_(predicate)) { throw new TypeError(`Invalid predicate: ${JSON.stringify(predicate)}`); } if (values.length === 0) { throw new TypeError('Invalid number of values'); } return method.call(values, predicate); }; is.any = (predicate, ...values) => { const predicates = is.array(predicate) ? predicate : [predicate]; return predicates.some(singlePredicate => predicateOnArray(Array.prototype.some, singlePredicate, values)); }; is.all = (predicate, ...values) => predicateOnArray(Array.prototype.every, predicate, values); const assertType = (condition, description, value, options = {}) => { if (!condition) { const { multipleValues } = options; const valuesMessage = multipleValues ? `received values of types ${[ ...new Set(value.map(singleValue => `\`${is(singleValue)}\``)), ].join(', ')}` : `received value of type \`${is(value)}\``; throw new TypeError(`Expected value which is \`${description}\`, ${valuesMessage}.`); } }; /* eslint-disable @typescript-eslint/no-confusing-void-expression */ const assert = { // Unknowns. undefined: (value) => assertType(is.undefined(value), 'undefined', value), string: (value) => assertType(is.string(value), 'string', value), number: (value) => assertType(is.number(value), 'number', value), bigint: (value) => assertType(is.bigint(value), 'bigint', value), // eslint-disable-next-line @typescript-eslint/ban-types function_: (value) => assertType(is.function_(value), 'Function', value), null_: (value) => assertType(is.null_(value), 'null', value), class_: (value) => assertType(is.class_(value), "Class" /* AssertionTypeDescription.class_ */, value), boolean: (value) => assertType(is.boolean(value), 'boolean', value), symbol: (value) => assertType(is.symbol(value), 'symbol', value), numericString: (value) => assertType(is.numericString(value), "string with a number" /* AssertionTypeDescription.numericString */, value), array: (value, assertion) => { const assert = assertType; assert(is.array(value), 'Array', value); if (assertion) { // eslint-disable-next-line unicorn/no-array-for-each, unicorn/no-array-callback-reference value.forEach(assertion); } }, buffer: (value) => assertType(is.buffer(value), 'Buffer', value), blob: (value) => assertType(is.blob(value), 'Blob', value), nullOrUndefined: (value) => assertType(is.nullOrUndefined(value), "null or undefined" /* AssertionTypeDescription.nullOrUndefined */, value), object: (value) => assertType(is.object(value), 'Object', value), iterable: (value) => assertType(is.iterable(value), "Iterable" /* AssertionTypeDescription.iterable */, value), asyncIterable: (value) => assertType(is.asyncIterable(value), "AsyncIterable" /* AssertionTypeDescription.asyncIterable */, value), generator: (value) => assertType(is.generator(value), 'Generator', value), asyncGenerator: (value) => assertType(is.asyncGenerator(value), 'AsyncGenerator', value), nativePromise: (value) => assertType(is.nativePromise(value), "native Promise" /* AssertionTypeDescription.nativePromise */, value), promise: (value) => assertType(is.promise(value), 'Promise', value), generatorFunction: (value) => assertType(is.generatorFunction(value), 'GeneratorFunction', value), asyncGeneratorFunction: (value) => assertType(is.asyncGeneratorFunction(value), 'AsyncGeneratorFunction', value), // eslint-disable-next-line @typescript-eslint/ban-types asyncFunction: (value) => assertType(is.asyncFunction(value), 'AsyncFunction', value), // eslint-disable-next-line @typescript-eslint/ban-types boundFunction: (value) => assertType(is.boundFunction(value), 'Function', value), regExp: (value) => assertType(is.regExp(value), 'RegExp', value), date: (value) => assertType(is.date(value), 'Date', value), error: (value) => assertType(is.error(value), 'Error', value), map: (value) => assertType(is.map(value), 'Map', value), set: (value) => assertType(is.set(value), 'Set', value), weakMap: (value) => assertType(is.weakMap(value), 'WeakMap', value), weakSet: (value) => assertType(is.weakSet(value), 'WeakSet', value), weakRef: (value) => assertType(is.weakRef(value), 'WeakRef', value), int8Array: (value) => assertType(is.int8Array(value), 'Int8Array', value), uint8Array: (value) => assertType(is.uint8Array(value), 'Uint8Array', value), uint8ClampedArray: (value) => assertType(is.uint8ClampedArray(value), 'Uint8ClampedArray', value), int16Array: (value) => assertType(is.int16Array(value), 'Int16Array', value), uint16Array: (value) => assertType(is.uint16Array(value), 'Uint16Array', value), int32Array: (value) => assertType(is.int32Array(value), 'Int32Array', value), uint32Array: (value) => assertType(is.uint32Array(value), 'Uint32Array', value), float32Array: (value) => assertType(is.float32Array(value), 'Float32Array', value), float64Array: (value) => assertType(is.float64Array(value), 'Float64Array', value), bigInt64Array: (value) => assertType(is.bigInt64Array(value), 'BigInt64Array', value), bigUint64Array: (value) => assertType(is.bigUint64Array(value), 'BigUint64Array', value), arrayBuffer: (value) => assertType(is.arrayBuffer(value), 'ArrayBuffer', value), sharedArrayBuffer: (value) => assertType(is.sharedArrayBuffer(value), 'SharedArrayBuffer', value), dataView: (value) => assertType(is.dataView(value), 'DataView', value), enumCase: (value, targetEnum) => assertType(is.enumCase(value, targetEnum), 'EnumCase', value), urlInstance: (value) => assertType(is.urlInstance(value), 'URL', value), urlString: (value) => assertType(is.urlString(value), "string with a URL" /* AssertionTypeDescription.urlString */, value), truthy: (value) => assertType(is.truthy(value), "truthy" /* AssertionTypeDescription.truthy */, value), falsy: (value) => assertType(is.falsy(value), "falsy" /* AssertionTypeDescription.falsy */, value), nan: (value) => assertType(is.nan(value), "NaN" /* AssertionTypeDescription.nan */, value), primitive: (value) => assertType(is.primitive(value), "primitive" /* AssertionTypeDescription.primitive */, value), integer: (value) => assertType(is.integer(value), "integer" /* AssertionTypeDescription.integer */, value), safeInteger: (value) => assertType(is.safeInteger(value), "integer" /* AssertionTypeDescription.safeInteger */, value), plainObject: (value) => assertType(is.plainObject(value), "plain object" /* AssertionTypeDescription.plainObject */, value), typedArray: (value) => assertType(is.typedArray(value), "TypedArray" /* AssertionTypeDescription.typedArray */, value), arrayLike: (value) => assertType(is.arrayLike(value), "array-like" /* AssertionTypeDescription.arrayLike */, value), domElement: (value) => assertType(is.domElement(value), "HTMLElement" /* AssertionTypeDescription.domElement */, value), observable: (value) => assertType(is.observable(value), 'Observable', value), nodeStream: (value) => assertType(is.nodeStream(value), "Node.js Stream" /* AssertionTypeDescription.nodeStream */, value), infinite: (value) => assertType(is.infinite(value), "infinite number" /* AssertionTypeDescription.infinite */, value), emptyArray: (value) => assertType(is.emptyArray(value), "empty array" /* AssertionTypeDescription.emptyArray */, value), nonEmptyArray: (value) => assertType(is.nonEmptyArray(value), "non-empty array" /* AssertionTypeDescription.nonEmptyArray */, value), emptyString: (value) => assertType(is.emptyString(value), "empty string" /* AssertionTypeDescription.emptyString */, value), emptyStringOrWhitespace: (value) => assertType(is.emptyStringOrWhitespace(value), "empty string or whitespace" /* AssertionTypeDescription.emptyStringOrWhitespace */, value), nonEmptyString: (value) => assertType(is.nonEmptyString(value), "non-empty string" /* AssertionTypeDescription.nonEmptyString */, value), nonEmptyStringAndNotWhitespace: (value) => assertType(is.nonEmptyStringAndNotWhitespace(value), "non-empty string and not whitespace" /* AssertionTypeDescription.nonEmptyStringAndNotWhitespace */, value), emptyObject: (value) => assertType(is.emptyObject(value), "empty object" /* AssertionTypeDescription.emptyObject */, value), nonEmptyObject: (value) => assertType(is.nonEmptyObject(value), "non-empty object" /* AssertionTypeDescription.nonEmptyObject */, value), emptySet: (value) => assertType(is.emptySet(value), "empty set" /* AssertionTypeDescription.emptySet */, value), nonEmptySet: (value) => assertType(is.nonEmptySet(value), "non-empty set" /* AssertionTypeDescription.nonEmptySet */, value), emptyMap: (value) => assertType(is.emptyMap(value), "empty map" /* AssertionTypeDescription.emptyMap */, value), nonEmptyMap: (value) => assertType(is.nonEmptyMap(value), "non-empty map" /* AssertionTypeDescription.nonEmptyMap */, value), propertyKey: (value) => assertType(is.propertyKey(value), 'PropertyKey', value), formData: (value) => assertType(is.formData(value), 'FormData', value), urlSearchParams: (value) => assertType(is.urlSearchParams(value), 'URLSearchParams', value), // Numbers. evenInteger: (value) => assertType(is.evenInteger(value), "even integer" /* AssertionTypeDescription.evenInteger */, value), oddInteger: (value) => assertType(is.oddInteger(value), "odd integer" /* AssertionTypeDescription.oddInteger */, value), // Two arguments. directInstanceOf: (instance, class_) => assertType(is.directInstanceOf(instance, class_), "T" /* AssertionTypeDescription.directInstanceOf */, instance), inRange: (value, range) => assertType(is.inRange(value, range), "in range" /* AssertionTypeDescription.inRange */, value), // Variadic functions. any: (predicate, ...values) => assertType(is.any(predicate, ...values), "predicate returns truthy for any value" /* AssertionTypeDescription.any */, values, { multipleValues: true }), all: (predicate, ...values) => assertType(is.all(predicate, ...values), "predicate returns truthy for all values" /* AssertionTypeDescription.all */, values, { multipleValues: true }), }; /* eslint-enable @typescript-eslint/no-confusing-void-expression */ // Some few keywords are reserved, but we'll populate them for Node.js users // See https://github.com/Microsoft/TypeScript/issues/2536 Object.defineProperties(is, { class: { value: is.class_, }, function: { value: is.function_, }, null: { value: is.null_, }, }); Object.defineProperties(assert, { class: { value: assert.class_, }, function: { value: assert.function_, }, null: { value: assert.null_, }, }); /* harmony default export */ const dist = (is); // EXTERNAL MODULE: external "node:events" var external_node_events_ = __webpack_require__(5673); ;// CONCATENATED MODULE: ./node_modules/p-cancelable/index.js class CancelError extends Error { constructor(reason) { super(reason || 'Promise was canceled'); this.name = 'CancelError'; } get isCanceled() { return true; } } // TODO: Use private class fields when ESLint 8 is out. class PCancelable { static fn(userFunction) { return (...arguments_) => { return new PCancelable((resolve, reject, onCancel) => { arguments_.push(onCancel); // eslint-disable-next-line promise/prefer-await-to-then userFunction(...arguments_).then(resolve, reject); }); }; } constructor(executor) { this._cancelHandlers = []; this._isPending = true; this._isCanceled = false; this._rejectOnCancel = true; this._promise = new Promise((resolve, reject) => { this._reject = reject; const onResolve = value => { if (!this._isCanceled || !onCancel.shouldReject) { this._isPending = false; resolve(value); } }; const onReject = error => { this._isPending = false; reject(error); }; const onCancel = handler => { if (!this._isPending) { throw new Error('The `onCancel` handler was attached after the promise settled.'); } this._cancelHandlers.push(handler); }; Object.defineProperties(onCancel, { shouldReject: { get: () => this._rejectOnCancel, set: boolean => { this._rejectOnCancel = boolean; } } }); executor(onResolve, onReject, onCancel); }); } then(onFulfilled, onRejected) { // eslint-disable-next-line promise/prefer-await-to-then return this._promise.then(onFulfilled, onRejected); } catch(onRejected) { // eslint-disable-next-line promise/prefer-await-to-then return this._promise.catch(onRejected); } finally(onFinally) { // eslint-disable-next-line promise/prefer-await-to-then return this._promise.finally(onFinally); } cancel(reason) { if (!this._isPending || this._isCanceled) { return; } this._isCanceled = true; if (this._cancelHandlers.length > 0) { try { for (const handler of this._cancelHandlers) { handler(); } } catch (error) { this._reject(error); return; } } if (this._rejectOnCancel) { this._reject(new CancelError(reason)); } } get isCanceled() { return this._isCanceled; } } Object.setPrototypeOf(PCancelable.prototype, Promise.prototype); ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/errors.js // A hacky check to prevent circular references. function isRequest(x) { return dist.object(x) && '_onResponse' in x; } /** An error to be thrown when a request fails. Contains a `code` property with error class code, like `ECONNREFUSED`. */ class RequestError extends Error { constructor(message, error, self) { super(message); Object.defineProperty(this, "input", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "code", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "stack", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "response", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "request", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "timings", { enumerable: true, configurable: true, writable: true, value: void 0 }); Error.captureStackTrace(this, this.constructor); this.name = 'RequestError'; this.code = error.code ?? 'ERR_GOT_REQUEST_ERROR'; this.input = error.input; if (isRequest(self)) { Object.defineProperty(this, 'request', { enumerable: false, value: self, }); Object.defineProperty(this, 'response', { enumerable: false, value: self.response, }); this.options = self.options; } else { this.options = self; } this.timings = this.request?.timings; // Recover the original stacktrace if (dist.string(error.stack) && dist.string(this.stack)) { const indexOfMessage = this.stack.indexOf(this.message) + this.message.length; const thisStackTrace = this.stack.slice(indexOfMessage).split('\n').reverse(); const errorStackTrace = error.stack.slice(error.stack.indexOf(error.message) + error.message.length).split('\n').reverse(); // Remove duplicated traces while (errorStackTrace.length > 0 && errorStackTrace[0] === thisStackTrace[0]) { thisStackTrace.shift(); } this.stack = `${this.stack.slice(0, indexOfMessage)}${thisStackTrace.reverse().join('\n')}${errorStackTrace.reverse().join('\n')}`; } } } /** An error to be thrown when the server redirects you more than ten times. Includes a `response` property. */ class MaxRedirectsError extends RequestError { constructor(request) { super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request); this.name = 'MaxRedirectsError'; this.code = 'ERR_TOO_MANY_REDIRECTS'; } } /** An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304. Includes a `response` property. */ // eslint-disable-next-line @typescript-eslint/naming-convention class HTTPError extends RequestError { constructor(response) { super(`Response code ${response.statusCode} (${response.statusMessage})`, {}, response.request); this.name = 'HTTPError'; this.code = 'ERR_NON_2XX_3XX_RESPONSE'; } } /** An error to be thrown when a cache method fails. For example, if the database goes down or there's a filesystem error. */ class CacheError extends RequestError { constructor(error, request) { super(error.message, error, request); this.name = 'CacheError'; this.code = this.code === 'ERR_GOT_REQUEST_ERROR' ? 'ERR_CACHE_ACCESS' : this.code; } } /** An error to be thrown when the request body is a stream and an error occurs while reading from that stream. */ class UploadError extends RequestError { constructor(error, request) { super(error.message, error, request); this.name = 'UploadError'; this.code = this.code === 'ERR_GOT_REQUEST_ERROR' ? 'ERR_UPLOAD' : this.code; } } /** An error to be thrown when the request is aborted due to a timeout. Includes an `event` and `timings` property. */ class TimeoutError extends RequestError { constructor(error, timings, request) { super(error.message, error, request); Object.defineProperty(this, "timings", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "event", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.name = 'TimeoutError'; this.event = error.event; this.timings = timings; } } /** An error to be thrown when reading from response stream fails. */ class ReadError extends RequestError { constructor(error, request) { super(error.message, error, request); this.name = 'ReadError'; this.code = this.code === 'ERR_GOT_REQUEST_ERROR' ? 'ERR_READING_RESPONSE_STREAM' : this.code; } } /** An error which always triggers a new retry when thrown. */ class RetryError extends RequestError { constructor(request) { super('Retrying', {}, request); this.name = 'RetryError'; this.code = 'ERR_RETRYING'; } } /** An error to be thrown when the request is aborted by AbortController. */ class AbortError extends RequestError { constructor(request) { super('This operation was aborted.', {}, request); this.code = 'ERR_ABORTED'; this.name = 'AbortError'; } } // EXTERNAL MODULE: external "node:process" var external_node_process_ = __webpack_require__(7742); // EXTERNAL MODULE: external "node:buffer" var external_node_buffer_ = __webpack_require__(2254); // EXTERNAL MODULE: external "node:stream" var external_node_stream_ = __webpack_require__(4492); // EXTERNAL MODULE: external "node:url" var external_node_url_ = __webpack_require__(1041); // EXTERNAL MODULE: external "node:http" var external_node_http_ = __webpack_require__(8849); // EXTERNAL MODULE: external "events" var external_events_ = __webpack_require__(2361); // EXTERNAL MODULE: external "util" var external_util_ = __webpack_require__(3837); // EXTERNAL MODULE: ./node_modules/defer-to-connect/dist/source/index.js var source = __webpack_require__(6214); ;// CONCATENATED MODULE: ./node_modules/@szmarczak/http-timer/dist/source/index.js const timer = (request) => { if (request.timings) { return request.timings; } const timings = { start: Date.now(), socket: undefined, lookup: undefined, connect: undefined, secureConnect: undefined, upload: undefined, response: undefined, end: undefined, error: undefined, abort: undefined, phases: { wait: undefined, dns: undefined, tcp: undefined, tls: undefined, request: undefined, firstByte: undefined, download: undefined, total: undefined, }, }; request.timings = timings; const handleError = (origin) => { origin.once(external_events_.errorMonitor, () => { timings.error = Date.now(); timings.phases.total = timings.error - timings.start; }); }; handleError(request); const onAbort = () => { timings.abort = Date.now(); timings.phases.total = timings.abort - timings.start; }; request.prependOnceListener('abort', onAbort); const onSocket = (socket) => { timings.socket = Date.now(); timings.phases.wait = timings.socket - timings.start; if (external_util_.types.isProxy(socket)) { return; } const lookupListener = () => { timings.lookup = Date.now(); timings.phases.dns = timings.lookup - timings.socket; }; socket.prependOnceListener('lookup', lookupListener); source(socket, { connect: () => { timings.connect = Date.now(); if (timings.lookup === undefined) { socket.removeListener('lookup', lookupListener); timings.lookup = timings.connect; timings.phases.dns = timings.lookup - timings.socket; } timings.phases.tcp = timings.connect - timings.lookup; }, secureConnect: () => { timings.secureConnect = Date.now(); timings.phases.tls = timings.secureConnect - timings.connect; }, }); }; if (request.socket) { onSocket(request.socket); } else { request.prependOnceListener('socket', onSocket); } const onUpload = () => { timings.upload = Date.now(); timings.phases.request = timings.upload - (timings.secureConnect ?? timings.connect); }; if (request.writableFinished) { onUpload(); } else { request.prependOnceListener('finish', onUpload); } request.prependOnceListener('response', (response) => { timings.response = Date.now(); timings.phases.firstByte = timings.response - timings.upload; response.timings = timings; handleError(response); response.prependOnceListener('end', () => { request.off('abort', onAbort); response.off('aborted', onAbort); if (timings.phases.total) { // Aborted or errored return; } timings.end = Date.now(); timings.phases.download = timings.end - timings.response; timings.phases.total = timings.end - timings.start; }); response.prependOnceListener('aborted', onAbort); }); return timings; }; /* harmony default export */ const dist_source = (timer); // EXTERNAL MODULE: external "node:crypto" var external_node_crypto_ = __webpack_require__(6005); ;// CONCATENATED MODULE: ./node_modules/normalize-url/index.js // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain'; const DATA_URL_DEFAULT_CHARSET = 'us-ascii'; const testParameter = (name, filters) => filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name); const normalizeDataURL = (urlString, {stripHash}) => { const match = /^data:(?[^,]*?),(?[^#]*?)(?:#(?.*))?$/.exec(urlString); if (!match) { throw new Error(`Invalid URL: ${urlString}`); } let {type, data, hash} = match.groups; const mediaType = type.split(';'); hash = stripHash ? '' : hash; let isBase64 = false; if (mediaType[mediaType.length - 1] === 'base64') { mediaType.pop(); isBase64 = true; } // Lowercase MIME type const mimeType = (mediaType.shift() || '').toLowerCase(); const attributes = mediaType .map(attribute => { let [key, value = ''] = attribute.split('=').map(string => string.trim()); // Lowercase `charset` if (key === 'charset') { value = value.toLowerCase(); if (value === DATA_URL_DEFAULT_CHARSET) { return ''; } } return `${key}${value ? `=${value}` : ''}`; }) .filter(Boolean); const normalizedMediaType = [ ...attributes, ]; if (isBase64) { normalizedMediaType.push('base64'); } if (normalizedMediaType.length > 0 || (mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE)) { normalizedMediaType.unshift(mimeType); } return `data:${normalizedMediaType.join(';')},${isBase64 ? data.trim() : data}${hash ? `#${hash}` : ''}`; }; function normalizeUrl(urlString, options) { options = { defaultProtocol: 'http:', normalizeProtocol: true, forceHttp: false, forceHttps: false, stripAuthentication: true, stripHash: false, stripTextFragment: true, stripWWW: true, removeQueryParameters: [/^utm_\w+/i], removeTrailingSlash: true, removeSingleSlash: true, removeDirectoryIndex: false, removeExplicitPort: false, sortQueryParameters: true, ...options, }; urlString = urlString.trim(); // Data URL if (/^data:/i.test(urlString)) { return normalizeDataURL(urlString, options); } if (/^view-source:/i.test(urlString)) { throw new Error('`view-source:` is not supported as it is a non-standard protocol'); } const hasRelativeProtocol = urlString.startsWith('//'); const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString); // Prepend protocol if (!isRelativeUrl) { urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol); } const urlObject = new URL(urlString); if (options.forceHttp && options.forceHttps) { throw new Error('The `forceHttp` and `forceHttps` options cannot be used together'); } if (options.forceHttp && urlObject.protocol === 'https:') { urlObject.protocol = 'http:'; } if (options.forceHttps && urlObject.protocol === 'http:') { urlObject.protocol = 'https:'; } // Remove auth if (options.stripAuthentication) { urlObject.username = ''; urlObject.password = ''; } // Remove hash if (options.stripHash) { urlObject.hash = ''; } else if (options.stripTextFragment) { urlObject.hash = urlObject.hash.replace(/#?:~:text.*?$/i, ''); } // Remove duplicate slashes if not preceded by a protocol // NOTE: This could be implemented using a single negative lookbehind // regex, but we avoid that to maintain compatibility with older js engines // which do not have support for that feature. if (urlObject.pathname) { // TODO: Replace everything below with `urlObject.pathname = urlObject.pathname.replace(/(? 0) { let pathComponents = urlObject.pathname.split('/'); const lastComponent = pathComponents[pathComponents.length - 1]; if (testParameter(lastComponent, options.removeDirectoryIndex)) { pathComponents = pathComponents.slice(0, -1); urlObject.pathname = pathComponents.slice(1).join('/') + '/'; } } if (urlObject.hostname) { // Remove trailing dot urlObject.hostname = urlObject.hostname.replace(/\.$/, ''); // Remove `www.` if (options.stripWWW && /^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(urlObject.hostname)) { // Each label should be max 63 at length (min: 1). // Source: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names // Each TLD should be up to 63 characters long (min: 2). // It is technically possible to have a single character TLD, but none currently exist. urlObject.hostname = urlObject.hostname.replace(/^www\./, ''); } } // Remove query unwanted parameters if (Array.isArray(options.removeQueryParameters)) { // eslint-disable-next-line unicorn/no-useless-spread -- We are intentionally spreading to get a copy. for (const key of [...urlObject.searchParams.keys()]) { if (testParameter(key, options.removeQueryParameters)) { urlObject.searchParams.delete(key); } } } if (!Array.isArray(options.keepQueryParameters) && options.removeQueryParameters === true) { urlObject.search = ''; } // Keep wanted query parameters if (Array.isArray(options.keepQueryParameters) && options.keepQueryParameters.length > 0) { // eslint-disable-next-line unicorn/no-useless-spread -- We are intentionally spreading to get a copy. for (const key of [...urlObject.searchParams.keys()]) { if (!testParameter(key, options.keepQueryParameters)) { urlObject.searchParams.delete(key); } } } // Sort query parameters if (options.sortQueryParameters) { urlObject.searchParams.sort(); // Calling `.sort()` encodes the search parameters, so we need to decode them again. try { urlObject.search = decodeURIComponent(urlObject.search); } catch {} } if (options.removeTrailingSlash) { urlObject.pathname = urlObject.pathname.replace(/\/$/, ''); } // Remove an explicit port number, excluding a default port number, if applicable if (options.removeExplicitPort && urlObject.port) { urlObject.port = ''; } const oldUrlString = urlString; // Take advantage of many of the Node `url` normalizations urlString = urlObject.toString(); if (!options.removeSingleSlash && urlObject.pathname === '/' && !oldUrlString.endsWith('/') && urlObject.hash === '') { urlString = urlString.replace(/\/$/, ''); } // Remove ending `/` unless removeSingleSlash is false if ((options.removeTrailingSlash || urlObject.pathname === '/') && urlObject.hash === '' && options.removeSingleSlash) { urlString = urlString.replace(/\/$/, ''); } // Restore relative protocol, if applicable if (hasRelativeProtocol && !options.normalizeProtocol) { urlString = urlString.replace(/^http:\/\//, '//'); } // Remove http/https if (options.stripProtocol) { urlString = urlString.replace(/^(?:https?:)?\/\//, ''); } return urlString; } // EXTERNAL MODULE: ./node_modules/cacheable-request/node_modules/get-stream/index.js var get_stream = __webpack_require__(7040); // EXTERNAL MODULE: ./node_modules/http-cache-semantics/index.js var http_cache_semantics = __webpack_require__(1002); ;// CONCATENATED MODULE: ./node_modules/lowercase-keys/index.js function lowercaseKeys(object) { return Object.fromEntries(Object.entries(object).map(([key, value]) => [key.toLowerCase(), value])); } ;// CONCATENATED MODULE: ./node_modules/responselike/index.js class Response extends external_node_stream_.Readable { statusCode; headers; body; url; constructor({statusCode, headers, body, url}) { if (typeof statusCode !== 'number') { throw new TypeError('Argument `statusCode` should be a number'); } if (typeof headers !== 'object') { throw new TypeError('Argument `headers` should be an object'); } if (!(body instanceof Uint8Array)) { throw new TypeError('Argument `body` should be a buffer'); } if (typeof url !== 'string') { throw new TypeError('Argument `url` should be a string'); } super({ read() { this.push(body); this.push(null); }, }); this.statusCode = statusCode; this.headers = lowercaseKeys(headers); this.body = body; this.url = url; } } // EXTERNAL MODULE: ./node_modules/keyv/src/index.js var src = __webpack_require__(1531); ;// CONCATENATED MODULE: ./node_modules/mimic-response/index.js // We define these manually to ensure they're always copied // even if they would move up the prototype chain // https://nodejs.org/api/http.html#http_class_http_incomingmessage const knownProperties = [ 'aborted', 'complete', 'headers', 'httpVersion', 'httpVersionMinor', 'httpVersionMajor', 'method', 'rawHeaders', 'rawTrailers', 'setTimeout', 'socket', 'statusCode', 'statusMessage', 'trailers', 'url', ]; function mimicResponse(fromStream, toStream) { if (toStream._readableState.autoDestroy) { throw new Error('The second stream must have the `autoDestroy` option set to `false`'); } const fromProperties = new Set([...Object.keys(fromStream), ...knownProperties]); const properties = {}; for (const property of fromProperties) { // Don't overwrite existing properties. if (property in toStream) { continue; } properties[property] = { get() { const value = fromStream[property]; const isFunction = typeof value === 'function'; return isFunction ? value.bind(fromStream) : value; }, set(value) { fromStream[property] = value; }, enumerable: true, configurable: false, }; } Object.defineProperties(toStream, properties); fromStream.once('aborted', () => { toStream.destroy(); toStream.emit('aborted'); }); fromStream.once('close', () => { if (fromStream.complete) { if (toStream.readable) { toStream.once('end', () => { toStream.emit('close'); }); } else { toStream.emit('close'); } } else { toStream.emit('close'); } }); return toStream; } ;// CONCATENATED MODULE: ./node_modules/cacheable-request/dist/types.js // Type definitions for cacheable-request 6.0 // Project: https://github.com/lukechilds/cacheable-request#readme // Definitions by: BendingBender // Paul Melnikow // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 class types_RequestError extends Error { constructor(error) { super(error.message); Object.assign(this, error); } } class types_CacheError extends Error { constructor(error) { super(error.message); Object.assign(this, error); } } //# sourceMappingURL=types.js.map ;// CONCATENATED MODULE: ./node_modules/cacheable-request/dist/index.js class CacheableRequest { constructor(cacheRequest, cacheAdapter) { this.hooks = new Map(); this.request = () => (options, cb) => { let url; if (typeof options === 'string') { url = normalizeUrlObject(external_node_url_.parse(options)); options = {}; } else if (options instanceof external_node_url_.URL) { url = normalizeUrlObject(external_node_url_.parse(options.toString())); options = {}; } else { const [pathname, ...searchParts] = (options.path ?? '').split('?'); const search = searchParts.length > 0 ? `?${searchParts.join('?')}` : ''; url = normalizeUrlObject({ ...options, pathname, search }); } options = { headers: {}, method: 'GET', cache: true, strictTtl: false, automaticFailover: false, ...options, ...urlObjectToRequestOptions(url), }; options.headers = Object.fromEntries(entries(options.headers).map(([key, value]) => [key.toLowerCase(), value])); const ee = new external_node_events_(); const normalizedUrlString = normalizeUrl(external_node_url_.format(url), { stripWWW: false, removeTrailingSlash: false, stripAuthentication: false, }); let key = `${options.method}:${normalizedUrlString}`; // POST, PATCH, and PUT requests may be cached, depending on the response // cache-control headers. As a result, the body of the request should be // added to the cache key in order to avoid collisions. if (options.body && options.method !== undefined && ['POST', 'PATCH', 'PUT'].includes(options.method)) { if (options.body instanceof external_node_stream_.Readable) { // Streamed bodies should completely skip the cache because they may // or may not be hashable and in either case the stream would need to // close before the cache key could be generated. options.cache = false; } else { key += `:${external_node_crypto_.createHash('md5').update(options.body).digest('hex')}`; } } let revalidate = false; let madeRequest = false; const makeRequest = (options_) => { madeRequest = true; let requestErrored = false; let requestErrorCallback = () => { }; const requestErrorPromise = new Promise(resolve => { requestErrorCallback = () => { if (!requestErrored) { requestErrored = true; resolve(); } }; }); const handler = async (response) => { if (revalidate) { response.status = response.statusCode; const revalidatedPolicy = http_cache_semantics.fromObject(revalidate.cachePolicy).revalidatedPolicy(options_, response); if (!revalidatedPolicy.modified) { response.resume(); await new Promise(resolve => { // Skipping 'error' handler cause 'error' event should't be emitted for 304 response response .once('end', resolve); }); const headers = convertHeaders(revalidatedPolicy.policy.responseHeaders()); response = new Response({ statusCode: revalidate.statusCode, headers, body: revalidate.body, url: revalidate.url }); response.cachePolicy = revalidatedPolicy.policy; response.fromCache = true; } } if (!response.fromCache) { response.cachePolicy = new http_cache_semantics(options_, response, options_); response.fromCache = false; } let clonedResponse; if (options_.cache && response.cachePolicy.storable()) { clonedResponse = cloneResponse(response); (async () => { try { const bodyPromise = get_stream.buffer(response); await Promise.race([ requestErrorPromise, new Promise(resolve => response.once('end', resolve)), // eslint-disable-line no-promise-executor-return ]); const body = await bodyPromise; let value = { url: response.url, statusCode: response.fromCache ? revalidate.statusCode : response.statusCode, body, cachePolicy: response.cachePolicy.toObject(), }; let ttl = options_.strictTtl ? response.cachePolicy.timeToLive() : undefined; if (options_.maxTtl) { ttl = ttl ? Math.min(ttl, options_.maxTtl) : options_.maxTtl; } if (this.hooks.size > 0) { /* eslint-disable no-await-in-loop */ for (const key_ of this.hooks.keys()) { value = await this.runHook(key_, value, response); } /* eslint-enable no-await-in-loop */ } await this.cache.set(key, value, ttl); } catch (error) { ee.emit('error', new types_CacheError(error)); } })(); } else if (options_.cache && revalidate) { (async () => { try { await this.cache.delete(key); } catch (error) { ee.emit('error', new types_CacheError(error)); } })(); } ee.emit('response', clonedResponse ?? response); if (typeof cb === 'function') { cb(clonedResponse ?? response); } }; try { const request_ = this.cacheRequest(options_, handler); request_.once('error', requestErrorCallback); request_.once('abort', requestErrorCallback); ee.emit('request', request_); } catch (error) { ee.emit('error', new types_RequestError(error)); } }; (async () => { const get = async (options_) => { await Promise.resolve(); const cacheEntry = options_.cache ? await this.cache.get(key) : undefined; if (typeof cacheEntry === 'undefined' && !options_.forceRefresh) { makeRequest(options_); return; } const policy = http_cache_semantics.fromObject(cacheEntry.cachePolicy); if (policy.satisfiesWithoutRevalidation(options_) && !options_.forceRefresh) { const headers = convertHeaders(policy.responseHeaders()); const response = new Response({ statusCode: cacheEntry.statusCode, headers, body: cacheEntry.body, url: cacheEntry.url }); response.cachePolicy = policy; response.fromCache = true; ee.emit('response', response); if (typeof cb === 'function') { cb(response); } } else if (policy.satisfiesWithoutRevalidation(options_) && Date.now() >= policy.timeToLive() && options_.forceRefresh) { await this.cache.delete(key); options_.headers = policy.revalidationHeaders(options_); makeRequest(options_); } else { revalidate = cacheEntry; options_.headers = policy.revalidationHeaders(options_); makeRequest(options_); } }; const errorHandler = (error) => ee.emit('error', new types_CacheError(error)); if (this.cache instanceof src) { const cachek = this.cache; cachek.once('error', errorHandler); ee.on('error', () => cachek.removeListener('error', errorHandler)); } try { await get(options); } catch (error) { if (options.automaticFailover && !madeRequest) { makeRequest(options); } ee.emit('error', new types_CacheError(error)); } })(); return ee; }; this.addHook = (name, fn) => { if (!this.hooks.has(name)) { this.hooks.set(name, fn); } }; this.removeHook = (name) => this.hooks.delete(name); this.getHook = (name) => this.hooks.get(name); this.runHook = async (name, ...args) => this.hooks.get(name)?.(...args); if (cacheAdapter instanceof src) { this.cache = cacheAdapter; } else if (typeof cacheAdapter === 'string') { this.cache = new src({ uri: cacheAdapter, namespace: 'cacheable-request', }); } else { this.cache = new src({ store: cacheAdapter, namespace: 'cacheable-request', }); } this.request = this.request.bind(this); this.cacheRequest = cacheRequest; } } const entries = Object.entries; const cloneResponse = (response) => { const clone = new external_node_stream_.PassThrough({ autoDestroy: false }); mimicResponse(response, clone); return response.pipe(clone); }; const urlObjectToRequestOptions = (url) => { const options = { ...url }; options.path = `${url.pathname || '/'}${url.search || ''}`; delete options.pathname; delete options.search; return options; }; const normalizeUrlObject = (url) => // If url was parsed by url.parse or new URL: // - hostname will be set // - host will be hostname[:port] // - port will be set if it was explicit in the parsed string // Otherwise, url was from request options: // - hostname or host may be set // - host shall not have port encoded ({ protocol: url.protocol, auth: url.auth, hostname: url.hostname || url.host || 'localhost', port: url.port, pathname: url.pathname, search: url.search, }); const convertHeaders = (headers) => { const result = []; for (const name of Object.keys(headers)) { result[name.toLowerCase()] = headers[name]; } return result; }; /* harmony default export */ const cacheable_request_dist = (CacheableRequest); const onResponse = 'onResponse'; //# sourceMappingURL=index.js.map // EXTERNAL MODULE: ./node_modules/decompress-response/index.js var decompress_response = __webpack_require__(2391); // EXTERNAL MODULE: ./node_modules/got/node_modules/get-stream/index.js var node_modules_get_stream = __webpack_require__(6741); ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/isFunction.js const isFunction = (value) => (typeof value === "function"); ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/isFormData.js const isFormData = (value) => Boolean(value && isFunction(value.constructor) && value[Symbol.toStringTag] === "FormData" && isFunction(value.append) && isFunction(value.getAll) && isFunction(value.entries) && isFunction(value[Symbol.iterator])); ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/createBoundary.js const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"; function createBoundary() { let size = 16; let res = ""; while (size--) { res += alphabet[(Math.random() * alphabet.length) << 0]; } return res; } ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/normalizeValue.js const normalizeValue = (value) => String(value) .replace(/\r|\n/g, (match, i, str) => { if ((match === "\r" && str[i + 1] !== "\n") || (match === "\n" && str[i - 1] !== "\r")) { return "\r\n"; } return match; }); ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/isPlainObject.js const getType = (value) => (Object.prototype.toString.call(value).slice(8, -1).toLowerCase()); function isPlainObject(value) { if (getType(value) !== "object") { return false; } const pp = Object.getPrototypeOf(value); if (pp === null || pp === undefined) { return true; } const Ctor = pp.constructor && pp.constructor.toString(); return Ctor === Object.toString(); } ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/proxyHeaders.js function getProperty(target, prop) { if (typeof prop === "string") { for (const [name, value] of Object.entries(target)) { if (prop.toLowerCase() === name.toLowerCase()) { return value; } } } return undefined; } const proxyHeaders = (object) => new Proxy(object, { get: (target, prop) => getProperty(target, prop), has: (target, prop) => getProperty(target, prop) !== undefined }); ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/escapeName.js const escapeName = (name) => String(name) .replace(/\r/g, "%0D") .replace(/\n/g, "%0A") .replace(/"/g, "%22"); ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/util/isFile.js const isFile = (value) => Boolean(value && typeof value === "object" && isFunction(value.constructor) && value[Symbol.toStringTag] === "File" && isFunction(value.stream) && value.name != null); const isFileLike = (/* unused pure expression or super */ null && (isFile)); ;// CONCATENATED MODULE: ./node_modules/form-data-encoder/lib/FormDataEncoder.js var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _FormDataEncoder_instances, _FormDataEncoder_CRLF, _FormDataEncoder_CRLF_BYTES, _FormDataEncoder_CRLF_BYTES_LENGTH, _FormDataEncoder_DASHES, _FormDataEncoder_encoder, _FormDataEncoder_footer, _FormDataEncoder_form, _FormDataEncoder_options, _FormDataEncoder_getFieldHeader, _FormDataEncoder_getContentLength; const defaultOptions = { enableAdditionalHeaders: false }; const readonlyProp = { writable: false, configurable: false }; class FormDataEncoder { constructor(form, boundaryOrOptions, options) { _FormDataEncoder_instances.add(this); _FormDataEncoder_CRLF.set(this, "\r\n"); _FormDataEncoder_CRLF_BYTES.set(this, void 0); _FormDataEncoder_CRLF_BYTES_LENGTH.set(this, void 0); _FormDataEncoder_DASHES.set(this, "-".repeat(2)); _FormDataEncoder_encoder.set(this, new TextEncoder()); _FormDataEncoder_footer.set(this, void 0); _FormDataEncoder_form.set(this, void 0); _FormDataEncoder_options.set(this, void 0); if (!isFormData(form)) { throw new TypeError("Expected first argument to be a FormData instance."); } let boundary; if (isPlainObject(boundaryOrOptions)) { options = boundaryOrOptions; } else { boundary = boundaryOrOptions; } if (!boundary) { boundary = createBoundary(); } if (typeof boundary !== "string") { throw new TypeError("Expected boundary argument to be a string."); } if (options && !isPlainObject(options)) { throw new TypeError("Expected options argument to be an object."); } __classPrivateFieldSet(this, _FormDataEncoder_form, Array.from(form.entries()), "f"); __classPrivateFieldSet(this, _FormDataEncoder_options, { ...defaultOptions, ...options }, "f"); __classPrivateFieldSet(this, _FormDataEncoder_CRLF_BYTES, __classPrivateFieldGet(this, _FormDataEncoder_encoder, "f").encode(__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f")), "f"); __classPrivateFieldSet(this, _FormDataEncoder_CRLF_BYTES_LENGTH, __classPrivateFieldGet(this, _FormDataEncoder_CRLF_BYTES, "f").byteLength, "f"); this.boundary = `form-data-boundary-${boundary}`; this.contentType = `multipart/form-data; boundary=${this.boundary}`; __classPrivateFieldSet(this, _FormDataEncoder_footer, __classPrivateFieldGet(this, _FormDataEncoder_encoder, "f").encode(`${__classPrivateFieldGet(this, _FormDataEncoder_DASHES, "f")}${this.boundary}${__classPrivateFieldGet(this, _FormDataEncoder_DASHES, "f")}${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f").repeat(2)}`), "f"); const headers = { "Content-Type": this.contentType }; const contentLength = __classPrivateFieldGet(this, _FormDataEncoder_instances, "m", _FormDataEncoder_getContentLength).call(this); if (contentLength) { this.contentLength = contentLength; headers["Content-Length"] = contentLength; } this.headers = proxyHeaders(Object.freeze(headers)); Object.defineProperties(this, { boundary: readonlyProp, contentType: readonlyProp, contentLength: readonlyProp, headers: readonlyProp }); } getContentLength() { return this.contentLength == null ? undefined : Number(this.contentLength); } *values() { for (const [name, raw] of __classPrivateFieldGet(this, _FormDataEncoder_form, "f")) { const value = isFile(raw) ? raw : __classPrivateFieldGet(this, _FormDataEncoder_encoder, "f").encode(normalizeValue(raw)); yield __classPrivateFieldGet(this, _FormDataEncoder_instances, "m", _FormDataEncoder_getFieldHeader).call(this, name, value); yield value; yield __classPrivateFieldGet(this, _FormDataEncoder_CRLF_BYTES, "f"); } yield __classPrivateFieldGet(this, _FormDataEncoder_footer, "f"); } async *encode() { for (const part of this.values()) { if (isFile(part)) { yield* part.stream(); } else { yield part; } } } [(_FormDataEncoder_CRLF = new WeakMap(), _FormDataEncoder_CRLF_BYTES = new WeakMap(), _FormDataEncoder_CRLF_BYTES_LENGTH = new WeakMap(), _FormDataEncoder_DASHES = new WeakMap(), _FormDataEncoder_encoder = new WeakMap(), _FormDataEncoder_footer = new WeakMap(), _FormDataEncoder_form = new WeakMap(), _FormDataEncoder_options = new WeakMap(), _FormDataEncoder_instances = new WeakSet(), _FormDataEncoder_getFieldHeader = function _FormDataEncoder_getFieldHeader(name, value) { let header = ""; header += `${__classPrivateFieldGet(this, _FormDataEncoder_DASHES, "f")}${this.boundary}${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f")}`; header += `Content-Disposition: form-data; name="${escapeName(name)}"`; if (isFile(value)) { header += `; filename="${escapeName(value.name)}"${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f")}`; header += `Content-Type: ${value.type || "application/octet-stream"}`; } const size = isFile(value) ? value.size : value.byteLength; if (__classPrivateFieldGet(this, _FormDataEncoder_options, "f").enableAdditionalHeaders === true && size != null && !isNaN(size)) { header += `${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f")}Content-Length: ${isFile(value) ? value.size : value.byteLength}`; } return __classPrivateFieldGet(this, _FormDataEncoder_encoder, "f").encode(`${header}${__classPrivateFieldGet(this, _FormDataEncoder_CRLF, "f").repeat(2)}`); }, _FormDataEncoder_getContentLength = function _FormDataEncoder_getContentLength() { let length = 0; for (const [name, raw] of __classPrivateFieldGet(this, _FormDataEncoder_form, "f")) { const value = isFile(raw) ? raw : __classPrivateFieldGet(this, _FormDataEncoder_encoder, "f").encode(normalizeValue(raw)); const size = isFile(value) ? value.size : value.byteLength; if (size == null || isNaN(size)) { return undefined; } length += __classPrivateFieldGet(this, _FormDataEncoder_instances, "m", _FormDataEncoder_getFieldHeader).call(this, name, value).byteLength; length += size; length += __classPrivateFieldGet(this, _FormDataEncoder_CRLF_BYTES_LENGTH, "f"); } return String(length + __classPrivateFieldGet(this, _FormDataEncoder_footer, "f").byteLength); }, Symbol.iterator)]() { return this.values(); } [Symbol.asyncIterator]() { return this.encode(); } } // EXTERNAL MODULE: external "node:util" var external_node_util_ = __webpack_require__(7261); ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/is-form-data.js function is_form_data_isFormData(body) { return dist.nodeStream(body) && dist.function_(body.getBoundary); } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/get-body-size.js async function getBodySize(body, headers) { if (headers && 'content-length' in headers) { return Number(headers['content-length']); } if (!body) { return 0; } if (dist.string(body)) { return external_node_buffer_.Buffer.byteLength(body); } if (dist.buffer(body)) { return body.length; } if (is_form_data_isFormData(body)) { return (0,external_node_util_.promisify)(body.getLength.bind(body))(); } return undefined; } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/proxy-events.js function proxyEvents(from, to, events) { const eventFunctions = {}; for (const event of events) { const eventFunction = (...args) => { to.emit(event, ...args); }; eventFunctions[event] = eventFunction; from.on(event, eventFunction); } return () => { for (const [event, eventFunction] of Object.entries(eventFunctions)) { from.off(event, eventFunction); } }; } // EXTERNAL MODULE: external "node:net" var external_node_net_ = __webpack_require__(7503); ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/unhandle.js // When attaching listeners, it's very easy to forget about them. // Especially if you do error handling and set timeouts. // So instead of checking if it's proper to throw an error on every timeout ever, // use this simple tool which will remove all listeners you have attached. function unhandle() { const handlers = []; return { once(origin, event, fn) { origin.once(event, fn); handlers.push({ origin, event, fn }); }, unhandleAll() { for (const handler of handlers) { const { origin, event, fn } = handler; origin.removeListener(event, fn); } handlers.length = 0; }, }; } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/timed-out.js const reentry = Symbol('reentry'); const noop = () => { }; class timed_out_TimeoutError extends Error { constructor(threshold, event) { super(`Timeout awaiting '${event}' for ${threshold}ms`); Object.defineProperty(this, "event", { enumerable: true, configurable: true, writable: true, value: event }); Object.defineProperty(this, "code", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.name = 'TimeoutError'; this.code = 'ETIMEDOUT'; } } function timedOut(request, delays, options) { if (reentry in request) { return noop; } request[reentry] = true; const cancelers = []; const { once, unhandleAll } = unhandle(); const addTimeout = (delay, callback, event) => { const timeout = setTimeout(callback, delay, delay, event); timeout.unref?.(); const cancel = () => { clearTimeout(timeout); }; cancelers.push(cancel); return cancel; }; const { host, hostname } = options; const timeoutHandler = (delay, event) => { request.destroy(new timed_out_TimeoutError(delay, event)); }; const cancelTimeouts = () => { for (const cancel of cancelers) { cancel(); } unhandleAll(); }; request.once('error', error => { cancelTimeouts(); // Save original behavior /* istanbul ignore next */ if (request.listenerCount('error') === 0) { throw error; } }); if (typeof delays.request !== 'undefined') { const cancelTimeout = addTimeout(delays.request, timeoutHandler, 'request'); once(request, 'response', (response) => { once(response, 'end', cancelTimeout); }); } if (typeof delays.socket !== 'undefined') { const { socket } = delays; const socketTimeoutHandler = () => { timeoutHandler(socket, 'socket'); }; request.setTimeout(socket, socketTimeoutHandler); // `request.setTimeout(0)` causes a memory leak. // We can just remove the listener and forget about the timer - it's unreffed. // See https://github.com/sindresorhus/got/issues/690 cancelers.push(() => { request.removeListener('timeout', socketTimeoutHandler); }); } const hasLookup = typeof delays.lookup !== 'undefined'; const hasConnect = typeof delays.connect !== 'undefined'; const hasSecureConnect = typeof delays.secureConnect !== 'undefined'; const hasSend = typeof delays.send !== 'undefined'; if (hasLookup || hasConnect || hasSecureConnect || hasSend) { once(request, 'socket', (socket) => { const { socketPath } = request; /* istanbul ignore next: hard to test */ if (socket.connecting) { const hasPath = Boolean(socketPath ?? external_node_net_.isIP(hostname ?? host ?? '') !== 0); if (hasLookup && !hasPath && typeof socket.address().address === 'undefined') { const cancelTimeout = addTimeout(delays.lookup, timeoutHandler, 'lookup'); once(socket, 'lookup', cancelTimeout); } if (hasConnect) { const timeConnect = () => addTimeout(delays.connect, timeoutHandler, 'connect'); if (hasPath) { once(socket, 'connect', timeConnect()); } else { once(socket, 'lookup', (error) => { if (error === null) { once(socket, 'connect', timeConnect()); } }); } } if (hasSecureConnect && options.protocol === 'https:') { once(socket, 'connect', () => { const cancelTimeout = addTimeout(delays.secureConnect, timeoutHandler, 'secureConnect'); once(socket, 'secureConnect', cancelTimeout); }); } } if (hasSend) { const timeRequest = () => addTimeout(delays.send, timeoutHandler, 'send'); /* istanbul ignore next: hard to test */ if (socket.connecting) { once(socket, 'connect', () => { once(request, 'upload-complete', timeRequest()); }); } else { once(request, 'upload-complete', timeRequest()); } } }); } if (typeof delays.response !== 'undefined') { once(request, 'upload-complete', () => { const cancelTimeout = addTimeout(delays.response, timeoutHandler, 'response'); once(request, 'response', cancelTimeout); }); } if (typeof delays.read !== 'undefined') { once(request, 'response', (response) => { const cancelTimeout = addTimeout(delays.read, timeoutHandler, 'read'); once(response, 'end', cancelTimeout); }); } return cancelTimeouts; } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/url-to-options.js function urlToOptions(url) { // Cast to URL url = url; const options = { protocol: url.protocol, hostname: dist.string(url.hostname) && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname, host: url.host, hash: url.hash, search: url.search, pathname: url.pathname, href: url.href, path: `${url.pathname || ''}${url.search || ''}`, }; if (dist.string(url.port) && url.port.length > 0) { options.port = Number(url.port); } if (url.username || url.password) { options.auth = `${url.username || ''}:${url.password || ''}`; } return options; } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/weakable-map.js class WeakableMap { constructor() { Object.defineProperty(this, "weakMap", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "map", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.weakMap = new WeakMap(); this.map = new Map(); } set(key, value) { if (typeof key === 'object') { this.weakMap.set(key, value); } else { this.map.set(key, value); } } get(key) { if (typeof key === 'object') { return this.weakMap.get(key); } return this.map.get(key); } has(key) { if (typeof key === 'object') { return this.weakMap.has(key); } return this.map.has(key); } } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/calculate-retry-delay.js const calculateRetryDelay = ({ attemptCount, retryOptions, error, retryAfter, computedValue, }) => { if (error.name === 'RetryError') { return 1; } if (attemptCount > retryOptions.limit) { return 0; } const hasMethod = retryOptions.methods.includes(error.options.method); const hasErrorCode = retryOptions.errorCodes.includes(error.code); const hasStatusCode = error.response && retryOptions.statusCodes.includes(error.response.statusCode); if (!hasMethod || (!hasErrorCode && !hasStatusCode)) { return 0; } if (error.response) { if (retryAfter) { // In this case `computedValue` is `options.request.timeout` if (retryAfter > computedValue) { return 0; } return retryAfter; } if (error.response.statusCode === 413) { return 0; } } const noise = Math.random() * retryOptions.noise; return Math.min(((2 ** (attemptCount - 1)) * 1000), retryOptions.backoffLimit) + noise; }; /* harmony default export */ const calculate_retry_delay = (calculateRetryDelay); // EXTERNAL MODULE: external "node:tls" var external_node_tls_ = __webpack_require__(1764); // EXTERNAL MODULE: external "node:https" var external_node_https_ = __webpack_require__(2286); // EXTERNAL MODULE: external "node:dns" var external_node_dns_ = __webpack_require__(604); // EXTERNAL MODULE: external "node:os" var external_node_os_ = __webpack_require__(612); ;// CONCATENATED MODULE: ./node_modules/cacheable-lookup/source/index.js const {Resolver: AsyncResolver} = external_node_dns_.promises; const kCacheableLookupCreateConnection = Symbol('cacheableLookupCreateConnection'); const kCacheableLookupInstance = Symbol('cacheableLookupInstance'); const kExpires = Symbol('expires'); const supportsALL = typeof external_node_dns_.ALL === 'number'; const verifyAgent = agent => { if (!(agent && typeof agent.createConnection === 'function')) { throw new Error('Expected an Agent instance as the first argument'); } }; const map4to6 = entries => { for (const entry of entries) { if (entry.family === 6) { continue; } entry.address = `::ffff:${entry.address}`; entry.family = 6; } }; const getIfaceInfo = () => { let has4 = false; let has6 = false; for (const device of Object.values(external_node_os_.networkInterfaces())) { for (const iface of device) { if (iface.internal) { continue; } if (iface.family === 'IPv6') { has6 = true; } else { has4 = true; } if (has4 && has6) { return {has4, has6}; } } } return {has4, has6}; }; const isIterable = map => { return Symbol.iterator in map; }; const ignoreNoResultErrors = dnsPromise => { return dnsPromise.catch(error => { if ( error.code === 'ENODATA' || error.code === 'ENOTFOUND' || error.code === 'ENOENT' // Windows: name exists, but not this record type ) { return []; } throw error; }); }; const ttl = {ttl: true}; const source_all = {all: true}; const all4 = {all: true, family: 4}; const all6 = {all: true, family: 6}; class CacheableLookup { constructor({ cache = new Map(), maxTtl = Infinity, fallbackDuration = 3600, errorTtl = 0.15, resolver = new AsyncResolver(), lookup = external_node_dns_.lookup } = {}) { this.maxTtl = maxTtl; this.errorTtl = errorTtl; this._cache = cache; this._resolver = resolver; this._dnsLookup = lookup && (0,external_node_util_.promisify)(lookup); this.stats = { cache: 0, query: 0 }; if (this._resolver instanceof AsyncResolver) { this._resolve4 = this._resolver.resolve4.bind(this._resolver); this._resolve6 = this._resolver.resolve6.bind(this._resolver); } else { this._resolve4 = (0,external_node_util_.promisify)(this._resolver.resolve4.bind(this._resolver)); this._resolve6 = (0,external_node_util_.promisify)(this._resolver.resolve6.bind(this._resolver)); } this._iface = getIfaceInfo(); this._pending = {}; this._nextRemovalTime = false; this._hostnamesToFallback = new Set(); this.fallbackDuration = fallbackDuration; if (fallbackDuration > 0) { const interval = setInterval(() => { this._hostnamesToFallback.clear(); }, fallbackDuration * 1000); /* istanbul ignore next: There is no `interval.unref()` when running inside an Electron renderer */ if (interval.unref) { interval.unref(); } this._fallbackInterval = interval; } this.lookup = this.lookup.bind(this); this.lookupAsync = this.lookupAsync.bind(this); } set servers(servers) { this.clear(); this._resolver.setServers(servers); } get servers() { return this._resolver.getServers(); } lookup(hostname, options, callback) { if (typeof options === 'function') { callback = options; options = {}; } else if (typeof options === 'number') { options = { family: options }; } if (!callback) { throw new Error('Callback must be a function.'); } // eslint-disable-next-line promise/prefer-await-to-then this.lookupAsync(hostname, options).then(result => { if (options.all) { callback(null, result); } else { callback(null, result.address, result.family, result.expires, result.ttl, result.source); } }, callback); } async lookupAsync(hostname, options = {}) { if (typeof options === 'number') { options = { family: options }; } let cached = await this.query(hostname); if (options.family === 6) { const filtered = cached.filter(entry => entry.family === 6); if (options.hints & external_node_dns_.V4MAPPED) { if ((supportsALL && options.hints & external_node_dns_.ALL) || filtered.length === 0) { map4to6(cached); } else { cached = filtered; } } else { cached = filtered; } } else if (options.family === 4) { cached = cached.filter(entry => entry.family === 4); } if (options.hints & external_node_dns_.ADDRCONFIG) { const {_iface} = this; cached = cached.filter(entry => entry.family === 6 ? _iface.has6 : _iface.has4); } if (cached.length === 0) { const error = new Error(`cacheableLookup ENOTFOUND ${hostname}`); error.code = 'ENOTFOUND'; error.hostname = hostname; throw error; } if (options.all) { return cached; } return cached[0]; } async query(hostname) { let source = 'cache'; let cached = await this._cache.get(hostname); if (cached) { this.stats.cache++; } if (!cached) { const pending = this._pending[hostname]; if (pending) { this.stats.cache++; cached = await pending; } else { source = 'query'; const newPromise = this.queryAndCache(hostname); this._pending[hostname] = newPromise; this.stats.query++; try { cached = await newPromise; } finally { delete this._pending[hostname]; } } } cached = cached.map(entry => { return {...entry, source}; }); return cached; } async _resolve(hostname) { // ANY is unsafe as it doesn't trigger new queries in the underlying server. const [A, AAAA] = await Promise.all([ ignoreNoResultErrors(this._resolve4(hostname, ttl)), ignoreNoResultErrors(this._resolve6(hostname, ttl)) ]); let aTtl = 0; let aaaaTtl = 0; let cacheTtl = 0; const now = Date.now(); for (const entry of A) { entry.family = 4; entry.expires = now + (entry.ttl * 1000); aTtl = Math.max(aTtl, entry.ttl); } for (const entry of AAAA) { entry.family = 6; entry.expires = now + (entry.ttl * 1000); aaaaTtl = Math.max(aaaaTtl, entry.ttl); } if (A.length > 0) { if (AAAA.length > 0) { cacheTtl = Math.min(aTtl, aaaaTtl); } else { cacheTtl = aTtl; } } else { cacheTtl = aaaaTtl; } return { entries: [ ...A, ...AAAA ], cacheTtl }; } async _lookup(hostname) { try { const [A, AAAA] = await Promise.all([ // Passing {all: true} doesn't return all IPv4 and IPv6 entries. // See https://github.com/szmarczak/cacheable-lookup/issues/42 ignoreNoResultErrors(this._dnsLookup(hostname, all4)), ignoreNoResultErrors(this._dnsLookup(hostname, all6)) ]); return { entries: [ ...A, ...AAAA ], cacheTtl: 0 }; } catch { return { entries: [], cacheTtl: 0 }; } } async _set(hostname, data, cacheTtl) { if (this.maxTtl > 0 && cacheTtl > 0) { cacheTtl = Math.min(cacheTtl, this.maxTtl) * 1000; data[kExpires] = Date.now() + cacheTtl; try { await this._cache.set(hostname, data, cacheTtl); } catch (error) { this.lookupAsync = async () => { const cacheError = new Error('Cache Error. Please recreate the CacheableLookup instance.'); cacheError.cause = error; throw cacheError; }; } if (isIterable(this._cache)) { this._tick(cacheTtl); } } } async queryAndCache(hostname) { if (this._hostnamesToFallback.has(hostname)) { return this._dnsLookup(hostname, source_all); } let query = await this._resolve(hostname); if (query.entries.length === 0 && this._dnsLookup) { query = await this._lookup(hostname); if (query.entries.length !== 0 && this.fallbackDuration > 0) { // Use `dns.lookup(...)` for that particular hostname this._hostnamesToFallback.add(hostname); } } const cacheTtl = query.entries.length === 0 ? this.errorTtl : query.cacheTtl; await this._set(hostname, query.entries, cacheTtl); return query.entries; } _tick(ms) { const nextRemovalTime = this._nextRemovalTime; if (!nextRemovalTime || ms < nextRemovalTime) { clearTimeout(this._removalTimeout); this._nextRemovalTime = ms; this._removalTimeout = setTimeout(() => { this._nextRemovalTime = false; let nextExpiry = Infinity; const now = Date.now(); for (const [hostname, entries] of this._cache) { const expires = entries[kExpires]; if (now >= expires) { this._cache.delete(hostname); } else if (expires < nextExpiry) { nextExpiry = expires; } } if (nextExpiry !== Infinity) { this._tick(nextExpiry - now); } }, ms); /* istanbul ignore next: There is no `timeout.unref()` when running inside an Electron renderer */ if (this._removalTimeout.unref) { this._removalTimeout.unref(); } } } install(agent) { verifyAgent(agent); if (kCacheableLookupCreateConnection in agent) { throw new Error('CacheableLookup has been already installed'); } agent[kCacheableLookupCreateConnection] = agent.createConnection; agent[kCacheableLookupInstance] = this; agent.createConnection = (options, callback) => { if (!('lookup' in options)) { options.lookup = this.lookup; } return agent[kCacheableLookupCreateConnection](options, callback); }; } uninstall(agent) { verifyAgent(agent); if (agent[kCacheableLookupCreateConnection]) { if (agent[kCacheableLookupInstance] !== this) { throw new Error('The agent is not owned by this CacheableLookup instance'); } agent.createConnection = agent[kCacheableLookupCreateConnection]; delete agent[kCacheableLookupCreateConnection]; delete agent[kCacheableLookupInstance]; } } updateInterfaceInfo() { const {_iface} = this; this._iface = getIfaceInfo(); if ((_iface.has4 && !this._iface.has4) || (_iface.has6 && !this._iface.has6)) { this._cache.clear(); } } clear(hostname) { if (hostname) { this._cache.delete(hostname); return; } this._cache.clear(); } } // EXTERNAL MODULE: ./node_modules/http2-wrapper/source/index.js var http2_wrapper_source = __webpack_require__(4645); ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/parse-link-header.js function parseLinkHeader(link) { const parsed = []; const items = link.split(','); for (const item of items) { // https://tools.ietf.org/html/rfc5988#section-5 const [rawUriReference, ...rawLinkParameters] = item.split(';'); const trimmedUriReference = rawUriReference.trim(); // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with if (trimmedUriReference[0] !== '<' || trimmedUriReference[trimmedUriReference.length - 1] !== '>') { throw new Error(`Invalid format of the Link header reference: ${trimmedUriReference}`); } const reference = trimmedUriReference.slice(1, -1); const parameters = {}; if (rawLinkParameters.length === 0) { throw new Error(`Unexpected end of Link header parameters: ${rawLinkParameters.join(';')}`); } for (const rawParameter of rawLinkParameters) { const trimmedRawParameter = rawParameter.trim(); const center = trimmedRawParameter.indexOf('='); if (center === -1) { throw new Error(`Failed to parse Link header: ${link}`); } const name = trimmedRawParameter.slice(0, center).trim(); const value = trimmedRawParameter.slice(center + 1).trim(); parameters[name] = value; } parsed.push({ reference, parameters, }); } return parsed; } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/options.js // DO NOT use destructuring for `https.request` and `http.request` as it's not compatible with `nock`. const [major, minor] = external_node_process_.versions.node.split('.').map(Number); function validateSearchParameters(searchParameters) { // eslint-disable-next-line guard-for-in for (const key in searchParameters) { const value = searchParameters[key]; assert.any([dist.string, dist.number, dist.boolean, dist.null_, dist.undefined], value); } } const globalCache = new Map(); let globalDnsCache; const getGlobalDnsCache = () => { if (globalDnsCache) { return globalDnsCache; } globalDnsCache = new CacheableLookup(); return globalDnsCache; }; const defaultInternals = { request: undefined, agent: { http: undefined, https: undefined, http2: undefined, }, h2session: undefined, decompress: true, timeout: { connect: undefined, lookup: undefined, read: undefined, request: undefined, response: undefined, secureConnect: undefined, send: undefined, socket: undefined, }, prefixUrl: '', body: undefined, form: undefined, json: undefined, cookieJar: undefined, ignoreInvalidCookies: false, searchParams: undefined, dnsLookup: undefined, dnsCache: undefined, context: {}, hooks: { init: [], beforeRequest: [], beforeError: [], beforeRedirect: [], beforeRetry: [], afterResponse: [], }, followRedirect: true, maxRedirects: 10, cache: undefined, throwHttpErrors: true, username: '', password: '', http2: false, allowGetBody: false, headers: { 'user-agent': 'got (https://github.com/sindresorhus/got)', }, methodRewriting: false, dnsLookupIpVersion: undefined, parseJson: JSON.parse, stringifyJson: JSON.stringify, retry: { limit: 2, methods: [ 'GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE', ], statusCodes: [ 408, 413, 429, 500, 502, 503, 504, 521, 522, 524, ], errorCodes: [ 'ETIMEDOUT', 'ECONNRESET', 'EADDRINUSE', 'ECONNREFUSED', 'EPIPE', 'ENOTFOUND', 'ENETUNREACH', 'EAI_AGAIN', ], maxRetryAfter: undefined, calculateDelay: ({ computedValue }) => computedValue, backoffLimit: Number.POSITIVE_INFINITY, noise: 100, }, localAddress: undefined, method: 'GET', createConnection: undefined, cacheOptions: { shared: undefined, cacheHeuristic: undefined, immutableMinTimeToLive: undefined, ignoreCargoCult: undefined, }, https: { alpnProtocols: undefined, rejectUnauthorized: undefined, checkServerIdentity: undefined, certificateAuthority: undefined, key: undefined, certificate: undefined, passphrase: undefined, pfx: undefined, ciphers: undefined, honorCipherOrder: undefined, minVersion: undefined, maxVersion: undefined, signatureAlgorithms: undefined, tlsSessionLifetime: undefined, dhparam: undefined, ecdhCurve: undefined, certificateRevocationLists: undefined, }, encoding: undefined, resolveBodyOnly: false, isStream: false, responseType: 'text', url: undefined, pagination: { transform(response) { if (response.request.options.responseType === 'json') { return response.body; } return JSON.parse(response.body); }, paginate({ response }) { const rawLinkHeader = response.headers.link; if (typeof rawLinkHeader !== 'string' || rawLinkHeader.trim() === '') { return false; } const parsed = parseLinkHeader(rawLinkHeader); const next = parsed.find(entry => entry.parameters.rel === 'next' || entry.parameters.rel === '"next"'); if (next) { return { url: new external_node_url_.URL(next.reference, response.url), }; } return false; }, filter: () => true, shouldContinue: () => true, countLimit: Number.POSITIVE_INFINITY, backoff: 0, requestLimit: 10000, stackAllItems: false, }, setHost: true, maxHeaderSize: undefined, signal: undefined, enableUnixSockets: true, }; const cloneInternals = (internals) => { const { hooks, retry } = internals; const result = { ...internals, context: { ...internals.context }, cacheOptions: { ...internals.cacheOptions }, https: { ...internals.https }, agent: { ...internals.agent }, headers: { ...internals.headers }, retry: { ...retry, errorCodes: [...retry.errorCodes], methods: [...retry.methods], statusCodes: [...retry.statusCodes], }, timeout: { ...internals.timeout }, hooks: { init: [...hooks.init], beforeRequest: [...hooks.beforeRequest], beforeError: [...hooks.beforeError], beforeRedirect: [...hooks.beforeRedirect], beforeRetry: [...hooks.beforeRetry], afterResponse: [...hooks.afterResponse], }, searchParams: internals.searchParams ? new external_node_url_.URLSearchParams(internals.searchParams) : undefined, pagination: { ...internals.pagination }, }; if (result.url !== undefined) { result.prefixUrl = ''; } return result; }; const cloneRaw = (raw) => { const { hooks, retry } = raw; const result = { ...raw }; if (dist.object(raw.context)) { result.context = { ...raw.context }; } if (dist.object(raw.cacheOptions)) { result.cacheOptions = { ...raw.cacheOptions }; } if (dist.object(raw.https)) { result.https = { ...raw.https }; } if (dist.object(raw.cacheOptions)) { result.cacheOptions = { ...result.cacheOptions }; } if (dist.object(raw.agent)) { result.agent = { ...raw.agent }; } if (dist.object(raw.headers)) { result.headers = { ...raw.headers }; } if (dist.object(retry)) { result.retry = { ...retry }; if (dist.array(retry.errorCodes)) { result.retry.errorCodes = [...retry.errorCodes]; } if (dist.array(retry.methods)) { result.retry.methods = [...retry.methods]; } if (dist.array(retry.statusCodes)) { result.retry.statusCodes = [...retry.statusCodes]; } } if (dist.object(raw.timeout)) { result.timeout = { ...raw.timeout }; } if (dist.object(hooks)) { result.hooks = { ...hooks, }; if (dist.array(hooks.init)) { result.hooks.init = [...hooks.init]; } if (dist.array(hooks.beforeRequest)) { result.hooks.beforeRequest = [...hooks.beforeRequest]; } if (dist.array(hooks.beforeError)) { result.hooks.beforeError = [...hooks.beforeError]; } if (dist.array(hooks.beforeRedirect)) { result.hooks.beforeRedirect = [...hooks.beforeRedirect]; } if (dist.array(hooks.beforeRetry)) { result.hooks.beforeRetry = [...hooks.beforeRetry]; } if (dist.array(hooks.afterResponse)) { result.hooks.afterResponse = [...hooks.afterResponse]; } } // TODO: raw.searchParams if (dist.object(raw.pagination)) { result.pagination = { ...raw.pagination }; } return result; }; const getHttp2TimeoutOption = (internals) => { const delays = [internals.timeout.socket, internals.timeout.connect, internals.timeout.lookup, internals.timeout.request, internals.timeout.secureConnect].filter(delay => typeof delay === 'number'); if (delays.length > 0) { return Math.min(...delays); } return undefined; }; const init = (options, withOptions, self) => { const initHooks = options.hooks?.init; if (initHooks) { for (const hook of initHooks) { hook(withOptions, self); } } }; class Options { constructor(input, options, defaults) { Object.defineProperty(this, "_unixOptions", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_internals", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_merging", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_init", { enumerable: true, configurable: true, writable: true, value: void 0 }); assert.any([dist.string, dist.urlInstance, dist.object, dist.undefined], input); assert.any([dist.object, dist.undefined], options); assert.any([dist.object, dist.undefined], defaults); if (input instanceof Options || options instanceof Options) { throw new TypeError('The defaults must be passed as the third argument'); } this._internals = cloneInternals(defaults?._internals ?? defaults ?? defaultInternals); this._init = [...(defaults?._init ?? [])]; this._merging = false; this._unixOptions = undefined; // This rule allows `finally` to be considered more important. // Meaning no matter the error thrown in the `try` block, // if `finally` throws then the `finally` error will be thrown. // // Yes, we want this. If we set `url` first, then the `url.searchParams` // would get merged. Instead we set the `searchParams` first, then // `url.searchParams` is overwritten as expected. // /* eslint-disable no-unsafe-finally */ try { if (dist.plainObject(input)) { try { this.merge(input); this.merge(options); } finally { this.url = input.url; } } else { try { this.merge(options); } finally { if (options?.url !== undefined) { if (input === undefined) { this.url = options.url; } else { throw new TypeError('The `url` option is mutually exclusive with the `input` argument'); } } else if (input !== undefined) { this.url = input; } } } } catch (error) { error.options = this; throw error; } /* eslint-enable no-unsafe-finally */ } merge(options) { if (!options) { return; } if (options instanceof Options) { for (const init of options._init) { this.merge(init); } return; } options = cloneRaw(options); init(this, options, this); init(options, options, this); this._merging = true; // Always merge `isStream` first if ('isStream' in options) { this.isStream = options.isStream; } try { let push = false; for (const key in options) { // `got.extend()` options if (key === 'mutableDefaults' || key === 'handlers') { continue; } // Never merge `url` if (key === 'url') { continue; } if (!(key in this)) { throw new Error(`Unexpected option: ${key}`); } // @ts-expect-error Type 'unknown' is not assignable to type 'never'. this[key] = options[key]; push = true; } if (push) { this._init.push(options); } } finally { this._merging = false; } } /** Custom request function. The main purpose of this is to [support HTTP2 using a wrapper](https://github.com/szmarczak/http2-wrapper). @default http.request | https.request */ get request() { return this._internals.request; } set request(value) { assert.any([dist.function_, dist.undefined], value); this._internals.request = value; } /** An object representing `http`, `https` and `http2` keys for [`http.Agent`](https://nodejs.org/api/http.html#http_class_http_agent), [`https.Agent`](https://nodejs.org/api/https.html#https_class_https_agent) and [`http2wrapper.Agent`](https://github.com/szmarczak/http2-wrapper#new-http2agentoptions) instance. This is necessary because a request to one protocol might redirect to another. In such a scenario, Got will switch over to the right protocol agent for you. If a key is not present, it will default to a global agent. @example ``` import got from 'got'; import HttpAgent from 'agentkeepalive'; const {HttpsAgent} = HttpAgent; await got('https://sindresorhus.com', { agent: { http: new HttpAgent(), https: new HttpsAgent() } }); ``` */ get agent() { return this._internals.agent; } set agent(value) { assert.plainObject(value); // eslint-disable-next-line guard-for-in for (const key in value) { if (!(key in this._internals.agent)) { throw new TypeError(`Unexpected agent option: ${key}`); } // @ts-expect-error - No idea why `value[key]` doesn't work here. assert.any([dist.object, dist.undefined], value[key]); } if (this._merging) { Object.assign(this._internals.agent, value); } else { this._internals.agent = { ...value }; } } get h2session() { return this._internals.h2session; } set h2session(value) { this._internals.h2session = value; } /** Decompress the response automatically. This will set the `accept-encoding` header to `gzip, deflate, br` unless you set it yourself. If this is disabled, a compressed response is returned as a `Buffer`. This may be useful if you want to handle decompression yourself or stream the raw compressed data. @default true */ get decompress() { return this._internals.decompress; } set decompress(value) { assert.boolean(value); this._internals.decompress = value; } /** Milliseconds to wait for the server to end the response before aborting the request with `got.TimeoutError` error (a.k.a. `request` property). By default, there's no timeout. This also accepts an `object` with the following fields to constrain the duration of each phase of the request lifecycle: - `lookup` starts when a socket is assigned and ends when the hostname has been resolved. Does not apply when using a Unix domain socket. - `connect` starts when `lookup` completes (or when the socket is assigned if lookup does not apply to the request) and ends when the socket is connected. - `secureConnect` starts when `connect` completes and ends when the handshaking process completes (HTTPS only). - `socket` starts when the socket is connected. See [request.setTimeout](https://nodejs.org/api/http.html#http_request_settimeout_timeout_callback). - `response` starts when the request has been written to the socket and ends when the response headers are received. - `send` starts when the socket is connected and ends with the request has been written to the socket. - `request` starts when the request is initiated and ends when the response's end event fires. */ get timeout() { // We always return `Delays` here. // It has to be `Delays | number`, otherwise TypeScript will error because the getter and the setter have incompatible types. return this._internals.timeout; } set timeout(value) { assert.plainObject(value); // eslint-disable-next-line guard-for-in for (const key in value) { if (!(key in this._internals.timeout)) { throw new Error(`Unexpected timeout option: ${key}`); } // @ts-expect-error - No idea why `value[key]` doesn't work here. assert.any([dist.number, dist.undefined], value[key]); } if (this._merging) { Object.assign(this._internals.timeout, value); } else { this._internals.timeout = { ...value }; } } /** When specified, `prefixUrl` will be prepended to `url`. The prefix can be any valid URL, either relative or absolute. A trailing slash `/` is optional - one will be added automatically. __Note__: `prefixUrl` will be ignored if the `url` argument is a URL instance. __Note__: Leading slashes in `input` are disallowed when using this option to enforce consistency and avoid confusion. For example, when the prefix URL is `https://example.com/foo` and the input is `/bar`, there's ambiguity whether the resulting URL would become `https://example.com/foo/bar` or `https://example.com/bar`. The latter is used by browsers. __Tip__: Useful when used with `got.extend()` to create niche-specific Got instances. __Tip__: You can change `prefixUrl` using hooks as long as the URL still includes the `prefixUrl`. If the URL doesn't include it anymore, it will throw. @example ``` import got from 'got'; await got('unicorn', {prefixUrl: 'https://cats.com'}); //=> 'https://cats.com/unicorn' const instance = got.extend({ prefixUrl: 'https://google.com' }); await instance('unicorn', { hooks: { beforeRequest: [ options => { options.prefixUrl = 'https://cats.com'; } ] } }); //=> 'https://cats.com/unicorn' ``` */ get prefixUrl() { // We always return `string` here. // It has to be `string | URL`, otherwise TypeScript will error because the getter and the setter have incompatible types. return this._internals.prefixUrl; } set prefixUrl(value) { assert.any([dist.string, dist.urlInstance], value); if (value === '') { this._internals.prefixUrl = ''; return; } value = value.toString(); if (!value.endsWith('/')) { value += '/'; } if (this._internals.prefixUrl && this._internals.url) { const { href } = this._internals.url; this._internals.url.href = value + href.slice(this._internals.prefixUrl.length); } this._internals.prefixUrl = value; } /** __Note #1__: The `body` option cannot be used with the `json` or `form` option. __Note #2__: If you provide this option, `got.stream()` will be read-only. __Note #3__: If you provide a payload with the `GET` or `HEAD` method, it will throw a `TypeError` unless the method is `GET` and the `allowGetBody` option is set to `true`. __Note #4__: This option is not enumerable and will not be merged with the instance defaults. The `content-length` header will be automatically set if `body` is a `string` / `Buffer` / [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) / [`form-data` instance](https://github.com/form-data/form-data), and `content-length` and `transfer-encoding` are not manually set in `options.headers`. Since Got 12, the `content-length` is not automatically set when `body` is a `fs.createReadStream`. */ get body() { return this._internals.body; } set body(value) { assert.any([dist.string, dist.buffer, dist.nodeStream, dist.generator, dist.asyncGenerator, isFormData, dist.undefined], value); if (dist.nodeStream(value)) { assert.truthy(value.readable); } if (value !== undefined) { assert.undefined(this._internals.form); assert.undefined(this._internals.json); } this._internals.body = value; } /** The form body is converted to a query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj). If the `Content-Type` header is not present, it will be set to `application/x-www-form-urlencoded`. __Note #1__: If you provide this option, `got.stream()` will be read-only. __Note #2__: This option is not enumerable and will not be merged with the instance defaults. */ get form() { return this._internals.form; } set form(value) { assert.any([dist.plainObject, dist.undefined], value); if (value !== undefined) { assert.undefined(this._internals.body); assert.undefined(this._internals.json); } this._internals.form = value; } /** JSON body. If the `Content-Type` header is not set, it will be set to `application/json`. __Note #1__: If you provide this option, `got.stream()` will be read-only. __Note #2__: This option is not enumerable and will not be merged with the instance defaults. */ get json() { return this._internals.json; } set json(value) { if (value !== undefined) { assert.undefined(this._internals.body); assert.undefined(this._internals.form); } this._internals.json = value; } /** The URL to request, as a string, a [`https.request` options object](https://nodejs.org/api/https.html#https_https_request_options_callback), or a [WHATWG `URL`](https://nodejs.org/api/url.html#url_class_url). Properties from `options` will override properties in the parsed `url`. If no protocol is specified, it will throw a `TypeError`. __Note__: The query string is **not** parsed as search params. @example ``` await got('https://example.com/?query=a b'); //=> https://example.com/?query=a%20b await got('https://example.com/', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b // The query string is overridden by `searchParams` await got('https://example.com/?query=a b', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b ``` */ get url() { return this._internals.url; } set url(value) { assert.any([dist.string, dist.urlInstance, dist.undefined], value); if (value === undefined) { this._internals.url = undefined; return; } if (dist.string(value) && value.startsWith('/')) { throw new Error('`url` must not start with a slash'); } const urlString = `${this.prefixUrl}${value.toString()}`; const url = new external_node_url_.URL(urlString); this._internals.url = url; decodeURI(urlString); if (url.protocol === 'unix:') { url.href = `http://unix${url.pathname}${url.search}`; } if (url.protocol !== 'http:' && url.protocol !== 'https:') { const error = new Error(`Unsupported protocol: ${url.protocol}`); error.code = 'ERR_UNSUPPORTED_PROTOCOL'; throw error; } if (this._internals.username) { url.username = this._internals.username; this._internals.username = ''; } if (this._internals.password) { url.password = this._internals.password; this._internals.password = ''; } if (this._internals.searchParams) { url.search = this._internals.searchParams.toString(); this._internals.searchParams = undefined; } if (url.hostname === 'unix') { if (!this._internals.enableUnixSockets) { throw new Error('Using UNIX domain sockets but option `enableUnixSockets` is not enabled'); } const matches = /(?.+?):(?.+)/.exec(`${url.pathname}${url.search}`); if (matches?.groups) { const { socketPath, path } = matches.groups; this._unixOptions = { socketPath, path, host: '', }; } else { this._unixOptions = undefined; } return; } this._unixOptions = undefined; } /** Cookie support. You don't have to care about parsing or how to store them. __Note__: If you provide this option, `options.headers.cookie` will be overridden. */ get cookieJar() { return this._internals.cookieJar; } set cookieJar(value) { assert.any([dist.object, dist.undefined], value); if (value === undefined) { this._internals.cookieJar = undefined; return; } let { setCookie, getCookieString } = value; assert.function_(setCookie); assert.function_(getCookieString); /* istanbul ignore next: Horrible `tough-cookie` v3 check */ if (setCookie.length === 4 && getCookieString.length === 0) { setCookie = (0,external_node_util_.promisify)(setCookie.bind(value)); getCookieString = (0,external_node_util_.promisify)(getCookieString.bind(value)); this._internals.cookieJar = { setCookie, getCookieString: getCookieString, }; } else { this._internals.cookieJar = value; } } /** You can abort the `request` using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). *Requires Node.js 16 or later.* @example ``` import got from 'got'; const abortController = new AbortController(); const request = got('https://httpbin.org/anything', { signal: abortController.signal }); setTimeout(() => { abortController.abort(); }, 100); ``` */ // TODO: Replace `any` with `AbortSignal` when targeting Node 16. get signal() { return this._internals.signal; } // TODO: Replace `any` with `AbortSignal` when targeting Node 16. set signal(value) { assert.object(value); this._internals.signal = value; } /** Ignore invalid cookies instead of throwing an error. Only useful when the `cookieJar` option has been set. Not recommended. @default false */ get ignoreInvalidCookies() { return this._internals.ignoreInvalidCookies; } set ignoreInvalidCookies(value) { assert.boolean(value); this._internals.ignoreInvalidCookies = value; } /** Query string that will be added to the request URL. This will override the query string in `url`. If you need to pass in an array, you can do it using a `URLSearchParams` instance. @example ``` import got from 'got'; const searchParams = new URLSearchParams([['key', 'a'], ['key', 'b']]); await got('https://example.com', {searchParams}); console.log(searchParams.toString()); //=> 'key=a&key=b' ``` */ get searchParams() { if (this._internals.url) { return this._internals.url.searchParams; } if (this._internals.searchParams === undefined) { this._internals.searchParams = new external_node_url_.URLSearchParams(); } return this._internals.searchParams; } set searchParams(value) { assert.any([dist.string, dist.object, dist.undefined], value); const url = this._internals.url; if (value === undefined) { this._internals.searchParams = undefined; if (url) { url.search = ''; } return; } const searchParameters = this.searchParams; let updated; if (dist.string(value)) { updated = new external_node_url_.URLSearchParams(value); } else if (value instanceof external_node_url_.URLSearchParams) { updated = value; } else { validateSearchParameters(value); updated = new external_node_url_.URLSearchParams(); // eslint-disable-next-line guard-for-in for (const key in value) { const entry = value[key]; if (entry === null) { updated.append(key, ''); } else if (entry === undefined) { searchParameters.delete(key); } else { updated.append(key, entry); } } } if (this._merging) { // These keys will be replaced for (const key of updated.keys()) { searchParameters.delete(key); } for (const [key, value] of updated) { searchParameters.append(key, value); } } else if (url) { url.search = searchParameters.toString(); } else { this._internals.searchParams = searchParameters; } } get searchParameters() { throw new Error('The `searchParameters` option does not exist. Use `searchParams` instead.'); } set searchParameters(_value) { throw new Error('The `searchParameters` option does not exist. Use `searchParams` instead.'); } get dnsLookup() { return this._internals.dnsLookup; } set dnsLookup(value) { assert.any([dist.function_, dist.undefined], value); this._internals.dnsLookup = value; } /** An instance of [`CacheableLookup`](https://github.com/szmarczak/cacheable-lookup) used for making DNS lookups. Useful when making lots of requests to different *public* hostnames. `CacheableLookup` uses `dns.resolver4(..)` and `dns.resolver6(...)` under the hood and fall backs to `dns.lookup(...)` when the first two fail, which may lead to additional delay. __Note__: This should stay disabled when making requests to internal hostnames such as `localhost`, `database.local` etc. @default false */ get dnsCache() { return this._internals.dnsCache; } set dnsCache(value) { assert.any([dist.object, dist.boolean, dist.undefined], value); if (value === true) { this._internals.dnsCache = getGlobalDnsCache(); } else if (value === false) { this._internals.dnsCache = undefined; } else { this._internals.dnsCache = value; } } /** User data. `context` is shallow merged and enumerable. If it contains non-enumerable properties they will NOT be merged. @example ``` import got from 'got'; const instance = got.extend({ hooks: { beforeRequest: [ options => { if (!options.context || !options.context.token) { throw new Error('Token required'); } options.headers.token = options.context.token; } ] } }); const context = { token: 'secret' }; const response = await instance('https://httpbin.org/headers', {context}); // Let's see the headers console.log(response.body); ``` */ get context() { return this._internals.context; } set context(value) { assert.object(value); if (this._merging) { Object.assign(this._internals.context, value); } else { this._internals.context = { ...value }; } } /** Hooks allow modifications during the request lifecycle. Hook functions may be async and are run serially. */ get hooks() { return this._internals.hooks; } set hooks(value) { assert.object(value); // eslint-disable-next-line guard-for-in for (const knownHookEvent in value) { if (!(knownHookEvent in this._internals.hooks)) { throw new Error(`Unexpected hook event: ${knownHookEvent}`); } const typedKnownHookEvent = knownHookEvent; const hooks = value[typedKnownHookEvent]; assert.any([dist.array, dist.undefined], hooks); if (hooks) { for (const hook of hooks) { assert.function_(hook); } } if (this._merging) { if (hooks) { // @ts-expect-error FIXME this._internals.hooks[typedKnownHookEvent].push(...hooks); } } else { if (!hooks) { throw new Error(`Missing hook event: ${knownHookEvent}`); } // @ts-expect-error FIXME this._internals.hooks[knownHookEvent] = [...hooks]; } } } /** Defines if redirect responses should be followed automatically. Note that if a `303` is sent by the server in response to any request type (`POST`, `DELETE`, etc.), Got will automatically request the resource pointed to in the location header via `GET`. This is in accordance with [the spec](https://tools.ietf.org/html/rfc7231#section-6.4.4). You can optionally turn on this behavior also for other redirect codes - see `methodRewriting`. @default true */ get followRedirect() { return this._internals.followRedirect; } set followRedirect(value) { assert.boolean(value); this._internals.followRedirect = value; } get followRedirects() { throw new TypeError('The `followRedirects` option does not exist. Use `followRedirect` instead.'); } set followRedirects(_value) { throw new TypeError('The `followRedirects` option does not exist. Use `followRedirect` instead.'); } /** If exceeded, the request will be aborted and a `MaxRedirectsError` will be thrown. @default 10 */ get maxRedirects() { return this._internals.maxRedirects; } set maxRedirects(value) { assert.number(value); this._internals.maxRedirects = value; } /** A cache adapter instance for storing cached response data. @default false */ get cache() { return this._internals.cache; } set cache(value) { assert.any([dist.object, dist.string, dist.boolean, dist.undefined], value); if (value === true) { this._internals.cache = globalCache; } else if (value === false) { this._internals.cache = undefined; } else { this._internals.cache = value; } } /** Determines if a `got.HTTPError` is thrown for unsuccessful responses. If this is disabled, requests that encounter an error status code will be resolved with the `response` instead of throwing. This may be useful if you are checking for resource availability and are expecting error responses. @default true */ get throwHttpErrors() { return this._internals.throwHttpErrors; } set throwHttpErrors(value) { assert.boolean(value); this._internals.throwHttpErrors = value; } get username() { const url = this._internals.url; const value = url ? url.username : this._internals.username; return decodeURIComponent(value); } set username(value) { assert.string(value); const url = this._internals.url; const fixedValue = encodeURIComponent(value); if (url) { url.username = fixedValue; } else { this._internals.username = fixedValue; } } get password() { const url = this._internals.url; const value = url ? url.password : this._internals.password; return decodeURIComponent(value); } set password(value) { assert.string(value); const url = this._internals.url; const fixedValue = encodeURIComponent(value); if (url) { url.password = fixedValue; } else { this._internals.password = fixedValue; } } /** If set to `true`, Got will additionally accept HTTP2 requests. It will choose either HTTP/1.1 or HTTP/2 depending on the ALPN protocol. __Note__: This option requires Node.js 15.10.0 or newer as HTTP/2 support on older Node.js versions is very buggy. __Note__: Overriding `options.request` will disable HTTP2 support. @default false @example ``` import got from 'got'; const {headers} = await got('https://nghttp2.org/httpbin/anything', {http2: true}); console.log(headers.via); //=> '2 nghttpx' ``` */ get http2() { return this._internals.http2; } set http2(value) { assert.boolean(value); this._internals.http2 = value; } /** Set this to `true` to allow sending body for the `GET` method. However, the [HTTP/2 specification](https://tools.ietf.org/html/rfc7540#section-8.1.3) says that `An HTTP GET request includes request header fields and no payload body`, therefore when using the HTTP/2 protocol this option will have no effect. This option is only meant to interact with non-compliant servers when you have no other choice. __Note__: The [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.1) doesn't specify any particular behavior for the GET method having a payload, therefore __it's considered an [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern)__. @default false */ get allowGetBody() { return this._internals.allowGetBody; } set allowGetBody(value) { assert.boolean(value); this._internals.allowGetBody = value; } /** Request headers. Existing headers will be overwritten. Headers set to `undefined` will be omitted. @default {} */ get headers() { return this._internals.headers; } set headers(value) { assert.plainObject(value); if (this._merging) { Object.assign(this._internals.headers, lowercaseKeys(value)); } else { this._internals.headers = lowercaseKeys(value); } } /** Specifies if the HTTP request method should be [rewritten as `GET`](https://tools.ietf.org/html/rfc7231#section-6.4) on redirects. As the [specification](https://tools.ietf.org/html/rfc7231#section-6.4) prefers to rewrite the HTTP method only on `303` responses, this is Got's default behavior. Setting `methodRewriting` to `true` will also rewrite `301` and `302` responses, as allowed by the spec. This is the behavior followed by `curl` and browsers. __Note__: Got never performs method rewriting on `307` and `308` responses, as this is [explicitly prohibited by the specification](https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7). @default false */ get methodRewriting() { return this._internals.methodRewriting; } set methodRewriting(value) { assert.boolean(value); this._internals.methodRewriting = value; } /** Indicates which DNS record family to use. Values: - `undefined`: IPv4 (if present) or IPv6 - `4`: Only IPv4 - `6`: Only IPv6 @default undefined */ get dnsLookupIpVersion() { return this._internals.dnsLookupIpVersion; } set dnsLookupIpVersion(value) { if (value !== undefined && value !== 4 && value !== 6) { throw new TypeError(`Invalid DNS lookup IP version: ${value}`); } this._internals.dnsLookupIpVersion = value; } /** A function used to parse JSON responses. @example ``` import got from 'got'; import Bourne from '@hapi/bourne'; const parsed = await got('https://example.com', { parseJson: text => Bourne.parse(text) }).json(); console.log(parsed); ``` */ get parseJson() { return this._internals.parseJson; } set parseJson(value) { assert.function_(value); this._internals.parseJson = value; } /** A function used to stringify the body of JSON requests. @example ``` import got from 'got'; await got.post('https://example.com', { stringifyJson: object => JSON.stringify(object, (key, value) => { if (key.startsWith('_')) { return; } return value; }), json: { some: 'payload', _ignoreMe: 1234 } }); ``` @example ``` import got from 'got'; await got.post('https://example.com', { stringifyJson: object => JSON.stringify(object, (key, value) => { if (typeof value === 'number') { return value.toString(); } return value; }), json: { some: 'payload', number: 1 } }); ``` */ get stringifyJson() { return this._internals.stringifyJson; } set stringifyJson(value) { assert.function_(value); this._internals.stringifyJson = value; } /** An object representing `limit`, `calculateDelay`, `methods`, `statusCodes`, `maxRetryAfter` and `errorCodes` fields for maximum retry count, retry handler, allowed methods, allowed status codes, maximum [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time and allowed error codes. Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 1). The `calculateDelay` property is a `function` that receives an object with `attemptCount`, `retryOptions`, `error` and `computedValue` properties for current retry count, the retry options, error and default computed value. The function must return a delay in milliseconds (or a Promise resolving with it) (`0` return value cancels retry). By default, it retries *only* on the specified methods, status codes, and on these network errors: - `ETIMEDOUT`: One of the [timeout](#timeout) limits were reached. - `ECONNRESET`: Connection was forcibly closed by a peer. - `EADDRINUSE`: Could not bind to any free port. - `ECONNREFUSED`: Connection was refused by the server. - `EPIPE`: The remote side of the stream being written has been closed. - `ENOTFOUND`: Couldn't resolve the hostname to an IP address. - `ENETUNREACH`: No internet connection. - `EAI_AGAIN`: DNS lookup timed out. __Note__: If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`. __Note__: If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header is greater than `maxRetryAfter`, it will cancel the request. */ get retry() { return this._internals.retry; } set retry(value) { assert.plainObject(value); assert.any([dist.function_, dist.undefined], value.calculateDelay); assert.any([dist.number, dist.undefined], value.maxRetryAfter); assert.any([dist.number, dist.undefined], value.limit); assert.any([dist.array, dist.undefined], value.methods); assert.any([dist.array, dist.undefined], value.statusCodes); assert.any([dist.array, dist.undefined], value.errorCodes); assert.any([dist.number, dist.undefined], value.noise); if (value.noise && Math.abs(value.noise) > 100) { throw new Error(`The maximum acceptable retry noise is +/- 100ms, got ${value.noise}`); } for (const key in value) { if (!(key in this._internals.retry)) { throw new Error(`Unexpected retry option: ${key}`); } } if (this._merging) { Object.assign(this._internals.retry, value); } else { this._internals.retry = { ...value }; } const { retry } = this._internals; retry.methods = [...new Set(retry.methods.map(method => method.toUpperCase()))]; retry.statusCodes = [...new Set(retry.statusCodes)]; retry.errorCodes = [...new Set(retry.errorCodes)]; } /** From `http.RequestOptions`. The IP address used to send the request from. */ get localAddress() { return this._internals.localAddress; } set localAddress(value) { assert.any([dist.string, dist.undefined], value); this._internals.localAddress = value; } /** The HTTP method used to make the request. @default 'GET' */ get method() { return this._internals.method; } set method(value) { assert.string(value); this._internals.method = value.toUpperCase(); } get createConnection() { return this._internals.createConnection; } set createConnection(value) { assert.any([dist.function_, dist.undefined], value); this._internals.createConnection = value; } /** From `http-cache-semantics` @default {} */ get cacheOptions() { return this._internals.cacheOptions; } set cacheOptions(value) { assert.plainObject(value); assert.any([dist.boolean, dist.undefined], value.shared); assert.any([dist.number, dist.undefined], value.cacheHeuristic); assert.any([dist.number, dist.undefined], value.immutableMinTimeToLive); assert.any([dist.boolean, dist.undefined], value.ignoreCargoCult); for (const key in value) { if (!(key in this._internals.cacheOptions)) { throw new Error(`Cache option \`${key}\` does not exist`); } } if (this._merging) { Object.assign(this._internals.cacheOptions, value); } else { this._internals.cacheOptions = { ...value }; } } /** Options for the advanced HTTPS API. */ get https() { return this._internals.https; } set https(value) { assert.plainObject(value); assert.any([dist.boolean, dist.undefined], value.rejectUnauthorized); assert.any([dist.function_, dist.undefined], value.checkServerIdentity); assert.any([dist.string, dist.object, dist.array, dist.undefined], value.certificateAuthority); assert.any([dist.string, dist.object, dist.array, dist.undefined], value.key); assert.any([dist.string, dist.object, dist.array, dist.undefined], value.certificate); assert.any([dist.string, dist.undefined], value.passphrase); assert.any([dist.string, dist.buffer, dist.array, dist.undefined], value.pfx); assert.any([dist.array, dist.undefined], value.alpnProtocols); assert.any([dist.string, dist.undefined], value.ciphers); assert.any([dist.string, dist.buffer, dist.undefined], value.dhparam); assert.any([dist.string, dist.undefined], value.signatureAlgorithms); assert.any([dist.string, dist.undefined], value.minVersion); assert.any([dist.string, dist.undefined], value.maxVersion); assert.any([dist.boolean, dist.undefined], value.honorCipherOrder); assert.any([dist.number, dist.undefined], value.tlsSessionLifetime); assert.any([dist.string, dist.undefined], value.ecdhCurve); assert.any([dist.string, dist.buffer, dist.array, dist.undefined], value.certificateRevocationLists); for (const key in value) { if (!(key in this._internals.https)) { throw new Error(`HTTPS option \`${key}\` does not exist`); } } if (this._merging) { Object.assign(this._internals.https, value); } else { this._internals.https = { ...value }; } } /** [Encoding](https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings) to be used on `setEncoding` of the response data. To get a [`Buffer`](https://nodejs.org/api/buffer.html), you need to set `responseType` to `buffer` instead. Don't set this option to `null`. __Note__: This doesn't affect streams! Instead, you need to do `got.stream(...).setEncoding(encoding)`. @default 'utf-8' */ get encoding() { return this._internals.encoding; } set encoding(value) { if (value === null) { throw new TypeError('To get a Buffer, set `options.responseType` to `buffer` instead'); } assert.any([dist.string, dist.undefined], value); this._internals.encoding = value; } /** When set to `true` the promise will return the Response body instead of the Response object. @default false */ get resolveBodyOnly() { return this._internals.resolveBodyOnly; } set resolveBodyOnly(value) { assert.boolean(value); this._internals.resolveBodyOnly = value; } /** Returns a `Stream` instead of a `Promise`. This is equivalent to calling `got.stream(url, options?)`. @default false */ get isStream() { return this._internals.isStream; } set isStream(value) { assert.boolean(value); this._internals.isStream = value; } /** The parsing method. The promise also has `.text()`, `.json()` and `.buffer()` methods which return another Got promise for the parsed body. It's like setting the options to `{responseType: 'json', resolveBodyOnly: true}` but without affecting the main Got promise. __Note__: When using streams, this option is ignored. @example ``` const responsePromise = got(url); const bufferPromise = responsePromise.buffer(); const jsonPromise = responsePromise.json(); const [response, buffer, json] = Promise.all([responsePromise, bufferPromise, jsonPromise]); // `response` is an instance of Got Response // `buffer` is an instance of Buffer // `json` is an object ``` @example ``` // This const body = await got(url).json(); // is semantically the same as this const body = await got(url, {responseType: 'json', resolveBodyOnly: true}); ``` */ get responseType() { return this._internals.responseType; } set responseType(value) { if (value === undefined) { this._internals.responseType = 'text'; return; } if (value !== 'text' && value !== 'buffer' && value !== 'json') { throw new Error(`Invalid \`responseType\` option: ${value}`); } this._internals.responseType = value; } get pagination() { return this._internals.pagination; } set pagination(value) { assert.object(value); if (this._merging) { Object.assign(this._internals.pagination, value); } else { this._internals.pagination = value; } } get auth() { throw new Error('Parameter `auth` is deprecated. Use `username` / `password` instead.'); } set auth(_value) { throw new Error('Parameter `auth` is deprecated. Use `username` / `password` instead.'); } get setHost() { return this._internals.setHost; } set setHost(value) { assert.boolean(value); this._internals.setHost = value; } get maxHeaderSize() { return this._internals.maxHeaderSize; } set maxHeaderSize(value) { assert.any([dist.number, dist.undefined], value); this._internals.maxHeaderSize = value; } get enableUnixSockets() { return this._internals.enableUnixSockets; } set enableUnixSockets(value) { assert.boolean(value); this._internals.enableUnixSockets = value; } // eslint-disable-next-line @typescript-eslint/naming-convention toJSON() { return { ...this._internals }; } [Symbol.for('nodejs.util.inspect.custom')](_depth, options) { return (0,external_node_util_.inspect)(this._internals, options); } createNativeRequestOptions() { const internals = this._internals; const url = internals.url; let agent; if (url.protocol === 'https:') { agent = internals.http2 ? internals.agent : internals.agent.https; } else { agent = internals.agent.http; } const { https } = internals; let { pfx } = https; if (dist.array(pfx) && dist.plainObject(pfx[0])) { pfx = pfx.map(object => ({ buf: object.buffer, passphrase: object.passphrase, })); } return { ...internals.cacheOptions, ...this._unixOptions, // HTTPS options // eslint-disable-next-line @typescript-eslint/naming-convention ALPNProtocols: https.alpnProtocols, ca: https.certificateAuthority, cert: https.certificate, key: https.key, passphrase: https.passphrase, pfx: https.pfx, rejectUnauthorized: https.rejectUnauthorized, checkServerIdentity: https.checkServerIdentity ?? external_node_tls_.checkServerIdentity, ciphers: https.ciphers, honorCipherOrder: https.honorCipherOrder, minVersion: https.minVersion, maxVersion: https.maxVersion, sigalgs: https.signatureAlgorithms, sessionTimeout: https.tlsSessionLifetime, dhparam: https.dhparam, ecdhCurve: https.ecdhCurve, crl: https.certificateRevocationLists, // HTTP options lookup: internals.dnsLookup ?? internals.dnsCache?.lookup, family: internals.dnsLookupIpVersion, agent, setHost: internals.setHost, method: internals.method, maxHeaderSize: internals.maxHeaderSize, localAddress: internals.localAddress, headers: internals.headers, createConnection: internals.createConnection, timeout: internals.http2 ? getHttp2TimeoutOption(internals) : undefined, // HTTP/2 options h2session: internals.h2session, }; } getRequestFunction() { const url = this._internals.url; const { request } = this._internals; if (!request && url) { return this.getFallbackRequestFunction(); } return request; } getFallbackRequestFunction() { const url = this._internals.url; if (!url) { return; } if (url.protocol === 'https:') { if (this._internals.http2) { if (major < 15 || (major === 15 && minor < 10)) { const error = new Error('To use the `http2` option, install Node.js 15.10.0 or above'); error.code = 'EUNSUPPORTED'; throw error; } return http2_wrapper_source.auto; } return external_node_https_.request; } return external_node_http_.request; } freeze() { const options = this._internals; Object.freeze(options); Object.freeze(options.hooks); Object.freeze(options.hooks.afterResponse); Object.freeze(options.hooks.beforeError); Object.freeze(options.hooks.beforeRedirect); Object.freeze(options.hooks.beforeRequest); Object.freeze(options.hooks.beforeRetry); Object.freeze(options.hooks.init); Object.freeze(options.https); Object.freeze(options.cacheOptions); Object.freeze(options.agent); Object.freeze(options.headers); Object.freeze(options.timeout); Object.freeze(options.retry); Object.freeze(options.retry.errorCodes); Object.freeze(options.retry.methods); Object.freeze(options.retry.statusCodes); } } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/response.js const isResponseOk = (response) => { const { statusCode } = response; const limitStatusCode = response.request.options.followRedirect ? 299 : 399; return (statusCode >= 200 && statusCode <= limitStatusCode) || statusCode === 304; }; /** An error to be thrown when server response code is 2xx, and parsing body fails. Includes a `response` property. */ class ParseError extends RequestError { constructor(error, response) { const { options } = response.request; super(`${error.message} in "${options.url.toString()}"`, error, response.request); this.name = 'ParseError'; this.code = 'ERR_BODY_PARSE_FAILURE'; } } const parseBody = (response, responseType, parseJson, encoding) => { const { rawBody } = response; try { if (responseType === 'text') { return rawBody.toString(encoding); } if (responseType === 'json') { return rawBody.length === 0 ? '' : parseJson(rawBody.toString(encoding)); } if (responseType === 'buffer') { return rawBody; } } catch (error) { throw new ParseError(error, response); } throw new ParseError({ message: `Unknown body type '${responseType}'`, name: 'Error', }, response); }; ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/is-client-request.js function isClientRequest(clientRequest) { return clientRequest.writable && !clientRequest.writableEnded; } /* harmony default export */ const is_client_request = (isClientRequest); ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/utils/is-unix-socket-url.js // eslint-disable-next-line @typescript-eslint/naming-convention function isUnixSocketURL(url) { return url.protocol === 'unix:' || url.hostname === 'unix'; } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/core/index.js const supportsBrotli = dist.string(external_node_process_.versions.brotli); const methodsWithoutBody = new Set(['GET', 'HEAD']); const cacheableStore = new WeakableMap(); const redirectCodes = new Set([300, 301, 302, 303, 304, 307, 308]); const proxiedRequestEvents = [ 'socket', 'connect', 'continue', 'information', 'upgrade', ]; const core_noop = () => { }; class Request extends external_node_stream_.Duplex { constructor(url, options, defaults) { super({ // Don't destroy immediately, as the error may be emitted on unsuccessful retry autoDestroy: false, // It needs to be zero because we're just proxying the data to another stream highWaterMark: 0, }); // @ts-expect-error - Ignoring for now. Object.defineProperty(this, 'constructor', { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_noPipe", { enumerable: true, configurable: true, writable: true, value: void 0 }); // @ts-expect-error https://github.com/microsoft/TypeScript/issues/9568 Object.defineProperty(this, "options", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "response", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "requestUrl", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "redirectUrls", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "retryCount", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_stopRetry", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_downloadedSize", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_uploadedSize", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_stopReading", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_pipedServerResponses", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_request", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_responseSize", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_bodySize", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_unproxyEvents", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_isFromCache", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_cannotHaveBody", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_triggerRead", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_cancelTimeouts", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_nativeResponse", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_flushed", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_aborted", { enumerable: true, configurable: true, writable: true, value: void 0 }); // We need this because `this._request` if `undefined` when using cache Object.defineProperty(this, "_requestInitialized", { enumerable: true, configurable: true, writable: true, value: void 0 }); this._downloadedSize = 0; this._uploadedSize = 0; this._stopReading = false; this._pipedServerResponses = new Set(); this._cannotHaveBody = false; this._unproxyEvents = core_noop; this._triggerRead = false; this._cancelTimeouts = core_noop; this._jobs = []; this._flushed = false; this._requestInitialized = false; this._aborted = false; this.redirectUrls = []; this.retryCount = 0; this._stopRetry = core_noop; this.on('pipe', source => { if (source.headers) { Object.assign(this.options.headers, source.headers); } }); this.on('newListener', event => { if (event === 'retry' && this.listenerCount('retry') > 0) { throw new Error('A retry listener has been attached already.'); } }); try { this.options = new Options(url, options, defaults); if (!this.options.url) { if (this.options.prefixUrl === '') { throw new TypeError('Missing `url` property'); } this.options.url = ''; } this.requestUrl = this.options.url; } catch (error) { const { options } = error; if (options) { this.options = options; } this.flush = async () => { this.flush = async () => { }; this.destroy(error); }; return; } if (this.options.signal?.aborted) { this.destroy(new AbortError(this)); } this.options.signal?.addEventListener('abort', () => { this.destroy(new AbortError(this)); }); // Important! If you replace `body` in a handler with another stream, make sure it's readable first. // The below is run only once. const { body } = this.options; if (dist.nodeStream(body)) { body.once('error', error => { if (this._flushed) { this._beforeError(new UploadError(error, this)); } else { this.flush = async () => { this.flush = async () => { }; this._beforeError(new UploadError(error, this)); }; } }); } } async flush() { if (this._flushed) { return; } this._flushed = true; try { await this._finalizeBody(); if (this.destroyed) { return; } await this._makeRequest(); if (this.destroyed) { this._request?.destroy(); return; } // Queued writes etc. for (const job of this._jobs) { job(); } // Prevent memory leak this._jobs.length = 0; this._requestInitialized = true; } catch (error) { this._beforeError(error); } } _beforeError(error) { if (this._stopReading) { return; } const { response, options } = this; const attemptCount = this.retryCount + (error.name === 'RetryError' ? 0 : 1); this._stopReading = true; if (!(error instanceof RequestError)) { error = new RequestError(error.message, error, this); } const typedError = error; void (async () => { // Node.js parser is really weird. // It emits post-request Parse Errors on the same instance as previous request. WTF. // Therefore we need to check if it has been destroyed as well. // // Furthermore, Node.js 16 `response.destroy()` doesn't immediately destroy the socket, // but makes the response unreadable. So we additionally need to check `response.readable`. if (response?.readable && !response.rawBody && !this._request?.socket?.destroyed) { // @types/node has incorrect typings. `setEncoding` accepts `null` as well. response.setEncoding(this.readableEncoding); const success = await this._setRawBody(response); if (success) { response.body = response.rawBody.toString(); } } if (this.listenerCount('retry') !== 0) { let backoff; try { let retryAfter; if (response && 'retry-after' in response.headers) { retryAfter = Number(response.headers['retry-after']); if (Number.isNaN(retryAfter)) { retryAfter = Date.parse(response.headers['retry-after']) - Date.now(); if (retryAfter <= 0) { retryAfter = 1; } } else { retryAfter *= 1000; } } const retryOptions = options.retry; backoff = await retryOptions.calculateDelay({ attemptCount, retryOptions, error: typedError, retryAfter, computedValue: calculate_retry_delay({ attemptCount, retryOptions, error: typedError, retryAfter, computedValue: retryOptions.maxRetryAfter ?? options.timeout.request ?? Number.POSITIVE_INFINITY, }), }); } catch (error_) { void this._error(new RequestError(error_.message, error_, this)); return; } if (backoff) { await new Promise(resolve => { const timeout = setTimeout(resolve, backoff); this._stopRetry = () => { clearTimeout(timeout); resolve(); }; }); // Something forced us to abort the retry if (this.destroyed) { return; } try { for (const hook of this.options.hooks.beforeRetry) { // eslint-disable-next-line no-await-in-loop await hook(typedError, this.retryCount + 1); } } catch (error_) { void this._error(new RequestError(error_.message, error, this)); return; } // Something forced us to abort the retry if (this.destroyed) { return; } this.destroy(); this.emit('retry', this.retryCount + 1, error, (updatedOptions) => { const request = new Request(options.url, updatedOptions, options); request.retryCount = this.retryCount + 1; external_node_process_.nextTick(() => { void request.flush(); }); return request; }); return; } } void this._error(typedError); })(); } _read() { this._triggerRead = true; const { response } = this; if (response && !this._stopReading) { // We cannot put this in the `if` above // because `.read()` also triggers the `end` event if (response.readableLength) { this._triggerRead = false; } let data; while ((data = response.read()) !== null) { this._downloadedSize += data.length; // eslint-disable-line @typescript-eslint/restrict-plus-operands const progress = this.downloadProgress; if (progress.percent < 1) { this.emit('downloadProgress', progress); } this.push(data); } } } _write(chunk, encoding, callback) { const write = () => { this._writeRequest(chunk, encoding, callback); }; if (this._requestInitialized) { write(); } else { this._jobs.push(write); } } _final(callback) { const endRequest = () => { // We need to check if `this._request` is present, // because it isn't when we use cache. if (!this._request || this._request.destroyed) { callback(); return; } this._request.end((error) => { // The request has been destroyed before `_final` finished. // See https://github.com/nodejs/node/issues/39356 if (this._request._writableState?.errored) { return; } if (!error) { this._bodySize = this._uploadedSize; this.emit('uploadProgress', this.uploadProgress); this._request.emit('upload-complete'); } callback(error); }); }; if (this._requestInitialized) { endRequest(); } else { this._jobs.push(endRequest); } } _destroy(error, callback) { this._stopReading = true; this.flush = async () => { }; // Prevent further retries this._stopRetry(); this._cancelTimeouts(); if (this.options) { const { body } = this.options; if (dist.nodeStream(body)) { body.destroy(); } } if (this._request) { this._request.destroy(); } if (error !== null && !dist.undefined(error) && !(error instanceof RequestError)) { error = new RequestError(error.message, error, this); } callback(error); } pipe(destination, options) { if (destination instanceof external_node_http_.ServerResponse) { this._pipedServerResponses.add(destination); } return super.pipe(destination, options); } unpipe(destination) { if (destination instanceof external_node_http_.ServerResponse) { this._pipedServerResponses.delete(destination); } super.unpipe(destination); return this; } async _finalizeBody() { const { options } = this; const { headers } = options; const isForm = !dist.undefined(options.form); // eslint-disable-next-line @typescript-eslint/naming-convention const isJSON = !dist.undefined(options.json); const isBody = !dist.undefined(options.body); const cannotHaveBody = methodsWithoutBody.has(options.method) && !(options.method === 'GET' && options.allowGetBody); this._cannotHaveBody = cannotHaveBody; if (isForm || isJSON || isBody) { if (cannotHaveBody) { throw new TypeError(`The \`${options.method}\` method cannot be used with a body`); } // Serialize body const noContentType = !dist.string(headers['content-type']); if (isBody) { // Body is spec-compliant FormData if (isFormData(options.body)) { const encoder = new FormDataEncoder(options.body); if (noContentType) { headers['content-type'] = encoder.headers['Content-Type']; } if ('Content-Length' in encoder.headers) { headers['content-length'] = encoder.headers['Content-Length']; } options.body = encoder.encode(); } // Special case for https://github.com/form-data/form-data if (is_form_data_isFormData(options.body) && noContentType) { headers['content-type'] = `multipart/form-data; boundary=${options.body.getBoundary()}`; } } else if (isForm) { if (noContentType) { headers['content-type'] = 'application/x-www-form-urlencoded'; } const { form } = options; options.form = undefined; options.body = (new external_node_url_.URLSearchParams(form)).toString(); } else { if (noContentType) { headers['content-type'] = 'application/json'; } const { json } = options; options.json = undefined; options.body = options.stringifyJson(json); } const uploadBodySize = await getBodySize(options.body, options.headers); // See https://tools.ietf.org/html/rfc7230#section-3.3.2 // A user agent SHOULD send a Content-Length in a request message when // no Transfer-Encoding is sent and the request method defines a meaning // for an enclosed payload body. For example, a Content-Length header // field is normally sent in a POST request even when the value is 0 // (indicating an empty payload body). A user agent SHOULD NOT send a // Content-Length header field when the request message does not contain // a payload body and the method semantics do not anticipate such a // body. if (dist.undefined(headers['content-length']) && dist.undefined(headers['transfer-encoding']) && !cannotHaveBody && !dist.undefined(uploadBodySize)) { headers['content-length'] = String(uploadBodySize); } } if (options.responseType === 'json' && !('accept' in options.headers)) { options.headers.accept = 'application/json'; } this._bodySize = Number(headers['content-length']) || undefined; } async _onResponseBase(response) { // This will be called e.g. when using cache so we need to check if this request has been aborted. if (this.isAborted) { return; } const { options } = this; const { url } = options; this._nativeResponse = response; if (options.decompress) { response = decompress_response(response); } const statusCode = response.statusCode; const typedResponse = response; typedResponse.statusMessage = typedResponse.statusMessage ? typedResponse.statusMessage : external_node_http_.STATUS_CODES[statusCode]; typedResponse.url = options.url.toString(); typedResponse.requestUrl = this.requestUrl; typedResponse.redirectUrls = this.redirectUrls; typedResponse.request = this; typedResponse.isFromCache = this._nativeResponse.fromCache ?? false; typedResponse.ip = this.ip; typedResponse.retryCount = this.retryCount; typedResponse.ok = isResponseOk(typedResponse); this._isFromCache = typedResponse.isFromCache; this._responseSize = Number(response.headers['content-length']) || undefined; this.response = typedResponse; response.once('end', () => { this._responseSize = this._downloadedSize; this.emit('downloadProgress', this.downloadProgress); }); response.once('error', (error) => { this._aborted = true; // Force clean-up, because some packages don't do this. // TODO: Fix decompress-response response.destroy(); this._beforeError(new ReadError(error, this)); }); response.once('aborted', () => { this._aborted = true; this._beforeError(new ReadError({ name: 'Error', message: 'The server aborted pending request', code: 'ECONNRESET', }, this)); }); this.emit('downloadProgress', this.downloadProgress); const rawCookies = response.headers['set-cookie']; if (dist.object(options.cookieJar) && rawCookies) { let promises = rawCookies.map(async (rawCookie) => options.cookieJar.setCookie(rawCookie, url.toString())); if (options.ignoreInvalidCookies) { promises = promises.map(async (promise) => { try { await promise; } catch { } }); } try { await Promise.all(promises); } catch (error) { this._beforeError(error); return; } } // The above is running a promise, therefore we need to check if this request has been aborted yet again. if (this.isAborted) { return; } if (options.followRedirect && response.headers.location && redirectCodes.has(statusCode)) { // We're being redirected, we don't care about the response. // It'd be best to abort the request, but we can't because // we would have to sacrifice the TCP connection. We don't want that. response.resume(); this._cancelTimeouts(); this._unproxyEvents(); if (this.redirectUrls.length >= options.maxRedirects) { this._beforeError(new MaxRedirectsError(this)); return; } this._request = undefined; const updatedOptions = new Options(undefined, undefined, this.options); const serverRequestedGet = statusCode === 303 && updatedOptions.method !== 'GET' && updatedOptions.method !== 'HEAD'; const canRewrite = statusCode !== 307 && statusCode !== 308; const userRequestedGet = updatedOptions.methodRewriting && canRewrite; if (serverRequestedGet || userRequestedGet) { updatedOptions.method = 'GET'; updatedOptions.body = undefined; updatedOptions.json = undefined; updatedOptions.form = undefined; delete updatedOptions.headers['content-length']; } try { // We need this in order to support UTF-8 const redirectBuffer = external_node_buffer_.Buffer.from(response.headers.location, 'binary').toString(); const redirectUrl = new external_node_url_.URL(redirectBuffer, url); if (!isUnixSocketURL(url) && isUnixSocketURL(redirectUrl)) { this._beforeError(new RequestError('Cannot redirect to UNIX socket', {}, this)); return; } // Redirecting to a different site, clear sensitive data. if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) { if ('host' in updatedOptions.headers) { delete updatedOptions.headers.host; } if ('cookie' in updatedOptions.headers) { delete updatedOptions.headers.cookie; } if ('authorization' in updatedOptions.headers) { delete updatedOptions.headers.authorization; } if (updatedOptions.username || updatedOptions.password) { updatedOptions.username = ''; updatedOptions.password = ''; } } else { redirectUrl.username = updatedOptions.username; redirectUrl.password = updatedOptions.password; } this.redirectUrls.push(redirectUrl); updatedOptions.prefixUrl = ''; updatedOptions.url = redirectUrl; for (const hook of updatedOptions.hooks.beforeRedirect) { // eslint-disable-next-line no-await-in-loop await hook(updatedOptions, typedResponse); } this.emit('redirect', updatedOptions, typedResponse); this.options = updatedOptions; await this._makeRequest(); } catch (error) { this._beforeError(error); return; } return; } // `HTTPError`s always have `error.response.body` defined. // Therefore we cannot retry if `options.throwHttpErrors` is false. // On the last retry, if `options.throwHttpErrors` is false, we would need to return the body, // but that wouldn't be possible since the body would be already read in `error.response.body`. if (options.isStream && options.throwHttpErrors && !isResponseOk(typedResponse)) { this._beforeError(new HTTPError(typedResponse)); return; } response.on('readable', () => { if (this._triggerRead) { this._read(); } }); this.on('resume', () => { response.resume(); }); this.on('pause', () => { response.pause(); }); response.once('end', () => { this.push(null); }); if (this._noPipe) { const success = await this._setRawBody(); if (success) { this.emit('response', response); } return; } this.emit('response', response); for (const destination of this._pipedServerResponses) { if (destination.headersSent) { continue; } // eslint-disable-next-line guard-for-in for (const key in response.headers) { const isAllowed = options.decompress ? key !== 'content-encoding' : true; const value = response.headers[key]; if (isAllowed) { destination.setHeader(key, value); } } destination.statusCode = statusCode; } } async _setRawBody(from = this) { if (from.readableEnded) { return false; } try { // Errors are emitted via the `error` event const rawBody = await (0,node_modules_get_stream.buffer)(from); // On retry Request is destroyed with no error, therefore the above will successfully resolve. // So in order to check if this was really successfull, we need to check if it has been properly ended. if (!this.isAborted) { this.response.rawBody = rawBody; return true; } } catch { } return false; } async _onResponse(response) { try { await this._onResponseBase(response); } catch (error) { /* istanbul ignore next: better safe than sorry */ this._beforeError(error); } } _onRequest(request) { const { options } = this; const { timeout, url } = options; dist_source(request); if (this.options.http2) { // Unset stream timeout, as the `timeout` option was used only for connection timeout. request.setTimeout(0); } this._cancelTimeouts = timedOut(request, timeout, url); const responseEventName = options.cache ? 'cacheableResponse' : 'response'; request.once(responseEventName, (response) => { void this._onResponse(response); }); request.once('error', (error) => { this._aborted = true; // Force clean-up, because some packages (e.g. nock) don't do this. request.destroy(); error = error instanceof timed_out_TimeoutError ? new TimeoutError(error, this.timings, this) : new RequestError(error.message, error, this); this._beforeError(error); }); this._unproxyEvents = proxyEvents(request, this, proxiedRequestEvents); this._request = request; this.emit('uploadProgress', this.uploadProgress); this._sendBody(); this.emit('request', request); } async _asyncWrite(chunk) { return new Promise((resolve, reject) => { super.write(chunk, error => { if (error) { reject(error); return; } resolve(); }); }); } _sendBody() { // Send body const { body } = this.options; const currentRequest = this.redirectUrls.length === 0 ? this : this._request ?? this; if (dist.nodeStream(body)) { body.pipe(currentRequest); } else if (dist.generator(body) || dist.asyncGenerator(body)) { (async () => { try { for await (const chunk of body) { await this._asyncWrite(chunk); } super.end(); } catch (error) { this._beforeError(error); } })(); } else if (!dist.undefined(body)) { this._writeRequest(body, undefined, () => { }); currentRequest.end(); } else if (this._cannotHaveBody || this._noPipe) { currentRequest.end(); } } _prepareCache(cache) { if (!cacheableStore.has(cache)) { const cacheableRequest = new cacheable_request_dist(((requestOptions, handler) => { const result = requestOptions._request(requestOptions, handler); // TODO: remove this when `cacheable-request` supports async request functions. if (dist.promise(result)) { // We only need to implement the error handler in order to support HTTP2 caching. // The result will be a promise anyway. // @ts-expect-error ignore // eslint-disable-next-line @typescript-eslint/promise-function-async result.once = (event, handler) => { if (event === 'error') { (async () => { try { await result; } catch (error) { handler(error); } })(); } else if (event === 'abort') { // The empty catch is needed here in case when // it rejects before it's `await`ed in `_makeRequest`. (async () => { try { const request = (await result); request.once('abort', handler); } catch { } })(); } else { /* istanbul ignore next: safety check */ throw new Error(`Unknown HTTP2 promise event: ${event}`); } return result; }; } return result; }), cache); cacheableStore.set(cache, cacheableRequest.request()); } } async _createCacheableRequest(url, options) { return new Promise((resolve, reject) => { // TODO: Remove `utils/url-to-options.ts` when `cacheable-request` is fixed Object.assign(options, urlToOptions(url)); let request; // TODO: Fix `cacheable-response`. This is ugly. const cacheRequest = cacheableStore.get(options.cache)(options, async (response) => { response._readableState.autoDestroy = false; if (request) { const fix = () => { if (response.req) { response.complete = response.req.res.complete; } }; response.prependOnceListener('end', fix); fix(); (await request).emit('cacheableResponse', response); } resolve(response); }); cacheRequest.once('error', reject); cacheRequest.once('request', async (requestOrPromise) => { request = requestOrPromise; resolve(request); }); }); } async _makeRequest() { const { options } = this; const { headers, username, password } = options; const cookieJar = options.cookieJar; for (const key in headers) { if (dist.undefined(headers[key])) { // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete headers[key]; } else if (dist.null_(headers[key])) { throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${key}\` header`); } } if (options.decompress && dist.undefined(headers['accept-encoding'])) { headers['accept-encoding'] = supportsBrotli ? 'gzip, deflate, br' : 'gzip, deflate'; } if (username || password) { const credentials = external_node_buffer_.Buffer.from(`${username}:${password}`).toString('base64'); headers.authorization = `Basic ${credentials}`; } // Set cookies if (cookieJar) { const cookieString = await cookieJar.getCookieString(options.url.toString()); if (dist.nonEmptyString(cookieString)) { headers.cookie = cookieString; } } // Reset `prefixUrl` options.prefixUrl = ''; let request; for (const hook of options.hooks.beforeRequest) { // eslint-disable-next-line no-await-in-loop const result = await hook(options); if (!dist.undefined(result)) { // @ts-expect-error Skip the type mismatch to support abstract responses request = () => result; break; } } if (!request) { request = options.getRequestFunction(); } const url = options.url; this._requestOptions = options.createNativeRequestOptions(); if (options.cache) { this._requestOptions._request = request; this._requestOptions.cache = options.cache; this._requestOptions.body = options.body; this._prepareCache(options.cache); } // Cache support const fn = options.cache ? this._createCacheableRequest : request; try { // We can't do `await fn(...)`, // because stream `error` event can be emitted before `Promise.resolve()`. let requestOrResponse = fn(url, this._requestOptions); if (dist.promise(requestOrResponse)) { requestOrResponse = await requestOrResponse; } // Fallback if (dist.undefined(requestOrResponse)) { requestOrResponse = options.getFallbackRequestFunction()(url, this._requestOptions); if (dist.promise(requestOrResponse)) { requestOrResponse = await requestOrResponse; } } if (is_client_request(requestOrResponse)) { this._onRequest(requestOrResponse); } else if (this.writable) { this.once('finish', () => { void this._onResponse(requestOrResponse); }); this._sendBody(); } else { void this._onResponse(requestOrResponse); } } catch (error) { if (error instanceof types_CacheError) { throw new CacheError(error, this); } throw error; } } async _error(error) { try { if (error instanceof HTTPError && !this.options.throwHttpErrors) { // This branch can be reached only when using the Promise API // Skip calling the hooks on purpose. // See https://github.com/sindresorhus/got/issues/2103 } else { for (const hook of this.options.hooks.beforeError) { // eslint-disable-next-line no-await-in-loop error = await hook(error); } } } catch (error_) { error = new RequestError(error_.message, error_, this); } this.destroy(error); } _writeRequest(chunk, encoding, callback) { if (!this._request || this._request.destroyed) { // Probably the `ClientRequest` instance will throw return; } this._request.write(chunk, encoding, (error) => { // The `!destroyed` check is required to prevent `uploadProgress` being emitted after the stream was destroyed if (!error && !this._request.destroyed) { this._uploadedSize += external_node_buffer_.Buffer.byteLength(chunk, encoding); const progress = this.uploadProgress; if (progress.percent < 1) { this.emit('uploadProgress', progress); } } callback(error); }); } /** The remote IP address. */ get ip() { return this.socket?.remoteAddress; } /** Indicates whether the request has been aborted or not. */ get isAborted() { return this._aborted; } get socket() { return this._request?.socket ?? undefined; } /** Progress event for downloading (receiving a response). */ get downloadProgress() { let percent; if (this._responseSize) { percent = this._downloadedSize / this._responseSize; } else if (this._responseSize === this._downloadedSize) { percent = 1; } else { percent = 0; } return { percent, transferred: this._downloadedSize, total: this._responseSize, }; } /** Progress event for uploading (sending a request). */ get uploadProgress() { let percent; if (this._bodySize) { percent = this._uploadedSize / this._bodySize; } else if (this._bodySize === this._uploadedSize) { percent = 1; } else { percent = 0; } return { percent, transferred: this._uploadedSize, total: this._bodySize, }; } /** The object contains the following properties: - `start` - Time when the request started. - `socket` - Time when a socket was assigned to the request. - `lookup` - Time when the DNS lookup finished. - `connect` - Time when the socket successfully connected. - `secureConnect` - Time when the socket securely connected. - `upload` - Time when the request finished uploading. - `response` - Time when the request fired `response` event. - `end` - Time when the response fired `end` event. - `error` - Time when the request fired `error` event. - `abort` - Time when the request fired `abort` event. - `phases` - `wait` - `timings.socket - timings.start` - `dns` - `timings.lookup - timings.socket` - `tcp` - `timings.connect - timings.lookup` - `tls` - `timings.secureConnect - timings.connect` - `request` - `timings.upload - (timings.secureConnect || timings.connect)` - `firstByte` - `timings.response - timings.upload` - `download` - `timings.end - timings.response` - `total` - `(timings.end || timings.error || timings.abort) - timings.start` If something has not been measured yet, it will be `undefined`. __Note__: The time is a `number` representing the milliseconds elapsed since the UNIX epoch. */ get timings() { return this._request?.timings; } /** Whether the response was retrieved from the cache. */ get isFromCache() { return this._isFromCache; } get reusedSocket() { return this._request?.reusedSocket; } } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/as-promise/types.js /** An error to be thrown when the request is aborted with `.cancel()`. */ class types_CancelError extends RequestError { constructor(request) { super('Promise was canceled', {}, request); this.name = 'CancelError'; this.code = 'ERR_CANCELED'; } /** Whether the promise is canceled. */ get isCanceled() { return true; } } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/as-promise/index.js const as_promise_proxiedRequestEvents = [ 'request', 'response', 'redirect', 'uploadProgress', 'downloadProgress', ]; function asPromise(firstRequest) { let globalRequest; let globalResponse; let normalizedOptions; const emitter = new external_node_events_.EventEmitter(); const promise = new PCancelable((resolve, reject, onCancel) => { onCancel(() => { globalRequest.destroy(); }); onCancel.shouldReject = false; onCancel(() => { reject(new types_CancelError(globalRequest)); }); const makeRequest = (retryCount) => { // Errors when a new request is made after the promise settles. // Used to detect a race condition. // See https://github.com/sindresorhus/got/issues/1489 onCancel(() => { }); const request = firstRequest ?? new Request(undefined, undefined, normalizedOptions); request.retryCount = retryCount; request._noPipe = true; globalRequest = request; request.once('response', async (response) => { // Parse body const contentEncoding = (response.headers['content-encoding'] ?? '').toLowerCase(); const isCompressed = contentEncoding === 'gzip' || contentEncoding === 'deflate' || contentEncoding === 'br'; const { options } = request; if (isCompressed && !options.decompress) { response.body = response.rawBody; } else { try { response.body = parseBody(response, options.responseType, options.parseJson, options.encoding); } catch (error) { // Fall back to `utf8` response.body = response.rawBody.toString(); if (isResponseOk(response)) { request._beforeError(error); return; } } } try { const hooks = options.hooks.afterResponse; for (const [index, hook] of hooks.entries()) { // @ts-expect-error TS doesn't notice that CancelableRequest is a Promise // eslint-disable-next-line no-await-in-loop response = await hook(response, async (updatedOptions) => { options.merge(updatedOptions); options.prefixUrl = ''; if (updatedOptions.url) { options.url = updatedOptions.url; } // Remove any further hooks for that request, because we'll call them anyway. // The loop continues. We don't want duplicates (asPromise recursion). options.hooks.afterResponse = options.hooks.afterResponse.slice(0, index); throw new RetryError(request); }); if (!(dist.object(response) && dist.number(response.statusCode) && !dist.nullOrUndefined(response.body))) { throw new TypeError('The `afterResponse` hook returned an invalid value'); } } } catch (error) { request._beforeError(error); return; } globalResponse = response; if (!isResponseOk(response)) { request._beforeError(new HTTPError(response)); return; } request.destroy(); resolve(request.options.resolveBodyOnly ? response.body : response); }); const onError = (error) => { if (promise.isCanceled) { return; } const { options } = request; if (error instanceof HTTPError && !options.throwHttpErrors) { const { response } = error; request.destroy(); resolve(request.options.resolveBodyOnly ? response.body : response); return; } reject(error); }; request.once('error', onError); const previousBody = request.options?.body; request.once('retry', (newRetryCount, error) => { firstRequest = undefined; const newBody = request.options.body; if (previousBody === newBody && dist.nodeStream(newBody)) { error.message = 'Cannot retry with consumed body stream'; onError(error); return; } // This is needed! We need to reuse `request.options` because they can get modified! // For example, by calling `promise.json()`. normalizedOptions = request.options; makeRequest(newRetryCount); }); proxyEvents(request, emitter, as_promise_proxiedRequestEvents); if (dist.undefined(firstRequest)) { void request.flush(); } }; makeRequest(0); }); promise.on = (event, fn) => { emitter.on(event, fn); return promise; }; promise.off = (event, fn) => { emitter.off(event, fn); return promise; }; const shortcut = (responseType) => { const newPromise = (async () => { // Wait until downloading has ended await promise; const { options } = globalResponse.request; return parseBody(globalResponse, responseType, options.parseJson, options.encoding); })(); // eslint-disable-next-line @typescript-eslint/no-floating-promises Object.defineProperties(newPromise, Object.getOwnPropertyDescriptors(promise)); return newPromise; }; promise.json = () => { if (globalRequest.options) { const { headers } = globalRequest.options; if (!globalRequest.writableFinished && !('accept' in headers)) { headers.accept = 'application/json'; } } return shortcut('json'); }; promise.buffer = () => shortcut('buffer'); promise.text = () => shortcut('text'); return promise; } ;// CONCATENATED MODULE: ./node_modules/got/dist/source/create.js // The `delay` package weighs 10KB (!) const delay = async (ms) => new Promise(resolve => { setTimeout(resolve, ms); }); const isGotInstance = (value) => dist.function_(value); const aliases = [ 'get', 'post', 'put', 'patch', 'head', 'delete', ]; const create = (defaults) => { defaults = { options: new Options(undefined, undefined, defaults.options), handlers: [...defaults.handlers], mutableDefaults: defaults.mutableDefaults, }; Object.defineProperty(defaults, 'mutableDefaults', { enumerable: true, configurable: false, writable: false, }); // Got interface const got = ((url, options, defaultOptions = defaults.options) => { const request = new Request(url, options, defaultOptions); let promise; const lastHandler = (normalized) => { // Note: `options` is `undefined` when `new Options(...)` fails request.options = normalized; request._noPipe = !normalized.isStream; void request.flush(); if (normalized.isStream) { return request; } if (!promise) { promise = asPromise(request); } return promise; }; let iteration = 0; const iterateHandlers = (newOptions) => { const handler = defaults.handlers[iteration++] ?? lastHandler; const result = handler(newOptions, iterateHandlers); if (dist.promise(result) && !request.options.isStream) { if (!promise) { promise = asPromise(request); } if (result !== promise) { const descriptors = Object.getOwnPropertyDescriptors(promise); for (const key in descriptors) { if (key in result) { // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete descriptors[key]; } } // eslint-disable-next-line @typescript-eslint/no-floating-promises Object.defineProperties(result, descriptors); result.cancel = promise.cancel; } } return result; }; return iterateHandlers(request.options); }); got.extend = (...instancesOrOptions) => { const options = new Options(undefined, undefined, defaults.options); const handlers = [...defaults.handlers]; let mutableDefaults; for (const value of instancesOrOptions) { if (isGotInstance(value)) { options.merge(value.defaults.options); handlers.push(...value.defaults.handlers); mutableDefaults = value.defaults.mutableDefaults; } else { options.merge(value); if (value.handlers) { handlers.push(...value.handlers); } mutableDefaults = value.mutableDefaults; } } return create({ options, handlers, mutableDefaults: Boolean(mutableDefaults), }); }; // Pagination const paginateEach = (async function* (url, options) { let normalizedOptions = new Options(url, options, defaults.options); normalizedOptions.resolveBodyOnly = false; const { pagination } = normalizedOptions; assert.function_(pagination.transform); assert.function_(pagination.shouldContinue); assert.function_(pagination.filter); assert.function_(pagination.paginate); assert.number(pagination.countLimit); assert.number(pagination.requestLimit); assert.number(pagination.backoff); const allItems = []; let { countLimit } = pagination; let numberOfRequests = 0; while (numberOfRequests < pagination.requestLimit) { if (numberOfRequests !== 0) { // eslint-disable-next-line no-await-in-loop await delay(pagination.backoff); } // eslint-disable-next-line no-await-in-loop const response = (await got(undefined, undefined, normalizedOptions)); // eslint-disable-next-line no-await-in-loop const parsed = await pagination.transform(response); const currentItems = []; assert.array(parsed); for (const item of parsed) { if (pagination.filter({ item, currentItems, allItems })) { if (!pagination.shouldContinue({ item, currentItems, allItems })) { return; } yield item; if (pagination.stackAllItems) { allItems.push(item); } currentItems.push(item); if (--countLimit <= 0) { return; } } } const optionsToMerge = pagination.paginate({ response, currentItems, allItems, }); if (optionsToMerge === false) { return; } if (optionsToMerge === response.request.options) { normalizedOptions = response.request.options; } else { normalizedOptions.merge(optionsToMerge); assert.any([dist.urlInstance, dist.undefined], optionsToMerge.url); if (optionsToMerge.url !== undefined) { normalizedOptions.prefixUrl = ''; normalizedOptions.url = optionsToMerge.url; } } numberOfRequests++; } }); got.paginate = paginateEach; got.paginate.all = (async (url, options) => { const results = []; for await (const item of paginateEach(url, options)) { results.push(item); } return results; }); // For those who like very descriptive names got.paginate.each = paginateEach; // Stream API got.stream = ((url, options) => got(url, { ...options, isStream: true })); // Shortcuts for (const method of aliases) { got[method] = ((url, options) => got(url, { ...options, method })); got.stream[method] = ((url, options) => got(url, { ...options, method, isStream: true })); } if (!defaults.mutableDefaults) { Object.freeze(defaults.handlers); defaults.options.freeze(); } Object.defineProperty(got, 'defaults', { value: defaults, writable: false, configurable: false, enumerable: true, }); return got; }; /* harmony default export */ const source_create = (create); ;// CONCATENATED MODULE: ./node_modules/got/dist/source/index.js const defaults = { options: new Options(), handlers: [], mutableDefaults: false, }; const got = source_create(defaults); /* harmony default export */ const got_dist_source = (got); /***/ }) }; //# sourceMappingURL=593.index.js.map