diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3ab54b4..5fa53a0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,6 @@ on: [workflow_dispatch] jobs: release: - needs: [test] runs-on: ubuntu-latest steps: - uses: actions/setup-node@v3 diff --git a/index.js b/index.js index 2d6c19e..e5caaa1 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = { - /***/ 351: /***/ function ( + /***/ 7351: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -50,8 +50,8 @@ }; Object.defineProperty(exports, '__esModule', { value: true }); exports.issue = exports.issueCommand = void 0; - const os = __importStar(__nccwpck_require__(37)); - const utils_1 = __nccwpck_require__(278); + const os = __importStar(__nccwpck_require__(2037)); + const utils_1 = __nccwpck_require__(5278); /** * Commands * @@ -125,7 +125,7 @@ /***/ }, - /***/ 186: /***/ function ( + /***/ 2186: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -231,12 +231,12 @@ exports.exportVariable = exports.ExitCode = void 0; - const command_1 = __nccwpck_require__(351); + const command_1 = __nccwpck_require__(7351); const file_command_1 = __nccwpck_require__(717); - const utils_1 = __nccwpck_require__(278); - const os = __importStar(__nccwpck_require__(37)); - const path = __importStar(__nccwpck_require__(17)); - const oidc_utils_1 = __nccwpck_require__(41); + const utils_1 = __nccwpck_require__(5278); + const os = __importStar(__nccwpck_require__(2037)); + const path = __importStar(__nccwpck_require__(1017)); + const oidc_utils_1 = __nccwpck_require__(8041); /** * The code to exit an action */ @@ -526,7 +526,7 @@ /** * Summary exports */ - var summary_1 = __nccwpck_require__(327); + var summary_1 = __nccwpck_require__(1327); Object.defineProperty(exports, 'summary', { enumerable: true, get: function () { @@ -536,7 +536,7 @@ /** * @deprecated use core.summary */ - var summary_2 = __nccwpck_require__(327); + var summary_2 = __nccwpck_require__(1327); Object.defineProperty(exports, 'markdownSummary', { enumerable: true, get: function () { @@ -600,9 +600,9 @@ exports.issueCommand = void 0; // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ - const fs = __importStar(__nccwpck_require__(147)); - const os = __importStar(__nccwpck_require__(37)); - const utils_1 = __nccwpck_require__(278); + const fs = __importStar(__nccwpck_require__(7147)); + const os = __importStar(__nccwpck_require__(2037)); + const utils_1 = __nccwpck_require__(5278); function issueCommand(command, message) { const filePath = process.env[`GITHUB_${command}`]; if (!filePath) { @@ -627,7 +627,7 @@ /***/ }, - /***/ 41: /***/ function ( + /***/ 8041: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -671,9 +671,9 @@ }; Object.defineProperty(exports, '__esModule', { value: true }); exports.OidcClient = void 0; - const http_client_1 = __nccwpck_require__(925); - const auth_1 = __nccwpck_require__(702); - const core_1 = __nccwpck_require__(186); + const http_client_1 = __nccwpck_require__(9925); + const auth_1 = __nccwpck_require__(3702); + const core_1 = __nccwpck_require__(2186); class OidcClient { static createHttpClient(allowRetry = true, maxRetry = 10) { const requestOptions = { @@ -748,7 +748,7 @@ /***/ }, - /***/ 327: /***/ function ( + /***/ 1327: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -796,8 +796,8 @@ exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; - const os_1 = __nccwpck_require__(37); - const fs_1 = __nccwpck_require__(147); + const os_1 = __nccwpck_require__(2037); + const fs_1 = __nccwpck_require__(7147); const { access, appendFile, writeFile } = fs_1.promises; exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; exports.SUMMARY_DOCS_URL = @@ -1093,7 +1093,7 @@ /***/ }, - /***/ 278: /***/ (__unused_webpack_module, exports) => { + /***/ 5278: /***/ (__unused_webpack_module, exports) => { 'use strict'; // We use any as a valid input type @@ -1138,7 +1138,7 @@ /***/ }, - /***/ 514: /***/ function ( + /***/ 1514: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -1222,8 +1222,8 @@ }; Object.defineProperty(exports, '__esModule', { value: true }); exports.getExecOutput = exports.exec = void 0; - const string_decoder_1 = __nccwpck_require__(576); - const tr = __importStar(__nccwpck_require__(159)); + const string_decoder_1 = __nccwpck_require__(1576); + const tr = __importStar(__nccwpck_require__(8159)); /** * Exec a command. * Output will be streamed to the live console. @@ -1322,7 +1322,7 @@ /***/ }, - /***/ 159: /***/ function ( + /***/ 8159: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -1406,13 +1406,13 @@ }; Object.defineProperty(exports, '__esModule', { value: true }); exports.argStringToArray = exports.ToolRunner = void 0; - const os = __importStar(__nccwpck_require__(37)); - const events = __importStar(__nccwpck_require__(361)); - const child = __importStar(__nccwpck_require__(81)); - const path = __importStar(__nccwpck_require__(17)); - const io = __importStar(__nccwpck_require__(436)); - const ioUtil = __importStar(__nccwpck_require__(962)); - const timers_1 = __nccwpck_require__(512); + const os = __importStar(__nccwpck_require__(2037)); + const events = __importStar(__nccwpck_require__(2361)); + const child = __importStar(__nccwpck_require__(2081)); + const path = __importStar(__nccwpck_require__(1017)); + const io = __importStar(__nccwpck_require__(7436)); + const ioUtil = __importStar(__nccwpck_require__(1962)); + const timers_1 = __nccwpck_require__(9512); /* eslint-disable @typescript-eslint/unbound-method */ const IS_WINDOWS = process.platform === 'win32'; /* @@ -2045,7 +2045,7 @@ /***/ }, - /***/ 702: /***/ (__unused_webpack_module, exports) => { + /***/ 3702: /***/ (__unused_webpack_module, exports) => { 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); @@ -2110,7 +2110,7 @@ /***/ }, - /***/ 925: /***/ ( + /***/ 9925: /***/ ( __unused_webpack_module, exports, __nccwpck_require__ @@ -2118,9 +2118,9 @@ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); - const http = __nccwpck_require__(685); - const https = __nccwpck_require__(687); - const pm = __nccwpck_require__(443); + const http = __nccwpck_require__(3685); + const https = __nccwpck_require__(5687); + const pm = __nccwpck_require__(6443); let tunnel; var HttpCodes; (function (HttpCodes) { @@ -2631,7 +2631,7 @@ if (useProxy) { // If using proxy, need tunnel if (!tunnel) { - tunnel = __nccwpck_require__(294); + tunnel = __nccwpck_require__(4294); } const agentOptions = { maxSockets: maxSockets, @@ -2752,7 +2752,7 @@ /***/ }, - /***/ 443: /***/ (__unused_webpack_module, exports) => { + /***/ 6443: /***/ (__unused_webpack_module, exports) => { 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); @@ -2812,7 +2812,7 @@ /***/ }, - /***/ 962: /***/ function ( + /***/ 1962: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -2856,9 +2856,9 @@ }; var _a; Object.defineProperty(exports, '__esModule', { value: true }); - const assert_1 = __nccwpck_require__(491); - const fs = __nccwpck_require__(147); - const path = __nccwpck_require__(17); + const assert_1 = __nccwpck_require__(9491); + const fs = __nccwpck_require__(7147); + const path = __nccwpck_require__(1017); (_a = fs.promises), (exports.chmod = _a.chmod), (exports.copyFile = _a.copyFile), @@ -3059,7 +3059,7 @@ /***/ }, - /***/ 436: /***/ function ( + /***/ 7436: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -3102,10 +3102,10 @@ }); }; Object.defineProperty(exports, '__esModule', { value: true }); - const childProcess = __nccwpck_require__(81); - const path = __nccwpck_require__(17); - const util_1 = __nccwpck_require__(837); - const ioUtil = __nccwpck_require__(962); + const childProcess = __nccwpck_require__(2081); + const path = __nccwpck_require__(1017); + const util_1 = __nccwpck_require__(3837); + const ioUtil = __nccwpck_require__(1962); const exec = util_1.promisify(childProcess.exec); /** * Copies a file or folder. @@ -3391,7 +3391,2122 @@ /***/ }, - /***/ 431: /***/ ( + /***/ 7678: /***/ (module, exports) => { + 'use strict'; + + /// + /// + /// + Object.defineProperty(exports, '__esModule', { value: true }); + 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', + 'Object', + 'RegExp', + 'Date', + 'Error', + 'Map', + 'Set', + 'WeakMap', + 'WeakSet', + 'ArrayBuffer', + 'SharedArrayBuffer', + 'DataView', + 'Promise', + 'URL', + 'HTMLElement', + ...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 } = Object.prototype; + const getObjectType = (value) => { + const objectTypeName = 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'; + 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'); + 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(assertion); + }; + is.buffer = (value) => { + var _a, _b, _c, _d; + return (_d = + (_c = + (_b = + (_a = value) === null || _a === void 0 + ? void 0 + : _a.constructor) === null || _b === void 0 + ? void 0 + : _b.isBuffer) === null || _c === void 0 + ? void 0 + : _c.call(_b, value)) !== null && _d !== void 0 + ? _d + : false; + }; + is.nullOrUndefined = (value) => is.null_(value) || is.undefined(value); + is.object = (value) => + !is.null_(value) && (typeof value === 'object' || is.function_(value)); + is.iterable = (value) => { + var _a; + return is.function_( + (_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.iterator] + ); + }; + is.asyncIterable = (value) => { + var _a; + return is.function_( + (_a = value) === null || _a === void 0 + ? void 0 + : _a[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) => { + var _a, _b; + return ( + is.function_( + (_a = value) === null || _a === void 0 ? void 0 : _a.then + ) && + is.function_( + (_b = value) === null || _b === void 0 ? void 0 : _b.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); + is.weakSet = (value) => isObjectOfType('WeakSet')(value); + 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.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 (_a) { + return false; + } + }; + // TODO: Use the `not` operator with a type guard here when it's available. + // Example: `is.truthy = (value: unknown): value is (not false | not 0 | not '' | not undefined | not null) => Boolean(value);` + is.truthy = (value) => Boolean(value); + // 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/master/index.js + if (toString.call(value) !== '[object Object]') { + return false; + } + const prototype = Object.getPrototypeOf(value); + return prototype === null || prototype === Object.getPrototypeOf({}); + }; + 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)}`); + }; + const NODE_TYPE_ELEMENT = 1; + const DOM_PROPERTIES_TO_CHECK = [ + 'innerHTML', + 'ownerDocument', + 'style', + 'attributes', + 'nodeValue', + ]; + is.domElement = (value) => { + return ( + 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) => { + var _a, _b, _c, _d; + if (!value) { + return false; + } + // eslint-disable-next-line no-use-extend-native/no-use-extend-native + if ( + value === + ((_b = (_a = value)[Symbol.observable]) === null || _b === void 0 + ? void 0 + : _b.call(_a)) + ) { + return true; + } + if ( + value === + ((_d = (_c = value)['@@observable']) === null || _d === void 0 + ? void 0 + : _d.call(_c)) + ) { + return true; + } + return false; + }; + is.nodeStream = (value) => + is.object(value) && is.function_(value.pipe) && !is.observable(value); + is.infinite = (value) => value === Infinity || value === -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; + // TODO: Use `not ''` when the `not` operator is available. + is.nonEmptyString = (value) => is.string(value) && value.length > 0; + const isWhiteSpaceString = (value) => + is.string(value) && !/\S/.test(value); + is.emptyStringOrWhitespace = (value) => + is.emptyString(value) || isWhiteSpaceString(value); + 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 + 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; + is.emptyMap = (value) => is.map(value) && value.size === 0; + is.nonEmptyMap = (value) => is.map(value) && value.size > 0; + 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) => { + if (!condition) { + throw new TypeError( + `Expected value which is \`${description}\`, received value of type \`${is( + value + )}\`.` + ); + } + }; + exports.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' /* 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' /* numericString */, + value + ), + array: (value, assertion) => { + const assert = assertType; + assert(is.array(value), 'Array', value); + if (assertion) { + value.forEach(assertion); + } + }, + buffer: (value) => assertType(is.buffer(value), 'Buffer', value), + nullOrUndefined: (value) => + assertType( + is.nullOrUndefined(value), + 'null or undefined' /* nullOrUndefined */, + value + ), + object: (value) => assertType(is.object(value), 'Object', value), + iterable: (value) => + assertType(is.iterable(value), 'Iterable' /* iterable */, value), + asyncIterable: (value) => + assertType( + is.asyncIterable(value), + 'AsyncIterable' /* 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' /* 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), + 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), + urlInstance: (value) => assertType(is.urlInstance(value), 'URL', value), + urlString: (value) => + assertType( + is.urlString(value), + 'string with a URL' /* urlString */, + value + ), + truthy: (value) => + assertType(is.truthy(value), 'truthy' /* truthy */, value), + falsy: (value) => + assertType(is.falsy(value), 'falsy' /* falsy */, value), + nan: (value) => assertType(is.nan(value), 'NaN' /* nan */, value), + primitive: (value) => + assertType(is.primitive(value), 'primitive' /* primitive */, value), + integer: (value) => + assertType(is.integer(value), 'integer' /* integer */, value), + safeInteger: (value) => + assertType(is.safeInteger(value), 'integer' /* safeInteger */, value), + plainObject: (value) => + assertType( + is.plainObject(value), + 'plain object' /* plainObject */, + value + ), + typedArray: (value) => + assertType( + is.typedArray(value), + 'TypedArray' /* typedArray */, + value + ), + arrayLike: (value) => + assertType(is.arrayLike(value), 'array-like' /* arrayLike */, value), + domElement: (value) => + assertType( + is.domElement(value), + 'HTMLElement' /* domElement */, + value + ), + observable: (value) => + assertType(is.observable(value), 'Observable', value), + nodeStream: (value) => + assertType( + is.nodeStream(value), + 'Node.js Stream' /* nodeStream */, + value + ), + infinite: (value) => + assertType( + is.infinite(value), + 'infinite number' /* infinite */, + value + ), + emptyArray: (value) => + assertType( + is.emptyArray(value), + 'empty array' /* emptyArray */, + value + ), + nonEmptyArray: (value) => + assertType( + is.nonEmptyArray(value), + 'non-empty array' /* nonEmptyArray */, + value + ), + emptyString: (value) => + assertType( + is.emptyString(value), + 'empty string' /* emptyString */, + value + ), + nonEmptyString: (value) => + assertType( + is.nonEmptyString(value), + 'non-empty string' /* nonEmptyString */, + value + ), + emptyStringOrWhitespace: (value) => + assertType( + is.emptyStringOrWhitespace(value), + 'empty string or whitespace' /* emptyStringOrWhitespace */, + value + ), + emptyObject: (value) => + assertType( + is.emptyObject(value), + 'empty object' /* emptyObject */, + value + ), + nonEmptyObject: (value) => + assertType( + is.nonEmptyObject(value), + 'non-empty object' /* nonEmptyObject */, + value + ), + emptySet: (value) => + assertType(is.emptySet(value), 'empty set' /* emptySet */, value), + nonEmptySet: (value) => + assertType( + is.nonEmptySet(value), + 'non-empty set' /* nonEmptySet */, + value + ), + emptyMap: (value) => + assertType(is.emptyMap(value), 'empty map' /* emptyMap */, value), + nonEmptyMap: (value) => + assertType( + is.nonEmptyMap(value), + 'non-empty map' /* nonEmptyMap */, + value + ), + // Numbers. + evenInteger: (value) => + assertType( + is.evenInteger(value), + 'even integer' /* evenInteger */, + value + ), + oddInteger: (value) => + assertType( + is.oddInteger(value), + 'odd integer' /* oddInteger */, + value + ), + // Two arguments. + directInstanceOf: (instance, class_) => + assertType( + is.directInstanceOf(instance, class_), + 'T' /* directInstanceOf */, + instance + ), + inRange: (value, range) => + assertType(is.inRange(value, range), 'in range' /* inRange */, value), + // Variadic functions. + any: (predicate, ...values) => + assertType( + is.any(predicate, ...values), + 'predicate returns truthy for any value' /* any */, + values + ), + all: (predicate, ...values) => + assertType( + is.all(predicate, ...values), + 'predicate returns truthy for all values' /* all */, + values + ), + }; + // 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(exports.assert, { + class: { + value: exports.assert.class_, + }, + function: { + value: exports.assert.function_, + }, + null: { + value: exports.assert.null_, + }, + }); + exports['default'] = is; + // For CommonJS default export support + module.exports = is; + module.exports['default'] = is; + module.exports.assert = exports.assert; + + /***/ + }, + + /***/ 8097: /***/ (module, exports, __nccwpck_require__) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const defer_to_connect_1 = __nccwpck_require__(6214); + const nodejsMajorVersion = Number(process.versions.node.split('.')[0]); + const timer = (request) => { + 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) => { + const emit = origin.emit.bind(origin); + origin.emit = (event, ...args) => { + // Catches the `error` event + if (event === 'error') { + timings.error = Date.now(); + timings.phases.total = timings.error - timings.start; + origin.emit = emit; + } + // Saves the original behavior + return emit(event, ...args); + }; + }; + handleError(request); + request.prependOnceListener('abort', () => { + timings.abort = Date.now(); + // Let the `end` response event be responsible for setting the total phase, + // unless the Node.js major version is >= 13. + if (!timings.response || nodejsMajorVersion >= 13) { + timings.phases.total = Date.now() - timings.start; + } + }); + const onSocket = (socket) => { + timings.socket = Date.now(); + timings.phases.wait = timings.socket - timings.start; + const lookupListener = () => { + timings.lookup = Date.now(); + timings.phases.dns = timings.lookup - timings.socket; + }; + socket.prependOnceListener('lookup', lookupListener); + defer_to_connect_1.default(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; + // This callback is called before flushing any data, + // so we don't need to set `timings.phases.request` here. + }, + 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 = () => { + var _a; + timings.upload = Date.now(); + timings.phases.request = + timings.upload - + ((_a = timings.secureConnect), + _a !== null && _a !== void 0 ? _a : timings.connect); + }; + const writableFinished = () => { + if (typeof request.writableFinished === 'boolean') { + return request.writableFinished; + } + // Node.js doesn't have `request.writableFinished` property + return ( + request.finished && + request.outputSize === 0 && + (!request.socket || request.socket.writableLength === 0) + ); + }; + if (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', () => { + timings.end = Date.now(); + timings.phases.download = timings.end - timings.response; + timings.phases.total = timings.end - timings.start; + }); + }); + return timings; + }; + exports['default'] = timer; + // For CommonJS default export support + module.exports = timer; + module.exports['default'] = timer; + + /***/ + }, + + /***/ 2286: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const { + V4MAPPED, + ADDRCONFIG, + ALL, + promises: { Resolver: AsyncResolver }, + lookup: dnsLookup, + } = __nccwpck_require__(9523); + const { promisify } = __nccwpck_require__(3837); + const os = __nccwpck_require__(2037); + + const kCacheableLookupCreateConnection = Symbol( + 'cacheableLookupCreateConnection' + ); + const kCacheableLookupInstance = Symbol('cacheableLookupInstance'); + const kExpires = Symbol('expires'); + + const supportsALL = typeof 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(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 ttl = { ttl: true }; + const all = { all: true }; + + class CacheableLookup { + constructor({ + cache = new Map(), + maxTtl = Infinity, + fallbackDuration = 3600, + errorTtl = 0.15, + resolver = new AsyncResolver(), + lookup = dnsLookup, + } = {}) { + this.maxTtl = maxTtl; + this.errorTtl = errorTtl; + + this._cache = cache; + this._resolver = resolver; + this._dnsLookup = promisify(lookup); + + if (this._resolver instanceof AsyncResolver) { + this._resolve4 = this._resolver.resolve4.bind(this._resolver); + this._resolve6 = this._resolver.resolve6.bind(this._resolver); + } else { + this._resolve4 = promisify( + this._resolver.resolve4.bind(this._resolver) + ); + this._resolve6 = promisify( + this._resolver.resolve6.bind(this._resolver) + ); + } + + this._iface = getIfaceInfo(); + + this._pending = {}; + this._nextRemovalTime = false; + this._hostnamesToFallback = new Set(); + + if (fallbackDuration < 1) { + this._fallback = false; + } else { + this._fallback = true; + + 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.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 + ); + } + }, 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 & V4MAPPED) { + if ( + (supportsALL && options.hints & 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 & 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 cached = await this._cache.get(hostname); + + if (!cached) { + const pending = this._pending[hostname]; + + if (pending) { + cached = await pending; + } else { + const newPromise = this.queryAndCache(hostname); + this._pending[hostname] = newPromise; + + try { + cached = await newPromise; + } finally { + delete this._pending[hostname]; + } + } + } + + cached = cached.map((entry) => { + return { ...entry }; + }); + + return cached; + } + + async _resolve(hostname) { + const wrap = async (promise) => { + try { + return await promise; + } catch (error) { + if (error.code === 'ENODATA' || error.code === 'ENOTFOUND') { + return []; + } + + throw error; + } + }; + + // ANY is unsafe as it doesn't trigger new queries in the underlying server. + const [A, AAAA] = await Promise.all( + [this._resolve4(hostname, ttl), this._resolve6(hostname, ttl)].map( + (promise) => wrap(promise) + ) + ); + + 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 entries = await this._dnsLookup(hostname, { + all: true, + }); + + return { + entries, + 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, all); + } + + let query = await this._resolve(hostname); + + if (query.entries.length === 0 && this._fallback) { + query = await this._lookup(hostname); + + if (query.entries.length !== 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(); + } + } + + module.exports = CacheableLookup; + module.exports['default'] = CacheableLookup; + + /***/ + }, + + /***/ 7472: /***/ (module) => { + 'use strict'; + + // 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) => { + return 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}` : ''}`; + }; + + const 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, + 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 urlObj = new URL(urlString); + + if (options.forceHttp && options.forceHttps) { + throw new Error( + 'The `forceHttp` and `forceHttps` options cannot be used together' + ); + } + + if (options.forceHttp && urlObj.protocol === 'https:') { + urlObj.protocol = 'http:'; + } + + if (options.forceHttps && urlObj.protocol === 'http:') { + urlObj.protocol = 'https:'; + } + + // Remove auth + if (options.stripAuthentication) { + urlObj.username = ''; + urlObj.password = ''; + } + + // Remove hash + if (options.stripHash) { + urlObj.hash = ''; + } else if (options.stripTextFragment) { + urlObj.hash = urlObj.hash.replace(/#?:~:text.*?$/i, ''); + } + + // Remove duplicate slashes if not preceded by a protocol + if (urlObj.pathname) { + urlObj.pathname = urlObj.pathname.replace( + /(? 0 + ) { + let pathComponents = urlObj.pathname.split('/'); + const lastComponent = pathComponents[pathComponents.length - 1]; + + if (testParameter(lastComponent, options.removeDirectoryIndex)) { + pathComponents = pathComponents.slice(0, pathComponents.length - 1); + urlObj.pathname = pathComponents.slice(1).join('/') + '/'; + } + } + + if (urlObj.hostname) { + // Remove trailing dot + urlObj.hostname = urlObj.hostname.replace(/\.$/, ''); + + // Remove `www.` + if ( + options.stripWWW && + /^www\.(?!www\.)(?:[a-z\-\d]{1,63})\.(?:[a-z.\-\d]{2,63})$/.test( + urlObj.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. + urlObj.hostname = urlObj.hostname.replace(/^www\./, ''); + } + } + + // Remove query unwanted parameters + if (Array.isArray(options.removeQueryParameters)) { + for (const key of [...urlObj.searchParams.keys()]) { + if (testParameter(key, options.removeQueryParameters)) { + urlObj.searchParams.delete(key); + } + } + } + + if (options.removeQueryParameters === true) { + urlObj.search = ''; + } + + // Sort query parameters + if (options.sortQueryParameters) { + urlObj.searchParams.sort(); + } + + if (options.removeTrailingSlash) { + urlObj.pathname = urlObj.pathname.replace(/\/$/, ''); + } + + const oldUrlString = urlString; + + // Take advantage of many of the Node `url` normalizations + urlString = urlObj.toString(); + + if ( + !options.removeSingleSlash && + urlObj.pathname === '/' && + !oldUrlString.endsWith('/') && + urlObj.hash === '' + ) { + urlString = urlString.replace(/\/$/, ''); + } + + // Remove ending `/` unless removeSingleSlash is false + if ( + (options.removeTrailingSlash || urlObj.pathname === '/') && + urlObj.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; + }; + + module.exports = normalizeUrl; + + /***/ + }, + + /***/ 8116: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const EventEmitter = __nccwpck_require__(2361); + const urlLib = __nccwpck_require__(7310); + const normalizeUrl = __nccwpck_require__(7472); + const getStream = __nccwpck_require__(1766); + const CachePolicy = __nccwpck_require__(1002); + const Response = __nccwpck_require__(9004); + const lowercaseKeys = __nccwpck_require__(9662); + const cloneResponse = __nccwpck_require__(1312); + const Keyv = __nccwpck_require__(1531); + + class CacheableRequest { + constructor(request, cacheAdapter) { + if (typeof request !== 'function') { + throw new TypeError('Parameter `request` must be a function'); + } + + this.cache = new Keyv({ + uri: typeof cacheAdapter === 'string' && cacheAdapter, + store: typeof cacheAdapter !== 'string' && cacheAdapter, + namespace: 'cacheable-request', + }); + + return this.createCacheableRequest(request); + } + + createCacheableRequest(request) { + return (opts, cb) => { + let url; + if (typeof opts === 'string') { + url = normalizeUrlObject(urlLib.parse(opts)); + opts = {}; + } else if (opts instanceof urlLib.URL) { + url = normalizeUrlObject(urlLib.parse(opts.toString())); + opts = {}; + } else { + const [pathname, ...searchParts] = (opts.path || '').split('?'); + const search = + searchParts.length > 0 ? `?${searchParts.join('?')}` : ''; + url = normalizeUrlObject({ ...opts, pathname, search }); + } + + opts = { + headers: {}, + method: 'GET', + cache: true, + strictTtl: false, + automaticFailover: false, + ...opts, + ...urlObjectToRequestOptions(url), + }; + opts.headers = lowercaseKeys(opts.headers); + + const ee = new EventEmitter(); + const normalizedUrlString = normalizeUrl(urlLib.format(url), { + stripWWW: false, + removeTrailingSlash: false, + stripAuthentication: false, + }); + const key = `${opts.method}:${normalizedUrlString}`; + let revalidate = false; + let madeRequest = false; + + const makeRequest = (opts) => { + madeRequest = true; + let requestErrored = false; + let requestErrorCallback; + + const requestErrorPromise = new Promise((resolve) => { + requestErrorCallback = () => { + if (!requestErrored) { + requestErrored = true; + resolve(); + } + }; + }); + + const handler = (response) => { + if (revalidate && !opts.forceRefresh) { + response.status = response.statusCode; + const revalidatedPolicy = CachePolicy.fromObject( + revalidate.cachePolicy + ).revalidatedPolicy(opts, response); + if (!revalidatedPolicy.modified) { + const headers = revalidatedPolicy.policy.responseHeaders(); + response = new Response( + revalidate.statusCode, + headers, + revalidate.body, + revalidate.url + ); + response.cachePolicy = revalidatedPolicy.policy; + response.fromCache = true; + } + } + + if (!response.fromCache) { + response.cachePolicy = new CachePolicy(opts, response, opts); + response.fromCache = false; + } + + let clonedResponse; + if (opts.cache && response.cachePolicy.storable()) { + clonedResponse = cloneResponse(response); + + (async () => { + try { + const bodyPromise = getStream.buffer(response); + + await Promise.race([ + requestErrorPromise, + new Promise((resolve) => response.once('end', resolve)), + ]); + + if (requestErrored) { + return; + } + + const body = await bodyPromise; + + const value = { + cachePolicy: response.cachePolicy.toObject(), + url: response.url, + statusCode: response.fromCache + ? revalidate.statusCode + : response.statusCode, + body, + }; + + let ttl = opts.strictTtl + ? response.cachePolicy.timeToLive() + : undefined; + if (opts.maxTtl) { + ttl = ttl ? Math.min(ttl, opts.maxTtl) : opts.maxTtl; + } + + await this.cache.set(key, value, ttl); + } catch (error) { + ee.emit('error', new CacheableRequest.CacheError(error)); + } + })(); + } else if (opts.cache && revalidate) { + (async () => { + try { + await this.cache.delete(key); + } catch (error) { + ee.emit('error', new CacheableRequest.CacheError(error)); + } + })(); + } + + ee.emit('response', clonedResponse || response); + if (typeof cb === 'function') { + cb(clonedResponse || response); + } + }; + + try { + const req = request(opts, handler); + req.once('error', requestErrorCallback); + req.once('abort', requestErrorCallback); + ee.emit('request', req); + } catch (error) { + ee.emit('error', new CacheableRequest.RequestError(error)); + } + }; + + (async () => { + const get = async (opts) => { + await Promise.resolve(); + + const cacheEntry = opts.cache + ? await this.cache.get(key) + : undefined; + if (typeof cacheEntry === 'undefined') { + return makeRequest(opts); + } + + const policy = CachePolicy.fromObject(cacheEntry.cachePolicy); + if ( + policy.satisfiesWithoutRevalidation(opts) && + !opts.forceRefresh + ) { + const headers = policy.responseHeaders(); + const response = new Response( + cacheEntry.statusCode, + headers, + cacheEntry.body, + cacheEntry.url + ); + response.cachePolicy = policy; + response.fromCache = true; + + ee.emit('response', response); + if (typeof cb === 'function') { + cb(response); + } + } else { + revalidate = cacheEntry; + opts.headers = policy.revalidationHeaders(opts); + makeRequest(opts); + } + }; + + const errorHandler = (error) => + ee.emit('error', new CacheableRequest.CacheError(error)); + this.cache.once('error', errorHandler); + ee.on('response', () => + this.cache.removeListener('error', errorHandler) + ); + + try { + await get(opts); + } catch (error) { + if (opts.automaticFailover && !madeRequest) { + makeRequest(opts); + } + + ee.emit('error', new CacheableRequest.CacheError(error)); + } + })(); + + return ee; + }; + } + } + + function urlObjectToRequestOptions(url) { + const options = { ...url }; + options.path = `${url.pathname || '/'}${url.search || ''}`; + delete options.pathname; + delete options.search; + return options; + } + + function 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 + return { + protocol: url.protocol, + auth: url.auth, + hostname: url.hostname || url.host || 'localhost', + port: url.port, + pathname: url.pathname, + search: url.search, + }; + } + + CacheableRequest.RequestError = class extends Error { + constructor(error) { + super(error.message); + this.name = 'RequestError'; + Object.assign(this, error); + } + }; + + CacheableRequest.CacheError = class extends Error { + constructor(error) { + super(error.message); + this.name = 'CacheError'; + Object.assign(this, error); + } + }; + + module.exports = CacheableRequest; + + /***/ + }, + + /***/ 1312: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const PassThrough = __nccwpck_require__(2781).PassThrough; + const mimicResponse = __nccwpck_require__(2610); + + const cloneResponse = (response) => { + if (!(response && response.pipe)) { + throw new TypeError( + 'Parameter `response` must be a response stream.' + ); + } + + const clone = new PassThrough(); + mimicResponse(response, clone); + + return response.pipe(clone); + }; + + module.exports = cloneResponse; + + /***/ + }, + + /***/ 5728: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const { promisify } = __nccwpck_require__(3837); + const JSONB = __nccwpck_require__(2820); + const zlib = __nccwpck_require__(9796); + + const mergeOptions = __nccwpck_require__(4968); + + const compress = promisify(zlib.brotliCompress); + + const decompress = promisify(zlib.brotliDecompress); + + const identity = (val) => val; + + const createCompress = ({ + enable = true, + serialize = JSONB.stringify, + deserialize = JSONB.parse, + compressOptions, + decompressOptions, + } = {}) => { + if (!enable) { + return { + serialize, + deserialize, + decompress: identity, + compress: identity, + }; + } + + return { + serialize, + deserialize, + compress: async (data, options = {}) => { + if (data === undefined) return data; + const serializedData = serialize(data); + return compress( + serializedData, + mergeOptions(compressOptions, options) + ); + }, + decompress: async (data, options = {}) => { + if (data === undefined) return data; + return deserialize( + await decompress(data, mergeOptions(decompressOptions, options)) + ); + }, + }; + }; + + module.exports = createCompress; + module.exports.stringify = JSONB.stringify; + module.exports.parse = JSONB.parse; + + /***/ + }, + + /***/ 4968: /***/ (module) => { + 'use strict'; + + module.exports = (defaultOptions = {}, options = {}) => { + const params = { + ...(defaultOptions.params || {}), + ...(options.params || {}), + }; + + return { + ...defaultOptions, + ...options, + ...(Object.keys(params).length + ? { + params, + } + : {}), + }; + }; + + /***/ + }, + + /***/ 2391: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const { Transform, PassThrough } = __nccwpck_require__(2781); + const zlib = __nccwpck_require__(9796); + const mimicResponse = __nccwpck_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) => { + 'use strict'; + + // 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, __nccwpck_require__) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const tls_1 = __nccwpck_require__(4404); + 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 (socket instanceof tls_1.TLSSocket && 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; + + /***/ + }, + + /***/ 8431: /***/ ( __unused_webpack_module, exports, __nccwpck_require__ @@ -3441,13 +5556,13 @@ * @public */ - var fs = __nccwpck_require__(147); - var path = __nccwpck_require__(17); + var fs = __nccwpck_require__(7147); + var path = __nccwpck_require__(1017); var utils = __nccwpck_require__(356); var scopeOptionWarned = false; /** @type {string} */ - var _VERSION_STRING = __nccwpck_require__(558) /* .version */.i8; + var _VERSION_STRING = __nccwpck_require__(3558) /* .version */.i8; var _DEFAULT_OPEN_DELIMITER = '<'; var _DEFAULT_CLOSE_DELIMITER = '>'; var _DEFAULT_DELIMITER = '%'; @@ -4671,7 +6786,122 @@ /***/ }, - /***/ 171: /***/ (module) => { + /***/ 1205: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + var once = __nccwpck_require__(1223); + + var noop = function () {}; + + var isRequest = function (stream) { + return stream.setHeader && typeof stream.abort === 'function'; + }; + + var isChildProcess = function (stream) { + return ( + stream.stdio && + Array.isArray(stream.stdio) && + stream.stdio.length === 3 + ); + }; + + var eos = function (stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + + callback = once(callback || noop); + + var ws = stream._writableState; + var rs = stream._readableState; + var readable = + opts.readable || (opts.readable !== false && stream.readable); + var writable = + opts.writable || (opts.writable !== false && stream.writable); + var cancelled = false; + + var onlegacyfinish = function () { + if (!stream.writable) onfinish(); + }; + + var onfinish = function () { + writable = false; + if (!readable) callback.call(stream); + }; + + var onend = function () { + readable = false; + if (!writable) callback.call(stream); + }; + + var onexit = function (exitCode) { + callback.call( + stream, + exitCode ? new Error('exited with error code: ' + exitCode) : null + ); + }; + + var onerror = function (err) { + callback.call(stream, err); + }; + + var onclose = function () { + process.nextTick(onclosenexttick); + }; + + var onclosenexttick = function () { + if (cancelled) return; + if (readable && !(rs && rs.ended && !rs.destroyed)) + return callback.call(stream, new Error('premature close')); + if (writable && !(ws && ws.ended && !ws.destroyed)) + return callback.call(stream, new Error('premature close')); + }; + + var onrequest = function () { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { + // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + + if (isChildProcess(stream)) stream.on('exit', onexit); + + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); + + return function () { + cancelled = true; + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('exit', onexit); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; + }; + + module.exports = eos; + + /***/ + }, + + /***/ 8171: /***/ (module) => { 'use strict'; var hasOwn = Object.prototype.hasOwnProperty; @@ -4808,12 +7038,336 @@ /***/ }, + /***/ 1585: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const { PassThrough: PassThroughStream } = __nccwpck_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; + }; + + /***/ + }, + + /***/ 1766: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const { constants: BufferConstants } = __nccwpck_require__(4300); + const pump = __nccwpck_require__(8341); + const bufferStream = __nccwpck_require__(1585); + + class MaxBufferError extends Error { + constructor() { + super('maxBuffer exceeded'); + this.name = 'MaxBufferError'; + } + } + + async function getStream(inputStream, options) { + if (!inputStream) { + return Promise.reject(new Error('Expected a stream')); + } + + options = { + maxBuffer: Infinity, + ...options, + }; + + const { maxBuffer } = options; + + let stream; + 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); + }; + + stream = pump(inputStream, bufferStream(options), (error) => { + if (error) { + rejectPromise(error); + return; + } + + resolve(); + }); + + stream.on('data', () => { + if (stream.getBufferedLength() > maxBuffer) { + rejectPromise(new MaxBufferError()); + } + }); + }); + + return stream.getBufferedValue(); + } + + module.exports = getStream; + // TODO: Remove this for the next major release + module.exports['default'] = 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; + + /***/ + }, + + /***/ 7094: /***/ function ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) { + 'use strict'; + + var __importDefault = + (this && this.__importDefault) || + function (mod) { + return mod && mod.__esModule ? mod : { default: mod }; + }; + Object.defineProperty(exports, '__esModule', { value: true }); + exports.createClient = void 0; + const got_1 = __importDefault(__nccwpck_require__(3061)); + function wait(time) { + return new Promise((resolve) => { + const tid = setTimeout(() => { + resolve(); + clearTimeout(tid); + }, time); + }); + } + function rand(min, max) { + // min and max included + return Math.floor(Math.random() * (max - min + 1) + min); + } + const DEFAULT_OPTIONS = { + prefixUrl: 'https://api.github.com', + responseType: 'json', + hooks: { + beforeRequest: [ + async () => { + // reduce rate limits + await wait(rand(10, 25)); + }, + ], + }, + }; + const client = got_1.default.extend(DEFAULT_OPTIONS); + const createClient = (opts) => { + return client.extend(opts || {}); + }; + exports.createClient = createClient; + + /***/ + }, + + /***/ 6636: /***/ function ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) { + 'use strict'; + + var __importDefault = + (this && this.__importDefault) || + function (mod) { + return mod && mod.__esModule ? mod : { default: mod }; + }; + Object.defineProperty(exports, '__esModule', { value: true }); + exports.setHttpClient = exports.getNextPage = void 0; + const parse_link_header_1 = __importDefault(__nccwpck_require__(1940)); + const client_1 = __nccwpck_require__(7094); + function getNextPage({ next, last }) { + if (!next || !last) return null; + if (!next?.page || !last?.page) return null; + if (next.page === last.page) return null; + return next.page; + } + exports.getNextPage = getNextPage; + async function* paginateStars(url, opts) { + let nextPage = '1'; + while (nextPage) { + try { + const { headers, body } = await opts.http.get(url, { + searchParams: { + per_page: 100, + page: nextPage, + }, + }); + for (const record of body) { + yield record; + } + nextPage = getNextPage( + (0, parse_link_header_1.default)(headers.link) + ); + if (!opts.accessToken) { + console.warn( + 'No github access token provided, limiting call to first page to avoid rate limit ban' + ); + break; + } + } catch (e) { + console.error('[http-error]:', e?.response?.body || e); + break; + } + } + } + async function apiGetStar(opts) { + const data = []; + const API_STARRED_URL = `users/${opts.username}/starred`; + for await (const star of paginateStars(API_STARRED_URL, opts)) { + data.push(star); + } + if (!opts.compactByLanguage) { + if (typeof opts.transform !== 'function') return data; + return data.map((star) => opts.transform(star)); + } + const sorted = data.reduce((acc, val) => { + const language = val.language || 'miscellaneous'; + const parsed = + typeof opts.transform !== 'function' ? val : opts.transform(val); + if (!acc[language]) { + acc[language] = [parsed]; + } else { + acc[language].push(parsed); + } + return acc; + }, {}); + return sorted; + } + function transform(star) { + return { + id: star.id, + node_id: star.node_id, + name: star.name, + full_name: star.full_name, + owner: { + login: star?.owner?.login, + id: star?.owner?.id, + avatar_url: star?.owner?.avatar_url, + url: star?.owner?.url, + html_url: star?.owner?.html_url, + }, + html_url: star.html_url, + description: star.description, + url: star.url, + languages_url: star.languages_url, + created_at: star.created_at, + updated_at: star.updated_at, + git_url: star.git_url, + ssh_url: star.ssh_url, + clone_url: star.clone_url, + homepage: star.homepage, + stargazers_count: star.stargazers_count, + watchers_count: star.watchers_count, + language: star.language, + topics: star.topics, + }; + } + const DEFAULT_OPTIONS = { + accessToken: process.env.GITHUB_TOKEN, + username: process.env.GITHUB_USERNAME, + compactByLanguage: false, + transform, + }; + function setHttpClient(opts) { + // http is provided in opts in test cases env + if (opts.http) return opts.http; + const headers = {}; + if (opts.accessToken) { + headers.Authorization = `token ${opts.accessToken}`; + } + return (0, client_1.createClient)({ headers }); + } + exports.setHttpClient = setHttpClient; + async function main(options) { + const http = setHttpClient(options); + const opts = Object.assign({}, DEFAULT_OPTIONS, options, { + http, + }); + if (!options.username) { + try { + const { login } = await http.get('user').json(); + options.username = login; + } catch { + throw new Error('[options.username] is not set'); + } + } + return apiGetStar(opts); + } + exports['default'] = main; + + /***/ + }, + /***/ 237: /***/ ( module, __unused_webpack_exports, __nccwpck_require__ ) => { - const regex = __nccwpck_require__(205); + const regex = __nccwpck_require__(7205); module.exports = BananaSlug; @@ -4867,7 +7421,7 @@ /***/ }, - /***/ 205: /***/ (module) => { + /***/ 7205: /***/ (module) => { // This module is generated by `script/`. /* eslint-disable no-control-regex, no-misleading-character-class, no-useless-escape */ module.exports = @@ -4876,30 +7430,6741 @@ /***/ }, - /***/ 294: /***/ ( - module, - __unused_webpack_exports, - __nccwpck_require__ - ) => { - module.exports = __nccwpck_require__(219); - - /***/ - }, - - /***/ 219: /***/ ( + /***/ 6457: /***/ ( __unused_webpack_module, exports, __nccwpck_require__ ) => { 'use strict'; - var net = __nccwpck_require__(808); - var tls = __nccwpck_require__(404); - var http = __nccwpck_require__(685); - var https = __nccwpck_require__(687); - var events = __nccwpck_require__(361); - var assert = __nccwpck_require__(491); - var util = __nccwpck_require__(837); + Object.defineProperty(exports, '__esModule', { value: true }); + const types_1 = __nccwpck_require__(4597); + function createRejection(error, ...beforeErrorGroups) { + const promise = (async () => { + if (error instanceof types_1.RequestError) { + try { + for (const hooks of beforeErrorGroups) { + if (hooks) { + for (const hook of hooks) { + // eslint-disable-next-line no-await-in-loop + error = await hook(error); + } + } + } + } catch (error_) { + error = error_; + } + } + throw error; + })(); + const returnPromise = () => promise; + promise.json = returnPromise; + promise.text = returnPromise; + promise.buffer = returnPromise; + promise.on = returnPromise; + return promise; + } + exports['default'] = createRejection; + + /***/ + }, + + /***/ 6056: /***/ function ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) { + 'use strict'; + + var __createBinding = + (this && this.__createBinding) || + (Object.create + ? function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: function () { + return m[k]; + }, + }); + } + : function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + var __exportStar = + (this && this.__exportStar) || + function (m, exports) { + for (var p in m) + if ( + p !== 'default' && + !Object.prototype.hasOwnProperty.call(exports, p) + ) + __createBinding(exports, m, p); + }; + Object.defineProperty(exports, '__esModule', { value: true }); + const events_1 = __nccwpck_require__(2361); + const is_1 = __nccwpck_require__(7678); + const PCancelable = __nccwpck_require__(9072); + const types_1 = __nccwpck_require__(4597); + const parse_body_1 = __nccwpck_require__(8220); + const core_1 = __nccwpck_require__(94); + const proxy_events_1 = __nccwpck_require__(3021); + const get_buffer_1 = __nccwpck_require__(4500); + const is_response_ok_1 = __nccwpck_require__(9298); + const proxiedRequestEvents = [ + 'request', + 'response', + 'redirect', + 'uploadProgress', + 'downloadProgress', + ]; + function asPromise(normalizedOptions) { + let globalRequest; + let globalResponse; + const emitter = new events_1.EventEmitter(); + const promise = new PCancelable((resolve, reject, onCancel) => { + const makeRequest = (retryCount) => { + const request = new core_1.default(undefined, normalizedOptions); + request.retryCount = retryCount; + request._noPipe = true; + onCancel(() => request.destroy()); + onCancel.shouldReject = false; + onCancel(() => reject(new types_1.CancelError(request))); + globalRequest = request; + request.once('response', async (response) => { + var _a; + response.retryCount = retryCount; + if (response.request.aborted) { + // Canceled while downloading - will throw a `CancelError` or `TimeoutError` error + return; + } + // Download body + let rawBody; + try { + rawBody = await get_buffer_1.default(request); + response.rawBody = rawBody; + } catch (_b) { + // The same error is caught below. + // See request.once('error') + return; + } + if (request._isAboutToError) { + return; + } + // Parse body + const contentEncoding = ( + (_a = response.headers['content-encoding']) !== null && + _a !== void 0 + ? _a + : '' + ).toLowerCase(); + const isCompressed = ['gzip', 'deflate', 'br'].includes( + contentEncoding + ); + const { options } = request; + if (isCompressed && !options.decompress) { + response.body = rawBody; + } else { + try { + response.body = parse_body_1.default( + response, + options.responseType, + options.parseJson, + options.encoding + ); + } catch (error) { + // Fallback to `utf8` + response.body = rawBody.toString(); + if (is_response_ok_1.isResponseOk(response)) { + request._beforeError(error); + return; + } + } + } + try { + for (const [ + index, + hook, + ] of options.hooks.afterResponse.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) => { + const typedOptions = core_1.default.normalizeArguments( + undefined, + { + ...updatedOptions, + retry: { + calculateDelay: () => 0, + }, + throwHttpErrors: false, + resolveBodyOnly: false, + }, + options + ); + // Remove any further hooks for that request, because we'll call them anyway. + // The loop continues. We don't want duplicates (asPromise recursion). + typedOptions.hooks.afterResponse = + typedOptions.hooks.afterResponse.slice(0, index); + for (const hook of typedOptions.hooks.beforeRetry) { + // eslint-disable-next-line no-await-in-loop + await hook(typedOptions); + } + const promise = asPromise(typedOptions); + onCancel(() => { + promise.catch(() => {}); + promise.cancel(); + }); + return promise; + }); + } + } catch (error) { + request._beforeError( + new types_1.RequestError(error.message, error, request) + ); + return; + } + if (!is_response_ok_1.isResponseOk(response)) { + request._beforeError(new types_1.HTTPError(response)); + return; + } + globalResponse = response; + resolve( + request.options.resolveBodyOnly ? response.body : response + ); + }); + const onError = (error) => { + if (promise.isCanceled) { + return; + } + const { options } = request; + if ( + error instanceof types_1.HTTPError && + !options.throwHttpErrors + ) { + const { response } = error; + resolve( + request.options.resolveBodyOnly ? response.body : response + ); + return; + } + reject(error); + }; + request.once('error', onError); + const previousBody = request.options.body; + request.once('retry', (newRetryCount, error) => { + var _a, _b; + if ( + previousBody === + ((_a = error.request) === null || _a === void 0 + ? void 0 + : _a.options.body) && + is_1.default.nodeStream( + (_b = error.request) === null || _b === void 0 + ? void 0 + : _b.options.body + ) + ) { + onError(error); + return; + } + makeRequest(newRetryCount); + }); + proxy_events_1.default(request, emitter, proxiedRequestEvents); + }; + makeRequest(0); + }); + promise.on = (event, fn) => { + emitter.on(event, fn); + return promise; + }; + const shortcut = (responseType) => { + const newPromise = (async () => { + // Wait until downloading has ended + await promise; + const { options } = globalResponse.request; + return parse_body_1.default( + globalResponse, + responseType, + options.parseJson, + options.encoding + ); + })(); + Object.defineProperties( + newPromise, + Object.getOwnPropertyDescriptors(promise) + ); + return newPromise; + }; + promise.json = () => { + const { headers } = globalRequest.options; + if (!globalRequest.writableFinished && headers.accept === undefined) { + headers.accept = 'application/json'; + } + return shortcut('json'); + }; + promise.buffer = () => shortcut('buffer'); + promise.text = () => shortcut('text'); + return promise; + } + exports['default'] = asPromise; + __exportStar(__nccwpck_require__(4597), exports); + + /***/ + }, + + /***/ 1048: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const is_1 = __nccwpck_require__(7678); + const normalizeArguments = (options, defaults) => { + if (is_1.default.null_(options.encoding)) { + throw new TypeError( + 'To get a Buffer, set `options.responseType` to `buffer` instead' + ); + } + is_1.assert.any( + [is_1.default.string, is_1.default.undefined], + options.encoding + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.resolveBodyOnly + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.methodRewriting + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.isStream + ); + is_1.assert.any( + [is_1.default.string, is_1.default.undefined], + options.responseType + ); + // `options.responseType` + if (options.responseType === undefined) { + options.responseType = 'text'; + } + // `options.retry` + const { retry } = options; + if (defaults) { + options.retry = { ...defaults.retry }; + } else { + options.retry = { + calculateDelay: (retryObject) => retryObject.computedValue, + limit: 0, + methods: [], + statusCodes: [], + errorCodes: [], + maxRetryAfter: undefined, + }; + } + if (is_1.default.object(retry)) { + options.retry = { + ...options.retry, + ...retry, + }; + options.retry.methods = [ + ...new Set( + options.retry.methods.map((method) => method.toUpperCase()) + ), + ]; + options.retry.statusCodes = [...new Set(options.retry.statusCodes)]; + options.retry.errorCodes = [...new Set(options.retry.errorCodes)]; + } else if (is_1.default.number(retry)) { + options.retry.limit = retry; + } + if (is_1.default.undefined(options.retry.maxRetryAfter)) { + options.retry.maxRetryAfter = Math.min( + // TypeScript is not smart enough to handle `.filter(x => is.number(x))`. + // eslint-disable-next-line unicorn/no-fn-reference-in-iterator + ...[options.timeout.request, options.timeout.connect].filter( + is_1.default.number + ) + ); + } + // `options.pagination` + if (is_1.default.object(options.pagination)) { + if (defaults) { + options.pagination = { + ...defaults.pagination, + ...options.pagination, + }; + } + const { pagination } = options; + if (!is_1.default.function_(pagination.transform)) { + throw new Error( + '`options.pagination.transform` must be implemented' + ); + } + if (!is_1.default.function_(pagination.shouldContinue)) { + throw new Error( + '`options.pagination.shouldContinue` must be implemented' + ); + } + if (!is_1.default.function_(pagination.filter)) { + throw new TypeError( + '`options.pagination.filter` must be implemented' + ); + } + if (!is_1.default.function_(pagination.paginate)) { + throw new Error( + '`options.pagination.paginate` must be implemented' + ); + } + } + // JSON mode + if ( + options.responseType === 'json' && + options.headers.accept === undefined + ) { + options.headers.accept = 'application/json'; + } + return options; + }; + exports['default'] = normalizeArguments; + + /***/ + }, + + /***/ 8220: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const types_1 = __nccwpck_require__(4597); + 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()); + } + if (responseType === 'buffer') { + return rawBody; + } + throw new types_1.ParseError( + { + message: `Unknown body type '${responseType}'`, + name: 'Error', + }, + response + ); + } catch (error) { + throw new types_1.ParseError(error, response); + } + }; + exports['default'] = parseBody; + + /***/ + }, + + /***/ 4597: /***/ function ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) { + 'use strict'; + + var __createBinding = + (this && this.__createBinding) || + (Object.create + ? function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: function () { + return m[k]; + }, + }); + } + : function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + var __exportStar = + (this && this.__exportStar) || + function (m, exports) { + for (var p in m) + if ( + p !== 'default' && + !Object.prototype.hasOwnProperty.call(exports, p) + ) + __createBinding(exports, m, p); + }; + Object.defineProperty(exports, '__esModule', { value: true }); + exports.CancelError = exports.ParseError = void 0; + const core_1 = __nccwpck_require__(94); + /** +An error to be thrown when server response code is 2xx, and parsing body fails. +Includes a `response` property. +*/ + class ParseError extends core_1.RequestError { + constructor(error, response) { + const { options } = response.request; + super( + `${error.message} in "${options.url.toString()}"`, + error, + response.request + ); + this.name = 'ParseError'; + this.code = + this.code === 'ERR_GOT_REQUEST_ERROR' + ? 'ERR_BODY_PARSE_FAILURE' + : this.code; + } + } + exports.ParseError = ParseError; + /** +An error to be thrown when the request is aborted with `.cancel()`. +*/ + class CancelError extends core_1.RequestError { + constructor(request) { + super('Promise was canceled', {}, request); + this.name = 'CancelError'; + this.code = 'ERR_CANCELED'; + } + get isCanceled() { + return true; + } + } + exports.CancelError = CancelError; + __exportStar(__nccwpck_require__(94), exports); + + /***/ + }, + + /***/ 3462: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + exports.retryAfterStatusCodes = void 0; + exports.retryAfterStatusCodes = new Set([413, 429, 503]); + const calculateRetryDelay = ({ + attemptCount, + retryOptions, + error, + retryAfter, + }) => { + 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) { + if ( + retryOptions.maxRetryAfter === undefined || + retryAfter > retryOptions.maxRetryAfter + ) { + return 0; + } + return retryAfter; + } + if (error.response.statusCode === 413) { + return 0; + } + } + const noise = Math.random() * 100; + return 2 ** (attemptCount - 1) * 1000 + noise; + }; + exports['default'] = calculateRetryDelay; + + /***/ + }, + + /***/ 94: /***/ (__unused_webpack_module, exports, __nccwpck_require__) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + exports.UnsupportedProtocolError = + exports.ReadError = + exports.TimeoutError = + exports.UploadError = + exports.CacheError = + exports.HTTPError = + exports.MaxRedirectsError = + exports.RequestError = + exports.setNonEnumerableProperties = + exports.knownHookEvents = + exports.withoutBody = + exports.kIsNormalizedAlready = + void 0; + const util_1 = __nccwpck_require__(3837); + const stream_1 = __nccwpck_require__(2781); + const fs_1 = __nccwpck_require__(7147); + const url_1 = __nccwpck_require__(7310); + const http = __nccwpck_require__(3685); + const http_1 = __nccwpck_require__(3685); + const https = __nccwpck_require__(5687); + const http_timer_1 = __nccwpck_require__(8097); + const cacheable_lookup_1 = __nccwpck_require__(2286); + const CacheableRequest = __nccwpck_require__(8116); + const decompressResponse = __nccwpck_require__(2391); + // @ts-expect-error Missing types + const http2wrapper = __nccwpck_require__(4645); + const lowercaseKeys = __nccwpck_require__(9662); + const is_1 = __nccwpck_require__(7678); + const get_body_size_1 = __nccwpck_require__(4564); + const is_form_data_1 = __nccwpck_require__(40); + const proxy_events_1 = __nccwpck_require__(3021); + const timed_out_1 = __nccwpck_require__(2454); + const url_to_options_1 = __nccwpck_require__(8026); + const options_to_url_1 = __nccwpck_require__(9219); + const weakable_map_1 = __nccwpck_require__(7288); + const get_buffer_1 = __nccwpck_require__(4500); + const dns_ip_version_1 = __nccwpck_require__(4993); + const is_response_ok_1 = __nccwpck_require__(9298); + const deprecation_warning_1 = __nccwpck_require__(397); + const normalize_arguments_1 = __nccwpck_require__(1048); + const calculate_retry_delay_1 = __nccwpck_require__(3462); + let globalDnsCache; + const kRequest = Symbol('request'); + const kResponse = Symbol('response'); + const kResponseSize = Symbol('responseSize'); + const kDownloadedSize = Symbol('downloadedSize'); + const kBodySize = Symbol('bodySize'); + const kUploadedSize = Symbol('uploadedSize'); + const kServerResponsesPiped = Symbol('serverResponsesPiped'); + const kUnproxyEvents = Symbol('unproxyEvents'); + const kIsFromCache = Symbol('isFromCache'); + const kCancelTimeouts = Symbol('cancelTimeouts'); + const kStartedReading = Symbol('startedReading'); + const kStopReading = Symbol('stopReading'); + const kTriggerRead = Symbol('triggerRead'); + const kBody = Symbol('body'); + const kJobs = Symbol('jobs'); + const kOriginalResponse = Symbol('originalResponse'); + const kRetryTimeout = Symbol('retryTimeout'); + exports.kIsNormalizedAlready = Symbol('isNormalizedAlready'); + const supportsBrotli = is_1.default.string(process.versions.brotli); + exports.withoutBody = new Set(['GET', 'HEAD']); + exports.knownHookEvents = [ + 'init', + 'beforeRequest', + 'beforeRedirect', + 'beforeError', + 'beforeRetry', + // Promise-Only + 'afterResponse', + ]; + function validateSearchParameters(searchParameters) { + // eslint-disable-next-line guard-for-in + for (const key in searchParameters) { + const value = searchParameters[key]; + if ( + !is_1.default.string(value) && + !is_1.default.number(value) && + !is_1.default.boolean(value) && + !is_1.default.null_(value) && + !is_1.default.undefined(value) + ) { + throw new TypeError( + `The \`searchParams\` value '${String( + value + )}' must be a string, number, boolean or null` + ); + } + } + } + function isClientRequest(clientRequest) { + return ( + is_1.default.object(clientRequest) && !('statusCode' in clientRequest) + ); + } + const cacheableStore = new weakable_map_1.default(); + const waitForOpenFile = async (file) => + new Promise((resolve, reject) => { + const onError = (error) => { + reject(error); + }; + // Node.js 12 has incomplete types + if (!file.pending) { + resolve(); + } + file.once('error', onError); + file.once('ready', () => { + file.off('error', onError); + resolve(); + }); + }); + const redirectCodes = new Set([300, 301, 302, 303, 304, 307, 308]); + const nonEnumerableProperties = ['context', 'body', 'json', 'form']; + exports.setNonEnumerableProperties = (sources, to) => { + // Non enumerable properties shall not be merged + const properties = {}; + for (const source of sources) { + if (!source) { + continue; + } + for (const name of nonEnumerableProperties) { + if (!(name in source)) { + continue; + } + properties[name] = { + writable: true, + configurable: true, + enumerable: false, + // @ts-expect-error TS doesn't see the check above + value: source[name], + }; + } + } + Object.defineProperties(to, properties); + }; + /** +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) { + var _a, _b; + super(message); + Error.captureStackTrace(this, this.constructor); + this.name = 'RequestError'; + this.code = + (_a = error.code) !== null && _a !== void 0 + ? _a + : 'ERR_GOT_REQUEST_ERROR'; + if (self instanceof Request) { + Object.defineProperty(this, 'request', { + enumerable: false, + value: self, + }); + Object.defineProperty(this, 'response', { + enumerable: false, + value: self[kResponse], + }); + Object.defineProperty(this, 'options', { + // This fails because of TS 3.7.2 useDefineForClassFields + // Ref: https://github.com/microsoft/TypeScript/issues/34972 + enumerable: false, + value: self.options, + }); + } else { + Object.defineProperty(this, 'options', { + // This fails because of TS 3.7.2 useDefineForClassFields + // Ref: https://github.com/microsoft/TypeScript/issues/34972 + enumerable: false, + value: self, + }); + } + this.timings = + (_b = this.request) === null || _b === void 0 ? void 0 : _b.timings; + // Recover the original stacktrace + if ( + is_1.default.string(error.stack) && + is_1.default.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')}`; + } + } + } + exports.RequestError = RequestError; + /** +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'; + } + } + exports.MaxRedirectsError = MaxRedirectsError; + /** +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. +*/ + 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'; + } + } + exports.HTTPError = HTTPError; + /** +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; + } + } + exports.CacheError = CacheError; + /** +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; + } + } + exports.UploadError = UploadError; + /** +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); + this.name = 'TimeoutError'; + this.event = error.event; + this.timings = timings; + } + } + exports.TimeoutError = TimeoutError; + /** +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; + } + } + exports.ReadError = ReadError; + /** +An error to be thrown when given an unsupported protocol. +*/ + class UnsupportedProtocolError extends RequestError { + constructor(options) { + super(`Unsupported protocol "${options.url.protocol}"`, {}, options); + this.name = 'UnsupportedProtocolError'; + this.code = 'ERR_UNSUPPORTED_PROTOCOL'; + } + } + exports.UnsupportedProtocolError = UnsupportedProtocolError; + const proxiedRequestEvents = [ + 'socket', + 'connect', + 'continue', + 'information', + 'upgrade', + 'timeout', + ]; + class Request extends stream_1.Duplex { + constructor(url, options = {}, defaults) { + super({ + // This must be false, to enable throwing after destroy + // It is used for retry logic in Promise API + autoDestroy: false, + // It needs to be zero because we're just proxying the data to another stream + highWaterMark: 0, + }); + this[kDownloadedSize] = 0; + this[kUploadedSize] = 0; + this.requestInitialized = false; + this[kServerResponsesPiped] = new Set(); + this.redirects = []; + this[kStopReading] = false; + this[kTriggerRead] = false; + this[kJobs] = []; + this.retryCount = 0; + // TODO: Remove this when targeting Node.js >= 12 + this._progressCallbacks = []; + const unlockWrite = () => this._unlockWrite(); + const lockWrite = () => this._lockWrite(); + this.on('pipe', (source) => { + source.prependListener('data', unlockWrite); + source.on('data', lockWrite); + source.prependListener('end', unlockWrite); + source.on('end', lockWrite); + }); + this.on('unpipe', (source) => { + source.off('data', unlockWrite); + source.off('data', lockWrite); + source.off('end', unlockWrite); + source.off('end', lockWrite); + }); + this.on('pipe', (source) => { + if (source instanceof http_1.IncomingMessage) { + this.options.headers = { + ...source.headers, + ...this.options.headers, + }; + } + }); + const { json, body, form } = options; + if (json || body || form) { + this._lockWrite(); + } + if (exports.kIsNormalizedAlready in options) { + this.options = options; + } else { + try { + // @ts-expect-error Common TypeScript bug saying that `this.constructor` is not accessible + this.options = this.constructor.normalizeArguments( + url, + options, + defaults + ); + } catch (error) { + // TODO: Move this to `_destroy()` + if (is_1.default.nodeStream(options.body)) { + options.body.destroy(); + } + this.destroy(error); + return; + } + } + (async () => { + var _a; + try { + if (this.options.body instanceof fs_1.ReadStream) { + await waitForOpenFile(this.options.body); + } + const { url: normalizedURL } = this.options; + if (!normalizedURL) { + throw new TypeError('Missing `url` property'); + } + this.requestUrl = normalizedURL.toString(); + decodeURI(this.requestUrl); + await this._finalizeBody(); + await this._makeRequest(); + if (this.destroyed) { + (_a = this[kRequest]) === null || _a === void 0 + ? void 0 + : _a.destroy(); + return; + } + // Queued writes etc. + for (const job of this[kJobs]) { + job(); + } + // Prevent memory leak + this[kJobs].length = 0; + this.requestInitialized = true; + } catch (error) { + if (error instanceof RequestError) { + this._beforeError(error); + return; + } + // This is a workaround for https://github.com/nodejs/node/issues/33335 + if (!this.destroyed) { + this.destroy(error); + } + } + })(); + } + static normalizeArguments(url, options, defaults) { + var _a, _b, _c, _d, _e; + const rawOptions = options; + if (is_1.default.object(url) && !is_1.default.urlInstance(url)) { + options = { ...defaults, ...url, ...options }; + } else { + if (url && options && options.url !== undefined) { + throw new TypeError( + 'The `url` option is mutually exclusive with the `input` argument' + ); + } + options = { ...defaults, ...options }; + if (url !== undefined) { + options.url = url; + } + if (is_1.default.urlInstance(options.url)) { + options.url = new url_1.URL(options.url.toString()); + } + } + // TODO: Deprecate URL options in Got 12. + // Support extend-specific options + if (options.cache === false) { + options.cache = undefined; + } + if (options.dnsCache === false) { + options.dnsCache = undefined; + } + // Nice type assertions + is_1.assert.any( + [is_1.default.string, is_1.default.undefined], + options.method + ); + is_1.assert.any( + [is_1.default.object, is_1.default.undefined], + options.headers + ); + is_1.assert.any( + [ + is_1.default.string, + is_1.default.urlInstance, + is_1.default.undefined, + ], + options.prefixUrl + ); + is_1.assert.any( + [is_1.default.object, is_1.default.undefined], + options.cookieJar + ); + is_1.assert.any( + [is_1.default.object, is_1.default.string, is_1.default.undefined], + options.searchParams + ); + is_1.assert.any( + [is_1.default.object, is_1.default.string, is_1.default.undefined], + options.cache + ); + is_1.assert.any( + [is_1.default.object, is_1.default.number, is_1.default.undefined], + options.timeout + ); + is_1.assert.any( + [is_1.default.object, is_1.default.undefined], + options.context + ); + is_1.assert.any( + [is_1.default.object, is_1.default.undefined], + options.hooks + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.decompress + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.ignoreInvalidCookies + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.followRedirect + ); + is_1.assert.any( + [is_1.default.number, is_1.default.undefined], + options.maxRedirects + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.throwHttpErrors + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.http2 + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.allowGetBody + ); + is_1.assert.any( + [is_1.default.string, is_1.default.undefined], + options.localAddress + ); + is_1.assert.any( + [dns_ip_version_1.isDnsLookupIpVersion, is_1.default.undefined], + options.dnsLookupIpVersion + ); + is_1.assert.any( + [is_1.default.object, is_1.default.undefined], + options.https + ); + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.rejectUnauthorized + ); + if (options.https) { + is_1.assert.any( + [is_1.default.boolean, is_1.default.undefined], + options.https.rejectUnauthorized + ); + is_1.assert.any( + [is_1.default.function_, is_1.default.undefined], + options.https.checkServerIdentity + ); + is_1.assert.any( + [ + is_1.default.string, + is_1.default.object, + is_1.default.array, + is_1.default.undefined, + ], + options.https.certificateAuthority + ); + is_1.assert.any( + [ + is_1.default.string, + is_1.default.object, + is_1.default.array, + is_1.default.undefined, + ], + options.https.key + ); + is_1.assert.any( + [ + is_1.default.string, + is_1.default.object, + is_1.default.array, + is_1.default.undefined, + ], + options.https.certificate + ); + is_1.assert.any( + [is_1.default.string, is_1.default.undefined], + options.https.passphrase + ); + is_1.assert.any( + [ + is_1.default.string, + is_1.default.buffer, + is_1.default.array, + is_1.default.undefined, + ], + options.https.pfx + ); + } + is_1.assert.any( + [is_1.default.object, is_1.default.undefined], + options.cacheOptions + ); + // `options.method` + if (is_1.default.string(options.method)) { + options.method = options.method.toUpperCase(); + } else { + options.method = 'GET'; + } + // `options.headers` + if ( + options.headers === + (defaults === null || defaults === void 0 + ? void 0 + : defaults.headers) + ) { + options.headers = { ...options.headers }; + } else { + options.headers = lowercaseKeys({ + ...(defaults === null || defaults === void 0 + ? void 0 + : defaults.headers), + ...options.headers, + }); + } + // Disallow legacy `url.Url` + if ('slashes' in options) { + throw new TypeError( + 'The legacy `url.Url` has been deprecated. Use `URL` instead.' + ); + } + // `options.auth` + if ('auth' in options) { + throw new TypeError( + 'Parameter `auth` is deprecated. Use `username` / `password` instead.' + ); + } + // `options.searchParams` + if ('searchParams' in options) { + if ( + options.searchParams && + options.searchParams !== + (defaults === null || defaults === void 0 + ? void 0 + : defaults.searchParams) + ) { + let searchParameters; + if ( + is_1.default.string(options.searchParams) || + options.searchParams instanceof url_1.URLSearchParams + ) { + searchParameters = new url_1.URLSearchParams( + options.searchParams + ); + } else { + validateSearchParameters(options.searchParams); + searchParameters = new url_1.URLSearchParams(); + // eslint-disable-next-line guard-for-in + for (const key in options.searchParams) { + const value = options.searchParams[key]; + if (value === null) { + searchParameters.append(key, ''); + } else if (value !== undefined) { + searchParameters.append(key, value); + } + } + } + // `normalizeArguments()` is also used to merge options + (_a = + defaults === null || defaults === void 0 + ? void 0 + : defaults.searchParams) === null || _a === void 0 + ? void 0 + : _a.forEach((value, key) => { + // Only use default if one isn't already defined + if (!searchParameters.has(key)) { + searchParameters.append(key, value); + } + }); + options.searchParams = searchParameters; + } + } + // `options.username` & `options.password` + options.username = + (_b = options.username) !== null && _b !== void 0 ? _b : ''; + options.password = + (_c = options.password) !== null && _c !== void 0 ? _c : ''; + // `options.prefixUrl` & `options.url` + if (is_1.default.undefined(options.prefixUrl)) { + options.prefixUrl = + (_d = + defaults === null || defaults === void 0 + ? void 0 + : defaults.prefixUrl) !== null && _d !== void 0 + ? _d + : ''; + } else { + options.prefixUrl = options.prefixUrl.toString(); + if (options.prefixUrl !== '' && !options.prefixUrl.endsWith('/')) { + options.prefixUrl += '/'; + } + } + if (is_1.default.string(options.url)) { + if (options.url.startsWith('/')) { + throw new Error( + '`input` must not start with a slash when using `prefixUrl`' + ); + } + options.url = options_to_url_1.default( + options.prefixUrl + options.url, + options + ); + } else if ( + (is_1.default.undefined(options.url) && options.prefixUrl !== '') || + options.protocol + ) { + options.url = options_to_url_1.default(options.prefixUrl, options); + } + if (options.url) { + if ('port' in options) { + delete options.port; + } + // Make it possible to change `options.prefixUrl` + let { prefixUrl } = options; + Object.defineProperty(options, 'prefixUrl', { + set: (value) => { + const url = options.url; + if (!url.href.startsWith(value)) { + throw new Error( + `Cannot change \`prefixUrl\` from ${prefixUrl} to ${value}: ${url.href}` + ); + } + options.url = new url_1.URL( + value + url.href.slice(prefixUrl.length) + ); + prefixUrl = value; + }, + get: () => prefixUrl, + }); + // Support UNIX sockets + let { protocol } = options.url; + if (protocol === 'unix:') { + protocol = 'http:'; + options.url = new url_1.URL( + `http://unix${options.url.pathname}${options.url.search}` + ); + } + // Set search params + if (options.searchParams) { + // eslint-disable-next-line @typescript-eslint/no-base-to-string + options.url.search = options.searchParams.toString(); + } + // Protocol check + if (protocol !== 'http:' && protocol !== 'https:') { + throw new UnsupportedProtocolError(options); + } + // Update `username` + if (options.username === '') { + options.username = options.url.username; + } else { + options.url.username = options.username; + } + // Update `password` + if (options.password === '') { + options.password = options.url.password; + } else { + options.url.password = options.password; + } + } + // `options.cookieJar` + const { cookieJar } = options; + if (cookieJar) { + let { setCookie, getCookieString } = cookieJar; + is_1.assert.function_(setCookie); + is_1.assert.function_(getCookieString); + /* istanbul ignore next: Horrible `tough-cookie` v3 check */ + if (setCookie.length === 4 && getCookieString.length === 0) { + setCookie = util_1.promisify(setCookie.bind(options.cookieJar)); + getCookieString = util_1.promisify( + getCookieString.bind(options.cookieJar) + ); + options.cookieJar = { + setCookie, + getCookieString: getCookieString, + }; + } + } + // `options.cache` + const { cache } = options; + if (cache) { + if (!cacheableStore.has(cache)) { + cacheableStore.set( + cache, + new CacheableRequest((requestOptions, handler) => { + const result = requestOptions[kRequest]( + requestOptions, + handler + ); + // TODO: remove this when `cacheable-request` supports async request functions. + if (is_1.default.promise(result)) { + // @ts-expect-error + // We only need to implement the error handler in order to support HTTP2 caching. + // The result will be a promise anyway. + result.once = (event, handler) => { + if (event === 'error') { + result.catch(handler); + } 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 (_a) {} + })(); + } else { + /* istanbul ignore next: safety check */ + throw new Error( + `Unknown HTTP2 promise event: ${event}` + ); + } + return result; + }; + } + return result; + }, cache) + ); + } + } + // `options.cacheOptions` + options.cacheOptions = { ...options.cacheOptions }; + // `options.dnsCache` + if (options.dnsCache === true) { + if (!globalDnsCache) { + globalDnsCache = new cacheable_lookup_1.default(); + } + options.dnsCache = globalDnsCache; + } else if ( + !is_1.default.undefined(options.dnsCache) && + !options.dnsCache.lookup + ) { + throw new TypeError( + `Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${is_1.default( + options.dnsCache + )}` + ); + } + // `options.timeout` + if (is_1.default.number(options.timeout)) { + options.timeout = { request: options.timeout }; + } else if (defaults && options.timeout !== defaults.timeout) { + options.timeout = { + ...defaults.timeout, + ...options.timeout, + }; + } else { + options.timeout = { ...options.timeout }; + } + // `options.context` + if (!options.context) { + options.context = {}; + } + // `options.hooks` + const areHooksDefault = + options.hooks === + (defaults === null || defaults === void 0 + ? void 0 + : defaults.hooks); + options.hooks = { ...options.hooks }; + for (const event of exports.knownHookEvents) { + if (event in options.hooks) { + if (is_1.default.array(options.hooks[event])) { + // See https://github.com/microsoft/TypeScript/issues/31445#issuecomment-576929044 + options.hooks[event] = [...options.hooks[event]]; + } else { + throw new TypeError( + `Parameter \`${event}\` must be an Array, got ${is_1.default( + options.hooks[event] + )}` + ); + } + } else { + options.hooks[event] = []; + } + } + if (defaults && !areHooksDefault) { + for (const event of exports.knownHookEvents) { + const defaultHooks = defaults.hooks[event]; + if (defaultHooks.length > 0) { + // See https://github.com/microsoft/TypeScript/issues/31445#issuecomment-576929044 + options.hooks[event] = [ + ...defaults.hooks[event], + ...options.hooks[event], + ]; + } + } + } + // DNS options + if ('family' in options) { + deprecation_warning_1.default( + '"options.family" was never documented, please use "options.dnsLookupIpVersion"' + ); + } + // HTTPS options + if ( + defaults === null || defaults === void 0 ? void 0 : defaults.https + ) { + options.https = { ...defaults.https, ...options.https }; + } + if ('rejectUnauthorized' in options) { + deprecation_warning_1.default( + '"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"' + ); + } + if ('checkServerIdentity' in options) { + deprecation_warning_1.default( + '"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"' + ); + } + if ('ca' in options) { + deprecation_warning_1.default( + '"options.ca" was never documented, please use "options.https.certificateAuthority"' + ); + } + if ('key' in options) { + deprecation_warning_1.default( + '"options.key" was never documented, please use "options.https.key"' + ); + } + if ('cert' in options) { + deprecation_warning_1.default( + '"options.cert" was never documented, please use "options.https.certificate"' + ); + } + if ('passphrase' in options) { + deprecation_warning_1.default( + '"options.passphrase" was never documented, please use "options.https.passphrase"' + ); + } + if ('pfx' in options) { + deprecation_warning_1.default( + '"options.pfx" was never documented, please use "options.https.pfx"' + ); + } + // Other options + if ('followRedirects' in options) { + throw new TypeError( + 'The `followRedirects` option does not exist. Use `followRedirect` instead.' + ); + } + if (options.agent) { + for (const key in options.agent) { + if (key !== 'http' && key !== 'https' && key !== 'http2') { + throw new TypeError( + `Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${key}\`` + ); + } + } + } + options.maxRedirects = + (_e = options.maxRedirects) !== null && _e !== void 0 ? _e : 0; + // Set non-enumerable properties + exports.setNonEnumerableProperties([defaults, rawOptions], options); + return normalize_arguments_1.default(options, defaults); + } + _lockWrite() { + const onLockedWrite = () => { + throw new TypeError('The payload has been already provided'); + }; + this.write = onLockedWrite; + this.end = onLockedWrite; + } + _unlockWrite() { + this.write = super.write; + this.end = super.end; + } + async _finalizeBody() { + const { options } = this; + const { headers } = options; + const isForm = !is_1.default.undefined(options.form); + const isJSON = !is_1.default.undefined(options.json); + const isBody = !is_1.default.undefined(options.body); + const hasPayload = isForm || isJSON || isBody; + const cannotHaveBody = + exports.withoutBody.has(options.method) && + !(options.method === 'GET' && options.allowGetBody); + this._cannotHaveBody = cannotHaveBody; + if (hasPayload) { + if (cannotHaveBody) { + throw new TypeError( + `The \`${options.method}\` method cannot be used with a body` + ); + } + if ( + [isBody, isForm, isJSON].filter((isTrue) => isTrue).length > 1 + ) { + throw new TypeError( + 'The `body`, `json` and `form` options are mutually exclusive' + ); + } + if ( + isBody && + !(options.body instanceof stream_1.Readable) && + !is_1.default.string(options.body) && + !is_1.default.buffer(options.body) && + !is_form_data_1.default(options.body) + ) { + throw new TypeError( + 'The `body` option must be a stream.Readable, string or Buffer' + ); + } + if (isForm && !is_1.default.object(options.form)) { + throw new TypeError('The `form` option must be an Object'); + } + { + // Serialize body + const noContentType = !is_1.default.string( + headers['content-type'] + ); + if (isBody) { + // Special case for https://github.com/form-data/form-data + if (is_form_data_1.default(options.body) && noContentType) { + headers[ + 'content-type' + ] = `multipart/form-data; boundary=${options.body.getBoundary()}`; + } + this[kBody] = options.body; + } else if (isForm) { + if (noContentType) { + headers['content-type'] = 'application/x-www-form-urlencoded'; + } + this[kBody] = new url_1.URLSearchParams( + options.form + ).toString(); + } else { + if (noContentType) { + headers['content-type'] = 'application/json'; + } + this[kBody] = options.stringifyJson(options.json); + } + const uploadBodySize = await get_body_size_1.default( + this[kBody], + 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 ( + is_1.default.undefined(headers['content-length']) && + is_1.default.undefined(headers['transfer-encoding']) + ) { + if ( + !cannotHaveBody && + !is_1.default.undefined(uploadBodySize) + ) { + headers['content-length'] = String(uploadBodySize); + } + } + } + } else if (cannotHaveBody) { + this._lockWrite(); + } else { + this._unlockWrite(); + } + this[kBodySize] = Number(headers['content-length']) || undefined; + } + async _onResponseBase(response) { + const { options } = this; + const { url } = options; + this[kOriginalResponse] = response; + if (options.decompress) { + response = decompressResponse(response); + } + const statusCode = response.statusCode; + const typedResponse = response; + typedResponse.statusMessage = typedResponse.statusMessage + ? typedResponse.statusMessage + : http.STATUS_CODES[statusCode]; + typedResponse.url = options.url.toString(); + typedResponse.requestUrl = this.requestUrl; + typedResponse.redirectUrls = this.redirects; + typedResponse.request = this; + typedResponse.isFromCache = response.fromCache || false; + typedResponse.ip = this.ip; + typedResponse.retryCount = this.retryCount; + this[kIsFromCache] = typedResponse.isFromCache; + this[kResponseSize] = + Number(response.headers['content-length']) || undefined; + this[kResponse] = response; + response.once('end', () => { + this[kResponseSize] = this[kDownloadedSize]; + this.emit('downloadProgress', this.downloadProgress); + }); + response.once('error', (error) => { + // 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._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 (is_1.default.object(options.cookieJar) && rawCookies) { + let promises = rawCookies.map(async (rawCookie) => + options.cookieJar.setCookie(rawCookie, url.toString()) + ); + if (options.ignoreInvalidCookies) { + promises = promises.map(async (p) => p.catch(() => {})); + } + try { + await Promise.all(promises); + } catch (error) { + this._beforeError(error); + 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(); + if (this[kRequest]) { + this[kCancelTimeouts](); + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete this[kRequest]; + this[kUnproxyEvents](); + } + const shouldBeGet = + statusCode === 303 && + options.method !== 'GET' && + options.method !== 'HEAD'; + if (shouldBeGet || !options.methodRewriting) { + // Server responded with "see other", indicating that the resource exists at another location, + // and the client should request it from that location via GET or HEAD. + options.method = 'GET'; + if ('body' in options) { + delete options.body; + } + if ('json' in options) { + delete options.json; + } + if ('form' in options) { + delete options.form; + } + this[kBody] = undefined; + delete options.headers['content-length']; + } + if (this.redirects.length >= options.maxRedirects) { + this._beforeError(new MaxRedirectsError(this)); + return; + } + try { + // Do not remove. See https://github.com/sindresorhus/got/pull/214 + const redirectBuffer = Buffer.from( + response.headers.location, + 'binary' + ).toString(); + // Handles invalid URLs. See https://github.com/sindresorhus/got/issues/604 + const redirectUrl = new url_1.URL(redirectBuffer, url); + const redirectString = redirectUrl.toString(); + decodeURI(redirectString); + // Redirecting to a different site, clear sensitive data. + if ( + redirectUrl.hostname !== url.hostname || + redirectUrl.port !== url.port + ) { + if ('host' in options.headers) { + delete options.headers.host; + } + if ('cookie' in options.headers) { + delete options.headers.cookie; + } + if ('authorization' in options.headers) { + delete options.headers.authorization; + } + if (options.username || options.password) { + options.username = ''; + options.password = ''; + } + } else { + redirectUrl.username = options.username; + redirectUrl.password = options.password; + } + this.redirects.push(redirectString); + options.url = redirectUrl; + for (const hook of options.hooks.beforeRedirect) { + // eslint-disable-next-line no-await-in-loop + await hook(options, typedResponse); + } + this.emit('redirect', typedResponse, options); + await this._makeRequest(); + } catch (error) { + this._beforeError(error); + return; + } + return; + } + if ( + options.isStream && + options.throwHttpErrors && + !is_response_ok_1.isResponseOk(typedResponse) + ) { + this._beforeError(new HTTPError(typedResponse)); + return; + } + response.on('readable', () => { + if (this[kTriggerRead]) { + this._read(); + } + }); + this.on('resume', () => { + response.resume(); + }); + this.on('pause', () => { + response.pause(); + }); + response.once('end', () => { + this.push(null); + }); + this.emit('response', response); + for (const destination of this[kServerResponsesPiped]) { + 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 _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; + http_timer_1.default(request); + this[kCancelTimeouts] = timed_out_1.default(request, timeout, url); + const responseEventName = options.cache + ? 'cacheableResponse' + : 'response'; + request.once(responseEventName, (response) => { + void this._onResponse(response); + }); + request.once('error', (error) => { + var _a; + // Force clean-up, because some packages (e.g. nock) don't do this. + request.destroy(); + // Node.js <= 12.18.2 mistakenly emits the response `end` first. + (_a = request.res) === null || _a === void 0 + ? void 0 + : _a.removeAllListeners('end'); + error = + error instanceof timed_out_1.TimeoutError + ? new TimeoutError(error, this.timings, this) + : new RequestError(error.message, error, this); + this._beforeError(error); + }); + this[kUnproxyEvents] = proxy_events_1.default( + request, + this, + proxiedRequestEvents + ); + this[kRequest] = request; + this.emit('uploadProgress', this.uploadProgress); + // Send body + const body = this[kBody]; + const currentRequest = this.redirects.length === 0 ? this : request; + if (is_1.default.nodeStream(body)) { + body.pipe(currentRequest); + body.once('error', (error) => { + this._beforeError(new UploadError(error, this)); + }); + } else { + this._unlockWrite(); + if (!is_1.default.undefined(body)) { + this._writeRequest(body, undefined, () => {}); + currentRequest.end(); + this._lockWrite(); + } else if (this._cannotHaveBody || this._noPipe) { + currentRequest.end(); + this._lockWrite(); + } + } + this.emit('request', 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, url_to_options_1.default(url)); + // `http-cache-semantics` checks this + // TODO: Fix this ignore. + // @ts-expect-error + delete options.url; + let request; + // This is ugly + const cacheRequest = cacheableStore.get(options.cache)( + options, + async (response) => { + // TODO: Fix `cacheable-response` + response._readableState.autoDestroy = false; + if (request) { + (await request).emit('cacheableResponse', response); + } + resolve(response); + } + ); + // Restore options + options.url = url; + cacheRequest.once('error', reject); + cacheRequest.once('request', async (requestOrPromise) => { + request = requestOrPromise; + resolve(request); + }); + }); + } + async _makeRequest() { + var _a, _b, _c, _d, _e; + const { options } = this; + const { headers } = options; + for (const key in headers) { + if (is_1.default.undefined(headers[key])) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete headers[key]; + } else if (is_1.default.null_(headers[key])) { + throw new TypeError( + `Use \`undefined\` instead of \`null\` to delete the \`${key}\` header` + ); + } + } + if ( + options.decompress && + is_1.default.undefined(headers['accept-encoding']) + ) { + headers['accept-encoding'] = supportsBrotli + ? 'gzip, deflate, br' + : 'gzip, deflate'; + } + // Set cookies + if (options.cookieJar) { + const cookieString = await options.cookieJar.getCookieString( + options.url.toString() + ); + if (is_1.default.nonEmptyString(cookieString)) { + options.headers.cookie = cookieString; + } + } + for (const hook of options.hooks.beforeRequest) { + // eslint-disable-next-line no-await-in-loop + const result = await hook(options); + if (!is_1.default.undefined(result)) { + // @ts-expect-error Skip the type mismatch to support abstract responses + options.request = () => result; + break; + } + } + if (options.body && this[kBody] !== options.body) { + this[kBody] = options.body; + } + const { agent, request, timeout, url } = options; + if (options.dnsCache && !('lookup' in options)) { + options.lookup = options.dnsCache.lookup; + } + // UNIX sockets + if (url.hostname === 'unix') { + const matches = /(?.+?):(?.+)/.exec( + `${url.pathname}${url.search}` + ); + if ( + matches === null || matches === void 0 ? void 0 : matches.groups + ) { + const { socketPath, path } = matches.groups; + Object.assign(options, { + socketPath, + path, + host: '', + }); + } + } + const isHttps = url.protocol === 'https:'; + // Fallback function + let fallbackFn; + if (options.http2) { + fallbackFn = http2wrapper.auto; + } else { + fallbackFn = isHttps ? https.request : http.request; + } + const realFn = + (_a = options.request) !== null && _a !== void 0 ? _a : fallbackFn; + // Cache support + const fn = options.cache ? this._createCacheableRequest : realFn; + // Pass an agent directly when HTTP2 is disabled + if (agent && !options.http2) { + options.agent = agent[isHttps ? 'https' : 'http']; + } + // Prepare plain HTTP request options + options[kRequest] = realFn; + delete options.request; + // TODO: Fix this ignore. + // @ts-expect-error + delete options.timeout; + const requestOptions = options; + requestOptions.shared = + (_b = options.cacheOptions) === null || _b === void 0 + ? void 0 + : _b.shared; + requestOptions.cacheHeuristic = + (_c = options.cacheOptions) === null || _c === void 0 + ? void 0 + : _c.cacheHeuristic; + requestOptions.immutableMinTimeToLive = + (_d = options.cacheOptions) === null || _d === void 0 + ? void 0 + : _d.immutableMinTimeToLive; + requestOptions.ignoreCargoCult = + (_e = options.cacheOptions) === null || _e === void 0 + ? void 0 + : _e.ignoreCargoCult; + // If `dnsLookupIpVersion` is not present do not override `family` + if (options.dnsLookupIpVersion !== undefined) { + try { + requestOptions.family = + dns_ip_version_1.dnsLookupIpVersionToFamily( + options.dnsLookupIpVersion + ); + } catch (_f) { + throw new Error('Invalid `dnsLookupIpVersion` option value'); + } + } + // HTTPS options remapping + if (options.https) { + if ('rejectUnauthorized' in options.https) { + requestOptions.rejectUnauthorized = + options.https.rejectUnauthorized; + } + if (options.https.checkServerIdentity) { + requestOptions.checkServerIdentity = + options.https.checkServerIdentity; + } + if (options.https.certificateAuthority) { + requestOptions.ca = options.https.certificateAuthority; + } + if (options.https.certificate) { + requestOptions.cert = options.https.certificate; + } + if (options.https.key) { + requestOptions.key = options.https.key; + } + if (options.https.passphrase) { + requestOptions.passphrase = options.https.passphrase; + } + if (options.https.pfx) { + requestOptions.pfx = options.https.pfx; + } + } + try { + let requestOrResponse = await fn(url, requestOptions); + if (is_1.default.undefined(requestOrResponse)) { + requestOrResponse = fallbackFn(url, requestOptions); + } + // Restore options + options.request = request; + options.timeout = timeout; + options.agent = agent; + // HTTPS options restore + if (options.https) { + if ('rejectUnauthorized' in options.https) { + delete requestOptions.rejectUnauthorized; + } + if (options.https.checkServerIdentity) { + // @ts-expect-error - This one will be removed when we remove the alias. + delete requestOptions.checkServerIdentity; + } + if (options.https.certificateAuthority) { + delete requestOptions.ca; + } + if (options.https.certificate) { + delete requestOptions.cert; + } + if (options.https.key) { + delete requestOptions.key; + } + if (options.https.passphrase) { + delete requestOptions.passphrase; + } + if (options.https.pfx) { + delete requestOptions.pfx; + } + } + if (isClientRequest(requestOrResponse)) { + this._onRequest(requestOrResponse); + // Emit the response after the stream has been ended + } else if (this.writable) { + this.once('finish', () => { + void this._onResponse(requestOrResponse); + }); + this._unlockWrite(); + this.end(); + this._lockWrite(); + } else { + void this._onResponse(requestOrResponse); + } + } catch (error) { + if (error instanceof CacheableRequest.CacheError) { + throw new CacheError(error, this); + } + throw new RequestError(error.message, error, this); + } + } + async _error(error) { + try { + 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); + } + _beforeError(error) { + if (this[kStopReading]) { + return; + } + const { options } = this; + const retryCount = this.retryCount + 1; + this[kStopReading] = true; + if (!(error instanceof RequestError)) { + error = new RequestError(error.message, error, this); + } + const typedError = error; + const { response } = typedError; + void (async () => { + if (response && !response.body) { + response.setEncoding(this._readableState.encoding); + try { + response.rawBody = await get_buffer_1.default(response); + response.body = response.rawBody.toString(); + } catch (_a) {} + } + 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; + } + } + backoff = await options.retry.calculateDelay({ + attemptCount: retryCount, + retryOptions: options.retry, + error: typedError, + retryAfter, + computedValue: calculate_retry_delay_1.default({ + attemptCount: retryCount, + retryOptions: options.retry, + error: typedError, + retryAfter, + computedValue: 0, + }), + }); + } catch (error_) { + void this._error( + new RequestError(error_.message, error_, this) + ); + return; + } + if (backoff) { + const retry = async () => { + try { + for (const hook of this.options.hooks.beforeRetry) { + // eslint-disable-next-line no-await-in-loop + await hook(this.options, typedError, retryCount); + } + } 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', retryCount, error); + }; + this[kRetryTimeout] = setTimeout(retry, backoff); + return; + } + } + void this._error(typedError); + })(); + } + _read() { + this[kTriggerRead] = true; + const response = this[kResponse]; + if (response && !this[kStopReading]) { + // We cannot put this in the `if` above + // because `.read()` also triggers the `end` event + if (response.readableLength) { + this[kTriggerRead] = false; + } + let data; + while ((data = response.read()) !== null) { + this[kDownloadedSize] += data.length; + this[kStartedReading] = true; + const progress = this.downloadProgress; + if (progress.percent < 1) { + this.emit('downloadProgress', progress); + } + this.push(data); + } + } + } + // Node.js 12 has incorrect types, so the encoding must be a string + _write(chunk, encoding, callback) { + const write = () => { + this._writeRequest(chunk, encoding, callback); + }; + if (this.requestInitialized) { + write(); + } else { + this[kJobs].push(write); + } + } + _writeRequest(chunk, encoding, callback) { + if (this[kRequest].destroyed) { + // Probably the `ClientRequest` instance will throw + return; + } + this._progressCallbacks.push(() => { + this[kUploadedSize] += Buffer.byteLength(chunk, encoding); + const progress = this.uploadProgress; + if (progress.percent < 1) { + this.emit('uploadProgress', progress); + } + }); + // TODO: What happens if it's from cache? Then this[kRequest] won't be defined. + this[kRequest].write(chunk, encoding, (error) => { + if (!error && this._progressCallbacks.length > 0) { + this._progressCallbacks.shift()(); + } + callback(error); + }); + } + _final(callback) { + const endRequest = () => { + // FIX: Node.js 10 calls the write callback AFTER the end callback! + while (this._progressCallbacks.length !== 0) { + this._progressCallbacks.shift()(); + } + // We need to check if `this[kRequest]` is present, + // because it isn't when we use cache. + if (!(kRequest in this)) { + callback(); + return; + } + if (this[kRequest].destroyed) { + callback(); + return; + } + this[kRequest].end((error) => { + if (!error) { + this[kBodySize] = this[kUploadedSize]; + this.emit('uploadProgress', this.uploadProgress); + this[kRequest].emit('upload-complete'); + } + callback(error); + }); + }; + if (this.requestInitialized) { + endRequest(); + } else { + this[kJobs].push(endRequest); + } + } + _destroy(error, callback) { + var _a; + this[kStopReading] = true; + // Prevent further retries + clearTimeout(this[kRetryTimeout]); + if (kRequest in this) { + this[kCancelTimeouts](); + // TODO: Remove the next `if` when these get fixed: + // - https://github.com/nodejs/node/issues/32851 + if ( + !((_a = this[kResponse]) === null || _a === void 0 + ? void 0 + : _a.complete) + ) { + this[kRequest].destroy(); + } + } + if ( + error !== null && + !is_1.default.undefined(error) && + !(error instanceof RequestError) + ) { + error = new RequestError(error.message, error, this); + } + callback(error); + } + get _isAboutToError() { + return this[kStopReading]; + } + /** + The remote IP address. + */ + get ip() { + var _a; + return (_a = this.socket) === null || _a === void 0 + ? void 0 + : _a.remoteAddress; + } + /** + Indicates whether the request has been aborted or not. + */ + get aborted() { + var _a, _b, _c; + return ( + ((_b = + (_a = this[kRequest]) === null || _a === void 0 + ? void 0 + : _a.destroyed) !== null && _b !== void 0 + ? _b + : this.destroyed) && + !((_c = this[kOriginalResponse]) === null || _c === void 0 + ? void 0 + : _c.complete) + ); + } + get socket() { + var _a, _b; + return (_b = + (_a = this[kRequest]) === null || _a === void 0 + ? void 0 + : _a.socket) !== null && _b !== void 0 + ? _b + : undefined; + } + /** + Progress event for downloading (receiving a response). + */ + get downloadProgress() { + let percent; + if (this[kResponseSize]) { + percent = this[kDownloadedSize] / this[kResponseSize]; + } else if (this[kResponseSize] === this[kDownloadedSize]) { + percent = 1; + } else { + percent = 0; + } + return { + percent, + transferred: this[kDownloadedSize], + total: this[kResponseSize], + }; + } + /** + Progress event for uploading (sending a request). + */ + get uploadProgress() { + let percent; + if (this[kBodySize]) { + percent = this[kUploadedSize] / this[kBodySize]; + } else if (this[kBodySize] === this[kUploadedSize]) { + percent = 1; + } else { + percent = 0; + } + return { + percent, + transferred: this[kUploadedSize], + total: this[kBodySize], + }; + } + /** + 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() { + var _a; + return (_a = this[kRequest]) === null || _a === void 0 + ? void 0 + : _a.timings; + } + /** + Whether the response was retrieved from the cache. + */ + get isFromCache() { + return this[kIsFromCache]; + } + pipe(destination, options) { + if (this[kStartedReading]) { + throw new Error( + 'Failed to pipe. The response has been emitted already.' + ); + } + if (destination instanceof http_1.ServerResponse) { + this[kServerResponsesPiped].add(destination); + } + return super.pipe(destination, options); + } + unpipe(destination) { + if (destination instanceof http_1.ServerResponse) { + this[kServerResponsesPiped].delete(destination); + } + super.unpipe(destination); + return this; + } + } + exports['default'] = Request; + + /***/ + }, + + /***/ 4993: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + exports.dnsLookupIpVersionToFamily = exports.isDnsLookupIpVersion = + void 0; + const conversionTable = { + auto: 0, + ipv4: 4, + ipv6: 6, + }; + exports.isDnsLookupIpVersion = (value) => { + return value in conversionTable; + }; + exports.dnsLookupIpVersionToFamily = (dnsLookupIpVersion) => { + if (exports.isDnsLookupIpVersion(dnsLookupIpVersion)) { + return conversionTable[dnsLookupIpVersion]; + } + throw new Error('Invalid DNS lookup IP version'); + }; + + /***/ + }, + + /***/ 4564: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const fs_1 = __nccwpck_require__(7147); + const util_1 = __nccwpck_require__(3837); + const is_1 = __nccwpck_require__(7678); + const is_form_data_1 = __nccwpck_require__(40); + const statAsync = util_1.promisify(fs_1.stat); + exports['default'] = async (body, headers) => { + if (headers && 'content-length' in headers) { + return Number(headers['content-length']); + } + if (!body) { + return 0; + } + if (is_1.default.string(body)) { + return Buffer.byteLength(body); + } + if (is_1.default.buffer(body)) { + return body.length; + } + if (is_form_data_1.default(body)) { + return util_1.promisify(body.getLength.bind(body))(); + } + if (body instanceof fs_1.ReadStream) { + const { size } = await statAsync(body.path); + if (size === 0) { + return undefined; + } + return size; + } + return undefined; + }; + + /***/ + }, + + /***/ 4500: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + // TODO: Update https://github.com/sindresorhus/get-stream + const getBuffer = async (stream) => { + const chunks = []; + let length = 0; + for await (const chunk of stream) { + chunks.push(chunk); + length += Buffer.byteLength(chunk); + } + if (Buffer.isBuffer(chunks[0])) { + return Buffer.concat(chunks, length); + } + return Buffer.from(chunks.join('')); + }; + exports['default'] = getBuffer; + + /***/ + }, + + /***/ 40: /***/ (__unused_webpack_module, exports, __nccwpck_require__) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const is_1 = __nccwpck_require__(7678); + exports['default'] = (body) => + is_1.default.nodeStream(body) && + is_1.default.function_(body.getBoundary); + + /***/ + }, + + /***/ 9298: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + exports.isResponseOk = void 0; + exports.isResponseOk = (response) => { + const { statusCode } = response; + const limitStatusCode = response.request.options.followRedirect + ? 299 + : 399; + return ( + (statusCode >= 200 && statusCode <= limitStatusCode) || + statusCode === 304 + ); + }; + + /***/ + }, + + /***/ 9219: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + /* istanbul ignore file: deprecated */ + const url_1 = __nccwpck_require__(7310); + const keys = [ + 'protocol', + 'host', + 'hostname', + 'port', + 'pathname', + 'search', + ]; + exports['default'] = (origin, options) => { + var _a, _b; + if (options.path) { + if (options.pathname) { + throw new TypeError( + 'Parameters `path` and `pathname` are mutually exclusive.' + ); + } + if (options.search) { + throw new TypeError( + 'Parameters `path` and `search` are mutually exclusive.' + ); + } + if (options.searchParams) { + throw new TypeError( + 'Parameters `path` and `searchParams` are mutually exclusive.' + ); + } + } + if (options.search && options.searchParams) { + throw new TypeError( + 'Parameters `search` and `searchParams` are mutually exclusive.' + ); + } + if (!origin) { + if (!options.protocol) { + throw new TypeError('No URL protocol specified'); + } + origin = `${options.protocol}//${ + (_b = + (_a = options.hostname) !== null && _a !== void 0 + ? _a + : options.host) !== null && _b !== void 0 + ? _b + : '' + }`; + } + const url = new url_1.URL(origin); + if (options.path) { + const searchIndex = options.path.indexOf('?'); + if (searchIndex === -1) { + options.pathname = options.path; + } else { + options.pathname = options.path.slice(0, searchIndex); + options.search = options.path.slice(searchIndex + 1); + } + delete options.path; + } + for (const key of keys) { + if (options[key]) { + url[key] = options[key].toString(); + } + } + return url; + }; + + /***/ + }, + + /***/ 3021: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + function default_1(from, to, events) { + const fns = {}; + for (const event of events) { + fns[event] = (...args) => { + to.emit(event, ...args); + }; + from.on(event, fns[event]); + } + return () => { + for (const event of events) { + from.off(event, fns[event]); + } + }; + } + exports['default'] = default_1; + + /***/ + }, + + /***/ 2454: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + exports.TimeoutError = void 0; + const net = __nccwpck_require__(1808); + const unhandle_1 = __nccwpck_require__(1593); + const reentry = Symbol('reentry'); + const noop = () => {}; + class TimeoutError extends Error { + constructor(threshold, event) { + super(`Timeout awaiting '${event}' for ${threshold}ms`); + this.event = event; + this.name = 'TimeoutError'; + this.code = 'ETIMEDOUT'; + } + } + exports.TimeoutError = TimeoutError; + exports['default'] = (request, delays, options) => { + if (reentry in request) { + return noop; + } + request[reentry] = true; + const cancelers = []; + const { once, unhandleAll } = unhandle_1.default(); + const addTimeout = (delay, callback, event) => { + var _a; + const timeout = setTimeout(callback, delay, delay, event); + (_a = timeout.unref) === null || _a === void 0 + ? void 0 + : _a.call(timeout); + const cancel = () => { + clearTimeout(timeout); + }; + cancelers.push(cancel); + return cancel; + }; + const { host, hostname } = options; + const timeoutHandler = (delay, event) => { + request.destroy(new 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; + } + }); + request.once('close', cancelTimeouts); + once(request, 'response', (response) => { + once(response, 'end', cancelTimeouts); + }); + if (typeof delays.request !== 'undefined') { + addTimeout(delays.request, timeoutHandler, 'request'); + } + if (typeof delays.socket !== 'undefined') { + const socketTimeoutHandler = () => { + timeoutHandler(delays.socket, 'socket'); + }; + request.setTimeout(delays.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); + }); + } + once(request, 'socket', (socket) => { + var _a; + const { socketPath } = request; + /* istanbul ignore next: hard to test */ + if (socket.connecting) { + const hasPath = Boolean( + socketPath !== null && socketPath !== void 0 + ? socketPath + : net.isIP( + (_a = + hostname !== null && hostname !== void 0 + ? hostname + : host) !== null && _a !== void 0 + ? _a + : '' + ) !== 0 + ); + if ( + typeof delays.lookup !== 'undefined' && + !hasPath && + typeof socket.address().address === 'undefined' + ) { + const cancelTimeout = addTimeout( + delays.lookup, + timeoutHandler, + 'lookup' + ); + once(socket, 'lookup', cancelTimeout); + } + if (typeof delays.connect !== 'undefined') { + 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 ( + typeof delays.secureConnect !== 'undefined' && + options.protocol === 'https:' + ) { + once(socket, 'connect', () => { + const cancelTimeout = addTimeout( + delays.secureConnect, + timeoutHandler, + 'secureConnect' + ); + once(socket, 'secureConnect', cancelTimeout); + }); + } + } + if (typeof delays.send !== 'undefined') { + 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); + }); + } + return cancelTimeouts; + }; + + /***/ + }, + + /***/ 1593: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + // 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. + exports['default'] = () => { + 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; + }, + }; + }; + + /***/ + }, + + /***/ 8026: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const is_1 = __nccwpck_require__(7678); + exports['default'] = (url) => { + // Cast to URL + url = url; + const options = { + protocol: url.protocol, + hostname: + is_1.default.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 (is_1.default.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; + }; + + /***/ + }, + + /***/ 7288: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + class WeakableMap { + constructor() { + 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); + } + } + exports['default'] = WeakableMap; + + /***/ + }, + + /***/ 4337: /***/ function ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) { + 'use strict'; + + var __createBinding = + (this && this.__createBinding) || + (Object.create + ? function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: function () { + return m[k]; + }, + }); + } + : function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + var __exportStar = + (this && this.__exportStar) || + function (m, exports) { + for (var p in m) + if ( + p !== 'default' && + !Object.prototype.hasOwnProperty.call(exports, p) + ) + __createBinding(exports, m, p); + }; + Object.defineProperty(exports, '__esModule', { value: true }); + exports.defaultHandler = void 0; + const is_1 = __nccwpck_require__(7678); + const as_promise_1 = __nccwpck_require__(6056); + const create_rejection_1 = __nccwpck_require__(6457); + const core_1 = __nccwpck_require__(94); + const deep_freeze_1 = __nccwpck_require__(285); + const errors = { + RequestError: as_promise_1.RequestError, + CacheError: as_promise_1.CacheError, + ReadError: as_promise_1.ReadError, + HTTPError: as_promise_1.HTTPError, + MaxRedirectsError: as_promise_1.MaxRedirectsError, + TimeoutError: as_promise_1.TimeoutError, + ParseError: as_promise_1.ParseError, + CancelError: as_promise_1.CancelError, + UnsupportedProtocolError: as_promise_1.UnsupportedProtocolError, + UploadError: as_promise_1.UploadError, + }; + // The `delay` package weighs 10KB (!) + const delay = async (ms) => + new Promise((resolve) => { + setTimeout(resolve, ms); + }); + const { normalizeArguments } = core_1.default; + const mergeOptions = (...sources) => { + let mergedOptions; + for (const source of sources) { + mergedOptions = normalizeArguments(undefined, source, mergedOptions); + } + return mergedOptions; + }; + const getPromiseOrStream = (options) => + options.isStream + ? new core_1.default(undefined, options) + : as_promise_1.default(options); + const isGotInstance = (value) => + 'defaults' in value && 'options' in value.defaults; + const aliases = ['get', 'post', 'put', 'patch', 'head', 'delete']; + exports.defaultHandler = (options, next) => next(options); + const callInitHooks = (hooks, options) => { + if (hooks) { + for (const hook of hooks) { + hook(options); + } + } + }; + const create = (defaults) => { + // Proxy properties from next handlers + defaults._rawHandlers = defaults.handlers; + defaults.handlers = defaults.handlers.map((fn) => (options, next) => { + // This will be assigned by assigning result + let root; + const result = fn(options, (newOptions) => { + root = next(newOptions); + return root; + }); + if (result !== root && !options.isStream && root) { + const typedResult = result; + const { + then: promiseThen, + catch: promiseCatch, + finally: promiseFianlly, + } = typedResult; + Object.setPrototypeOf(typedResult, Object.getPrototypeOf(root)); + Object.defineProperties( + typedResult, + Object.getOwnPropertyDescriptors(root) + ); + // These should point to the new promise + // eslint-disable-next-line promise/prefer-await-to-then + typedResult.then = promiseThen; + typedResult.catch = promiseCatch; + typedResult.finally = promiseFianlly; + } + return result; + }); + // Got interface + const got = (url, options = {}, _defaults) => { + var _a, _b; + let iteration = 0; + const iterateHandlers = (newOptions) => { + return defaults.handlers[iteration++]( + newOptions, + iteration === defaults.handlers.length + ? getPromiseOrStream + : iterateHandlers + ); + }; + // TODO: Remove this in Got 12. + if (is_1.default.plainObject(url)) { + const mergedOptions = { + ...url, + ...options, + }; + core_1.setNonEnumerableProperties([url, options], mergedOptions); + options = mergedOptions; + url = undefined; + } + try { + // Call `init` hooks + let initHookError; + try { + callInitHooks(defaults.options.hooks.init, options); + callInitHooks( + (_a = options.hooks) === null || _a === void 0 + ? void 0 + : _a.init, + options + ); + } catch (error) { + initHookError = error; + } + // Normalize options & call handlers + const normalizedOptions = normalizeArguments( + url, + options, + _defaults !== null && _defaults !== void 0 + ? _defaults + : defaults.options + ); + normalizedOptions[core_1.kIsNormalizedAlready] = true; + if (initHookError) { + throw new as_promise_1.RequestError( + initHookError.message, + initHookError, + normalizedOptions + ); + } + return iterateHandlers(normalizedOptions); + } catch (error) { + if (options.isStream) { + throw error; + } else { + return create_rejection_1.default( + error, + defaults.options.hooks.beforeError, + (_b = options.hooks) === null || _b === void 0 + ? void 0 + : _b.beforeError + ); + } + } + }; + got.extend = (...instancesOrOptions) => { + const optionsArray = [defaults.options]; + let handlers = [...defaults._rawHandlers]; + let isMutableDefaults; + for (const value of instancesOrOptions) { + if (isGotInstance(value)) { + optionsArray.push(value.defaults.options); + handlers.push(...value.defaults._rawHandlers); + isMutableDefaults = value.defaults.mutableDefaults; + } else { + optionsArray.push(value); + if ('handlers' in value) { + handlers.push(...value.handlers); + } + isMutableDefaults = value.mutableDefaults; + } + } + handlers = handlers.filter( + (handler) => handler !== exports.defaultHandler + ); + if (handlers.length === 0) { + handlers.push(exports.defaultHandler); + } + return create({ + options: mergeOptions(...optionsArray), + handlers, + mutableDefaults: Boolean(isMutableDefaults), + }); + }; + // Pagination + const paginateEach = async function* (url, options) { + // TODO: Remove this `@ts-expect-error` when upgrading to TypeScript 4. + // Error: Argument of type 'Merge> | undefined' is not assignable to parameter of type 'Options | undefined'. + // @ts-expect-error + let normalizedOptions = normalizeArguments( + url, + options, + defaults.options + ); + normalizedOptions.resolveBodyOnly = false; + const pagination = normalizedOptions.pagination; + if (!is_1.default.object(pagination)) { + throw new TypeError('`options.pagination` must be implemented'); + } + const all = []; + 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); + } + // @ts-expect-error FIXME! + // TODO: Throw when result is not an instance of Response + // eslint-disable-next-line no-await-in-loop + const result = await got(undefined, undefined, normalizedOptions); + // eslint-disable-next-line no-await-in-loop + const parsed = await pagination.transform(result); + const current = []; + for (const item of parsed) { + if (pagination.filter(item, all, current)) { + if (!pagination.shouldContinue(item, all, current)) { + return; + } + yield item; + if (pagination.stackAllItems) { + all.push(item); + } + current.push(item); + if (--countLimit <= 0) { + return; + } + } + } + const optionsToMerge = pagination.paginate(result, all, current); + if (optionsToMerge === false) { + return; + } + if (optionsToMerge === result.request.options) { + normalizedOptions = result.request.options; + } else if (optionsToMerge !== undefined) { + normalizedOptions = normalizeArguments( + undefined, + optionsToMerge, + normalizedOptions + ); + } + 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) => { + return got(url, { ...options, method, isStream: true }); + }; + } + Object.assign(got, errors); + Object.defineProperty(got, 'defaults', { + value: defaults.mutableDefaults + ? defaults + : deep_freeze_1.default(defaults), + writable: defaults.mutableDefaults, + configurable: defaults.mutableDefaults, + enumerable: true, + }); + got.mergeOptions = mergeOptions; + return got; + }; + exports['default'] = create; + __exportStar(__nccwpck_require__(2613), exports); + + /***/ + }, + + /***/ 3061: /***/ function (module, exports, __nccwpck_require__) { + 'use strict'; + + var __createBinding = + (this && this.__createBinding) || + (Object.create + ? function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: function () { + return m[k]; + }, + }); + } + : function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + var __exportStar = + (this && this.__exportStar) || + function (m, exports) { + for (var p in m) + if ( + p !== 'default' && + !Object.prototype.hasOwnProperty.call(exports, p) + ) + __createBinding(exports, m, p); + }; + Object.defineProperty(exports, '__esModule', { value: true }); + const url_1 = __nccwpck_require__(7310); + const create_1 = __nccwpck_require__(4337); + const defaults = { + options: { + method: 'GET', + 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, + }, + timeout: {}, + headers: { + 'user-agent': 'got (https://github.com/sindresorhus/got)', + }, + hooks: { + init: [], + beforeRequest: [], + beforeRedirect: [], + beforeRetry: [], + beforeError: [], + afterResponse: [], + }, + cache: undefined, + dnsCache: undefined, + decompress: true, + throwHttpErrors: true, + followRedirect: true, + isStream: false, + responseType: 'text', + resolveBodyOnly: false, + maxRedirects: 10, + prefixUrl: '', + methodRewriting: true, + ignoreInvalidCookies: false, + context: {}, + // TODO: Set this to `true` when Got 12 gets released + http2: false, + allowGetBody: false, + https: undefined, + pagination: { + transform: (response) => { + if (response.request.options.responseType === 'json') { + return response.body; + } + return JSON.parse(response.body); + }, + paginate: (response) => { + if (!Reflect.has(response.headers, 'link')) { + return false; + } + const items = response.headers.link.split(','); + let next; + for (const item of items) { + const parsed = item.split(';'); + if (parsed[1].includes('next')) { + next = parsed[0].trimStart().trim(); + next = next.slice(1, -1); + break; + } + } + if (next) { + const options = { + url: new url_1.URL(next), + }; + return options; + } + return false; + }, + filter: () => true, + shouldContinue: () => true, + countLimit: Infinity, + backoff: 0, + requestLimit: 10000, + stackAllItems: true, + }, + parseJson: (text) => JSON.parse(text), + stringifyJson: (object) => JSON.stringify(object), + cacheOptions: {}, + }, + handlers: [create_1.defaultHandler], + mutableDefaults: false, + }; + const got = create_1.default(defaults); + exports['default'] = got; + // For CommonJS default export support + module.exports = got; + module.exports['default'] = got; + module.exports.__esModule = true; // Workaround for TS issue: https://github.com/sindresorhus/got/pull/1267 + __exportStar(__nccwpck_require__(4337), exports); + __exportStar(__nccwpck_require__(6056), exports); + + /***/ + }, + + /***/ 2613: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + + /***/ + }, + + /***/ 285: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const is_1 = __nccwpck_require__(7678); + function deepFreeze(object) { + for (const value of Object.values(object)) { + if (is_1.default.plainObject(value) || is_1.default.array(value)) { + deepFreeze(value); + } + } + return Object.freeze(object); + } + exports['default'] = deepFreeze; + + /***/ + }, + + /***/ 397: /***/ (__unused_webpack_module, exports) => { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { value: true }); + const alreadyWarned = new Set(); + exports['default'] = (message) => { + if (alreadyWarned.has(message)) { + return; + } + alreadyWarned.add(message); + // @ts-expect-error Missing types. + process.emitWarning(`Got: ${message}`, { + type: 'DeprecationWarning', + }); + }; + + /***/ + }, + + /***/ 1002: /***/ (module) => { + 'use strict'; + + // 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, + __nccwpck_require__ + ) => { + 'use strict'; + + const EventEmitter = __nccwpck_require__(2361); + const tls = __nccwpck_require__(4404); + const http2 = __nccwpck_require__(5158); + const QuickLRU = __nccwpck_require__(9273); + + const kCurrentStreamsCount = Symbol('currentStreamsCount'); + const kRequest = Symbol('request'); + const kOriginSet = Symbol('cachedOriginSet'); + const kGracefullyClosing = Symbol('gracefullyClosing'); + + const nameKeys = [ + // `http2.connect()` options + 'maxDeflateDynamicTableSize', + 'maxSessionMemory', + 'maxHeaderListPairs', + 'maxOutstandingPings', + 'maxReservedRemoteStreams', + 'maxSendHeaderBlockLength', + 'paddingStrategy', + + // `tls.connect()` options + 'localAddress', + 'path', + 'rejectUnauthorized', + 'minDHSize', + + // `tls.createSecureContext()` options + 'ca', + 'cert', + 'clientCertEngine', + 'ciphers', + 'key', + 'pfx', + 'servername', + 'minVersion', + 'maxVersion', + 'secureProtocol', + 'crl', + 'honorCipherOrder', + 'ecdhCurve', + 'dhparam', + 'secureOptions', + 'sessionIdContext', + ]; + + const getSortedIndex = (array, value, compare) => { + let low = 0; + let high = array.length; + + while (low < high) { + const mid = (low + high) >>> 1; + + /* istanbul ignore next */ + if (compare(array[mid], value)) { + // This never gets called because we use descending sort. Better to have this anyway. + low = mid + 1; + } else { + high = mid; + } + } + + return low; + }; + + const compareSessions = (a, b) => { + return ( + 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 (const coveredSession of where) { + if ( + // 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[kCurrentStreamsCount] + + session[kCurrentStreamsCount] <= + 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 (const session of where) { + if ( + coveredSession[kOriginSet].length < session[kOriginSet].length && + coveredSession[kOriginSet].every((origin) => + session[kOriginSet].includes(origin) + ) && + coveredSession[kCurrentStreamsCount] + + session[kCurrentStreamsCount] <= + session.remoteSettings.maxConcurrentStreams + ) { + gracefullyClose(coveredSession); + } + } + }; + + const getSessions = ({ agent, isFree }) => { + const result = {}; + + // eslint-disable-next-line guard-for-in + for (const normalizedOptions in agent.sessions) { + const sessions = agent.sessions[normalizedOptions]; + + const filtered = sessions.filter((session) => { + const result = + session[Agent.kCurrentStreamsCount] < + session.remoteSettings.maxConcurrentStreams; + + return isFree ? result : !result; + }); + + if (filtered.length !== 0) { + result[normalizedOptions] = filtered; + } + } + + return result; + }; + + const gracefullyClose = (session) => { + session[kGracefullyClosing] = true; + + if (session[kCurrentStreamsCount] === 0) { + session.close(); + } + }; + + class Agent extends EventEmitter { + constructor({ + timeout = 60000, + maxSessions = Infinity, + maxFreeSessions = 10, + maxCachedTlsSessions = 100, + } = {}) { + super(); + + // A session is considered busy when its current streams count + // is equal to or greater than the `maxConcurrentStreams` value. + + // A session is considered free when its current streams count + // is less than the `maxConcurrentStreams` value. + + // SESSIONS[NORMALIZED_OPTIONS] = []; + this.sessions = {}; + + // The queue for creating new sessions. It looks like this: + // QUEUE[NORMALIZED_OPTIONS][NORMALIZED_ORIGIN] = ENTRY_FUNCTION + // + // 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 free sessions in total + // TODO: decreasing `maxFreeSessions` should close some sessions + this.maxFreeSessions = maxFreeSessions; + + this._freeSessionsCount = 0; + this._sessionsCount = 0; + + // We don't support push streams by default. + this.settings = { + enablePush: false, + }; + + // Reusing TLS sessions increases performance. + this.tlsSessionCache = new QuickLRU({ + maxSize: maxCachedTlsSessions, + }); + } + + static normalizeOrigin(url, servername) { + if (typeof url === 'string') { + url = new URL(url); + } + + if (servername && url.hostname !== servername) { + url.hostname = servername; + } + + return url.origin; + } + + normalizeOptions(options) { + let normalized = ''; + + if (options) { + for (const key of nameKeys) { + if (options[key]) { + normalized += `:${options[key]}`; + } + } + } + + return normalized; + } + + _tryToCreateNewSession(normalizedOptions, normalizedOrigin) { + if ( + !(normalizedOptions in this.queue) || + !(normalizedOrigin in this.queue[normalizedOptions]) + ) { + return; + } + + const item = this.queue[normalizedOptions][normalizedOrigin]; + + // The entry function can be run only once. + // BUG: The session may be never created when: + // - the first condition is false AND + // - this function is never called with the same arguments in the future. + if (this._sessionsCount < this.maxSessions && !item.completed) { + item.completed = true; + + item(); + } + } + + getSession(origin, options, listeners) { + return new Promise((resolve, reject) => { + if (Array.isArray(listeners)) { + 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 }]; + } + + const normalizedOptions = this.normalizeOptions(options); + const normalizedOrigin = Agent.normalizeOrigin( + origin, + options && options.servername + ); + + if (normalizedOrigin === undefined) { + for (const { reject } of listeners) { + reject( + new TypeError( + 'The `origin` argument needs to be a string or an URL object' + ) + ); + } + + return; + } + + 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. + for (const session of sessions) { + const sessionMaxConcurrentStreams = + session.remoteSettings.maxConcurrentStreams; + + if (sessionMaxConcurrentStreams < maxConcurrentStreams) { + break; + } + + if (session[kOriginSet].includes(normalizedOrigin)) { + const sessionCurrentStreamsCount = + session[kCurrentStreamsCount]; + + 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; + } + + // We're looking for the session which has biggest current pending stream count, + // in order to minimalize the amount of active sessions. + if (sessionCurrentStreamsCount > currentStreamsCount) { + optimalSession = session; + currentStreamsCount = sessionCurrentStreamsCount; + } + } + } + + if (optimalSession) { + /* istanbul ignore next: safety check */ + if (listeners.length !== 1) { + for (const { reject } of listeners) { + const error = new Error( + `Expected the length of listeners to be 1, got ${listeners.length}.\n` + + 'Please report this to https://github.com/szmarczak/http2-wrapper/' + ); + + reject(error); + } + + return; + } + + listeners[0].resolve(optimalSession); + 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 + ); + + // This shouldn't be executed here. + // See the comment inside _tryToCreateNewSession. + this._tryToCreateNewSession( + normalizedOptions, + normalizedOrigin + ); + return; + } + } else { + this.queue[normalizedOptions] = {}; + } + + // 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 (Object.keys(this.queue[normalizedOptions]).length === 0) { + delete this.queue[normalizedOptions]; + } + } + }; + + // The main logic is here + const entry = () => { + const name = `${normalizedOrigin}:${normalizedOptions}`; + let receivedSettings = false; + + try { + const session = http2.connect(origin, { + createConnection: this.createConnection, + settings: this.settings, + session: this.tlsSessionCache.get(name), + ...options, + }); + session[kCurrentStreamsCount] = 0; + session[kGracefullyClosing] = false; + + const isFree = () => + session[kCurrentStreamsCount] < + session.remoteSettings.maxConcurrentStreams; + let wasFree = true; + + session.socket.once('session', (tlsSession) => { + this.tlsSessionCache.set(name, tlsSession); + }); + + session.once('error', (error) => { + // Listeners are empty when the session successfully connected. + for (const { reject } of listeners) { + reject(error); + } + + // The connection got broken, purge the cache. + this.tlsSessionCache.delete(name); + }); + + session.setTimeout(this.timeout, () => { + // Terminates all streams owned by this session. + // TODO: Maybe the streams should have a "Session timed out" error? + session.destroy(); + }); + + session.once('close', () => { + if (receivedSettings) { + // 1. If it wasn't free then no need to decrease because + // it has been decreased already in session.request(). + // 2. `stream.once('close')` won't increment the count + // because the session is already closed. + if (wasFree) { + this._freeSessionsCount--; + } + + this._sessionsCount--; + + // 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]; + where.splice(where.indexOf(session), 1); + + if (where.length === 0) { + delete this.sessions[normalizedOptions]; + } + } else { + // Broken connection + const error = new Error( + 'Session closed without receiving a SETTINGS frame' + ); + error.code = 'HTTP2WRAPPER_NOSETTINGS'; + + for (const { reject } of listeners) { + reject(error); + } + + removeFromQueue(); + } + + // There may be another session awaiting. + this._tryToCreateNewSession( + normalizedOptions, + normalizedOrigin + ); + }); + + // Iterates over the queue and processes listeners. + const processListeners = () => { + if (!(normalizedOptions in this.queue) || !isFree()) { + return; + } + + for (const origin of session[kOriginSet]) { + if (origin in this.queue[normalizedOptions]) { + const { listeners } = + this.queue[normalizedOptions][origin]; + + // Prevents session overloading. + while (listeners.length !== 0 && isFree()) { + // We assume `resolve(...)` calls `request(...)` *directly*, + // otherwise the session will get overloaded. + listeners.shift().resolve(session); + } + + const where = this.queue[normalizedOptions]; + if (where[origin].listeners.length === 0) { + delete where[origin]; + + if (Object.keys(where).length === 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] = session.originSet; + + if (!isFree()) { + // The session is full. + return; + } + + processListeners(); + + // Close covered sessions (if possible). + closeCoveredSessions( + this.sessions[normalizedOptions], + session + ); + }); + + session.once('remoteSettings', () => { + // Fix Node.js bug preventing the process from exiting + session.ref(); + session.unref(); + + this._sessionsCount++; + + // The Agent could have been destroyed already. + if (entry.destroyed) { + const error = new Error('Agent has been destroyed'); + + for (const listener of listeners) { + listener.reject(error); + } + + session.destroy(); + return; + } + + session[kOriginSet] = session.originSet; + + { + const where = this.sessions; + + if (normalizedOptions in where) { + const sessions = where[normalizedOptions]; + sessions.splice( + getSortedIndex(sessions, session, compareSessions), + 0, + session + ); + } else { + where[normalizedOptions] = [session]; + } + } + + this._freeSessionsCount += 1; + receivedSettings = true; + + this.emit('session', session); + + processListeners(); + removeFromQueue(); + + // TODO: Close last recently used (or least used?) session + if ( + session[kCurrentStreamsCount] === 0 && + this._freeSessionsCount > this.maxFreeSessions + ) { + session.close(); + } + + // Check if we haven't managed to execute all listeners. + if (listeners.length !== 0) { + // Request for a new session with predefined listeners. + this.getSession(normalizedOrigin, options, listeners); + listeners.length = 0; + } + + // `session.remoteSettings.maxConcurrentStreams` might get increased + session.on('remoteSettings', () => { + processListeners(); + + // 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(); + + ++session[kCurrentStreamsCount]; + + if ( + session[kCurrentStreamsCount] === + session.remoteSettings.maxConcurrentStreams + ) { + this._freeSessionsCount--; + } + + stream.once('close', () => { + wasFree = isFree(); + + --session[kCurrentStreamsCount]; + + if (!session.destroyed && !session.closed) { + closeSessionIfCovered( + this.sessions[normalizedOptions], + session + ); + + if (isFree() && !session.closed) { + if (!wasFree) { + this._freeSessionsCount++; + + wasFree = true; + } + + const isEmpty = session[kCurrentStreamsCount] === 0; + + if (isEmpty) { + session.unref(); + } + + if ( + isEmpty && + (this._freeSessionsCount > this.maxFreeSessions || + session[kGracefullyClosing]) + ) { + session.close(); + } else { + closeCoveredSessions( + this.sessions[normalizedOptions], + session + ); + processListeners(); + } + } + } + }); + + return stream; + }; + } catch (error) { + for (const listener of listeners) { + listener.reject(error); + } + + removeFromQueue(); + } + }; + + entry.listeners = listeners; + entry.completed = false; + entry.destroyed = false; + + this.queue[normalizedOptions][normalizedOrigin] = entry; + this._tryToCreateNewSession(normalizedOptions, normalizedOrigin); + }); + } + + request(origin, options, headers, streamOptions) { + return new Promise((resolve, reject) => { + this.getSession(origin, options, [ + { + reject, + resolve: (session) => { + try { + resolve(session.request(headers, streamOptions)); + } catch (error) { + reject(error); + } + }, + }, + ]); + }); + } + + createConnection(origin, options) { + return Agent.connect(origin, options); + } + + static connect(origin, options) { + options.ALPNProtocols = ['h2']; + + const port = origin.port || 443; + const host = origin.hostname || origin.host; + + if (typeof options.servername === 'undefined') { + options.servername = host; + } + + return tls.connect(port, host, options); + } + + closeFreeSessions() { + for (const sessions of Object.values(this.sessions)) { + for (const session of sessions) { + if (session[kCurrentStreamsCount] === 0) { + session.close(); + } + } + } + } + + destroy(reason) { + for (const sessions of Object.values(this.sessions)) { + for (const session of sessions) { + session.destroy(reason); + } + } + + for (const entriesOfAuthority of Object.values(this.queue)) { + for (const entry of Object.values(entriesOfAuthority)) { + entry.destroyed = true; + } + } + + // New requests should NOT attach to destroyed sessions + this.queue = {}; + } + + get freeSessions() { + return getSessions({ agent: this, isFree: true }); + } + + get busySessions() { + return getSessions({ agent: this, isFree: false }); + } + } + + Agent.kCurrentStreamsCount = kCurrentStreamsCount; + Agent.kGracefullyClosing = kGracefullyClosing; + + module.exports = { + Agent, + globalAgent: new Agent(), + }; + + /***/ + }, + + /***/ 7167: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const http = __nccwpck_require__(3685); + const https = __nccwpck_require__(5687); + const resolveALPN = __nccwpck_require__(6624); + const QuickLRU = __nccwpck_require__(9273); + const Http2ClientRequest = __nccwpck_require__(9632); + const calculateServerName = __nccwpck_require__(1982); + const urlToOptions = __nccwpck_require__(2686); + + 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 onRemove = () => { + agent.removeSocket(socket, options); + socket.off('close', onClose); + socket.off('free', onFree); + socket.off('agentRemove', onRemove); + }; + + socket.on('agentRemove', onRemove); + + agent.emit('free', socket, options); + }; + + const resolveProtocol = 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 result.alpnProtocol; + } + + const { path, agent } = options; + options.path = options.socketPath; + + const resultPromise = resolveALPN(options); + queue.set(name, resultPromise); + + try { + const { socket, alpnProtocol } = await resultPromise; + cache.set(name, alpnProtocol); + + options.path = path; + + if (alpnProtocol === 'h2') { + // https://github.com/nodejs/node/issues/33343 + socket.destroy(); + } else { + const { globalAgent } = https; + const defaultCreateConnection = + https.Agent.prototype.createConnection; + + if (agent) { + if (agent.createConnection === defaultCreateConnection) { + installSocket(agent, socket, options); + } else { + socket.destroy(); + } + } else if ( + globalAgent.createConnection === defaultCreateConnection + ) { + installSocket(globalAgent, socket, options); + } else { + socket.destroy(); + } + } + + queue.delete(name); + + return alpnProtocol; + } catch (error) { + queue.delete(name); + + throw error; + } + } + + return cache.get(name); + }; + + module.exports = async (input, options, callback) => { + if (typeof input === 'string' || input instanceof URL) { + input = urlToOptions(new URL(input)); + } + + if (typeof options === 'function') { + callback = options; + options = undefined; + } + + options = { + ALPNProtocols: ['h2', 'http/1.1'], + ...input, + ...options, + resolveSocket: true, + }; + + 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); + options.port = options.port || (isHttps ? 443 : 80); + options._defaultAgent = isHttps ? https.globalAgent : http.globalAgent; + + const agents = options.agent; + + if (agents) { + if (agents.addRequest) { + throw new Error( + 'The `options.agent` object can contain only `http`, `https` or `http2` properties' + ); + } + + options.agent = agents[isHttps ? 'https' : 'http']; + } + + if (isHttps) { + const protocol = await resolveProtocol(options); + + if (protocol === 'h2') { + if (agents) { + options.agent = agents.http2; + } + + return new Http2ClientRequest(options, callback); + } + } + + return http.request(options, callback); + }; + + module.exports.protocolCache = cache; + + /***/ + }, + + /***/ 9632: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const http2 = __nccwpck_require__(5158); + const { Writable } = __nccwpck_require__(2781); + const { Agent, globalAgent } = __nccwpck_require__(9898); + const IncomingMessage = __nccwpck_require__(2575); + const urlToOptions = __nccwpck_require__(2686); + const proxyEvents = __nccwpck_require__(1818); + const isRequestPseudoHeader = __nccwpck_require__(1199); + const { + ERR_INVALID_ARG_TYPE, + ERR_INVALID_PROTOCOL, + ERR_HTTP_HEADERS_SENT, + ERR_INVALID_HTTP_TOKEN, + ERR_HTTP_INVALID_HEADER_VALUE, + ERR_INVALID_CHAR, + } = __nccwpck_require__(7087); + + const { + HTTP2_HEADER_STATUS, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + 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 isValidHttpToken = /^[\^`\-\w!#$%&*+.|~]+$/; + const isInvalidHeaderValue = /[^\t\u0020-\u007E\u0080-\u00FF]/; + + class ClientRequest extends Writable { + constructor(input, options, callback) { + super({ + autoDestroy: false, + }); + + const hasInput = typeof input === 'string' || input instanceof URL; + if (hasInput) { + input = urlToOptions(input instanceof URL ? input : new URL(input)); + } + + if (typeof options === 'function' || options === undefined) { + // (options, callback) + callback = options; + options = hasInput ? input : { ...input }; + } else { + // (input, options, callback) + options = { ...input, ...options }; + } + + if (options.h2session) { + this[kSession] = options.h2session; + } else if (options.agent === false) { + this.agent = new Agent({ maxFreeSessions: 0 }); + } else if ( + typeof options.agent === 'undefined' || + options.agent === null + ) { + if (typeof options.createConnection === 'function') { + // This is a workaround - we don't have to create the session on our own. + this.agent = new Agent({ maxFreeSessions: 0 }); + this.agent.createConnection = options.createConnection; + } else { + this.agent = globalAgent; + } + } else if (typeof options.agent.request === 'function') { + this.agent = options.agent; + } else { + throw new ERR_INVALID_ARG_TYPE( + 'options.agent', + ['Agent-like Object', 'undefined', 'false'], + options.agent + ); + } + + if (options.protocol && options.protocol !== 'https:') { + throw new ERR_INVALID_PROTOCOL(options.protocol, 'https:'); + } + + const port = + options.port || + options.defaultPort || + (this.agent && this.agent.defaultPort) || + 443; + const host = options.hostname || options.host || 'localhost'; + + // Don't enforce the origin via options. It may be changed in an Agent. + delete options.hostname; + delete options.host; + delete options.port; + + const { timeout } = options; + options.timeout = undefined; + + this[kHeaders] = Object.create(null); + this[kJobs] = []; + + this.socket = null; + this.connection = null; + + this.method = options.method || 'GET'; + this.path = options.path; + + this.res = null; + this.aborted = false; + this.reusedSocket = false; + + if (options.headers) { + for (const [header, value] of Object.entries(options.headers)) { + this.setHeader(header, value); + } + } + + 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. + if (port === 443) { + this[kOrigin] = `https://${host}`; + + if (!(':authority' in this[kHeaders])) { + this[kHeaders][':authority'] = host; + } + } else { + this[kOrigin] = `https://${host}:${port}`; + + if (!(':authority' in this[kHeaders])) { + this[kHeaders][':authority'] = `${host}:${port}`; + } + } + + 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() { + return this[kHeaders][HTTP2_HEADER_PATH]; + } + + set path(value) { + if (value) { + this[kHeaders][HTTP2_HEADER_PATH] = value; + } + } + + 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) { + if (this.destroyed) { + return; + } + + this.flushHeaders(); + + const callEnd = () => { + // For GET, HEAD and DELETE + if (this._mustNotHaveABody) { + 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(); + } + + _destroy(error, callback) { + if (this.res) { + this.res._dump(); + } + + if (this._request) { + this._request.destroy(); + } + + 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) { + proxyEvents(stream, this, [ + 'timeout', + 'continue', + 'close', + 'error', + ]); + } + + // Wait for the `finish` event. We don't want to emit the `response` event + // before `request.end()` is called. + const waitForEnd = (fn) => { + return (...args) => { + if (!this.writable && !this.destroyed) { + fn(...args); + } else { + this.once('finish', () => { + fn(...args); + }); + } + }; + }; + + // This event tells we are ready to listen for the data. + stream.once( + 'response', + waitForEnd((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; + + response.req = this; + response.statusCode = headers[HTTP2_HEADER_STATUS]; + response.headers = headers; + response.rawHeaders = rawHeaders; + + response.once('end', () => { + if (this.aborted) { + response.aborted = true; + response.emit('aborted'); + } else { + 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', () => { + response.push(null); + }); + + if (!this.emit('response', response)) { + // No listeners attached, dump the response. + response._dump(); + } + } + }) + ); + + // Emits `information` event + stream.once( + 'headers', + waitForEnd((headers) => + this.emit('information', { + statusCode: headers[HTTP2_HEADER_STATUS], + }) + ) + ); + + stream.once( + 'trailers', + waitForEnd((trailers, flags, rawTrailers) => { + const { res } = this; + + // Assigns trailers to the response object. + res.trailers = trailers; + res.rawTrailers = rawTrailers; + }) + ); + + const { socket } = stream.session; + this.socket = socket; + this.connection = socket; + + for (const job of this[kJobs]) { + job(); + } + + this.emit('socket', this.socket); + }; + + // Makes a HTTP2 request + if (this[kSession]) { + try { + onStream(this[kSession].request(this[kHeaders])); + } catch (error) { + this.emit('error', error); + } + } else { + this.reusedSocket = true; + + try { + onStream( + await this.agent.request( + this[kOrigin], + this[kOptions], + this[kHeaders] + ) + ); + } catch (error) { + this.emit('error', error); + } + } + } + + 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'); + } + + if ( + typeof name !== 'string' || + (!isValidHttpToken.test(name) && !isRequestPseudoHeader(name)) + ) { + throw new ERR_INVALID_HTTP_TOKEN('Header name', name); + } + + 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); + } + + this[kHeaders][name.toLowerCase()] = 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, + __nccwpck_require__ + ) => { + 'use strict'; + + const { Readable } = __nccwpck_require__(2781); + + class IncomingMessage extends Readable { + constructor(socket, highWaterMark) { + super({ + highWaterMark, + autoDestroy: false, + }); + + 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.connection = socket; + + this._dumped = false; + } + + _destroy(error) { + 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, + __nccwpck_require__ + ) => { + 'use strict'; + + const http2 = __nccwpck_require__(5158); + const agent = __nccwpck_require__(9898); + const ClientRequest = __nccwpck_require__(9632); + const IncomingMessage = __nccwpck_require__(2575); + const auto = __nccwpck_require__(7167); + + const request = (url, options, callback) => { + return 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, + request, + get, + auto, + }; + + /***/ + }, + + /***/ 1982: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const net = __nccwpck_require__(1808); + /* istanbul ignore file: https://github.com/nodejs/node/blob/v13.0.1/lib/_http_agent.js */ + + module.exports = (options) => { + let servername = options.host; + const hostHeader = options.headers && options.headers.host; + + if (hostHeader) { + if (hostHeader.startsWith('[')) { + const index = hostHeader.indexOf(']'); + if (index === -1) { + servername = hostHeader; + } else { + servername = hostHeader.slice(1, -1); + } + } else { + servername = hostHeader.split(':', 1)[0]; + } + } + + if (net.isIP(servername)) { + return ''; + } + + return servername; + }; + + /***/ + }, + + /***/ 7087: /***/ (module) => { + 'use strict'; + + /* 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) => { + return `Protocol "${args[0]}" not supported. Expected "${args[1]}"`; + }); + + makeError(Error, 'ERR_HTTP_HEADERS_SENT', (args) => { + return `Cannot ${args[0]} headers after they are sent to the client`; + }); + + makeError(TypeError, 'ERR_INVALID_HTTP_TOKEN', (args) => { + return `${args[0]} must be a valid HTTP token [${args[1]}]`; + }); + + makeError(TypeError, 'ERR_HTTP_INVALID_HEADER_VALUE', (args) => { + return `Invalid value "${args[0]} for header "${args[1]}"`; + }); + + makeError(TypeError, 'ERR_INVALID_CHAR', (args) => { + return `Invalid character in ${args[0]} [${args[1]}]`; + }); + + /***/ + }, + + /***/ 1199: /***/ (module) => { + 'use strict'; + + module.exports = (header) => { + switch (header) { + case ':method': + case ':scheme': + case ':authority': + case ':path': + return true; + default: + return false; + } + }; + + /***/ + }, + + /***/ 1818: /***/ (module) => { + 'use strict'; + + module.exports = (from, to, events) => { + for (const event of events) { + from.on(event, (...args) => to.emit(event, ...args)); + } + }; + + /***/ + }, + + /***/ 2686: /***/ (module) => { + 'use strict'; + + /* istanbul ignore file: https://github.com/nodejs/node/blob/a91293d4d9ab403046ab5eb022332e4e3d249bd3/lib/internal/url.js#L1257 */ + + module.exports = (url) => { + const options = { + protocol: url.protocol, + hostname: + typeof url.hostname === 'string' && 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 (typeof url.port === 'string' && url.port.length !== 0) { + options.port = Number(url.port); + } + + if (url.username || url.password) { + options.auth = `${url.username || ''}:${url.password || ''}`; + } + + return options; + }; + + /***/ + }, + + /***/ 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, + __nccwpck_require__ + ) => { + 'use strict'; + + const EventEmitter = __nccwpck_require__(2361); + const JSONB = __nccwpck_require__(2820); + const compressBrotli = __nccwpck_require__(5728); + + const loadStore = (options) => { + const adapters = { + redis: '@keyv/redis', + mongodb: '@keyv/mongo', + mongo: '@keyv/mongo', + sqlite: '@keyv/sqlite', + postgresql: '@keyv/postgres', + postgres: '@keyv/postgres', + mysql: '@keyv/mysql', + etcd: '@keyv/etcd', + }; + 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', + ]; + + class Keyv extends EventEmitter { + constructor(uri, 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.compress) { + const brotli = compressBrotli(this.opts.compress.opts); + this.opts.serialize = async ({ value, expires }) => + brotli.serialize({ + value: await brotli.compress(value), + expires, + }); + this.opts.deserialize = async (data) => { + const { value, expires } = brotli.deserialize(data); + return { value: await brotli.decompress(value), expires }; + }; + } + + if (typeof this.opts.store.on === 'function') { + 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 = + typeof raw === 'string' ? this.opts.deserialize(raw) : 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 this.opts.store.namespace + ? key.split(':').splice(1).join(':') + : key; + } + + 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) + : 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.every((x) => x === undefined) ? [] : data; + }); + } + + return Promise.resolve() + .then(() => + isArray ? store.getMany(keyPrefixed) : store.get(keyPrefixed) + ) + .then((data) => + typeof data === 'string' ? this.opts.deserialize(data) : data + ) + .then((data) => { + // Console.log('get', data); + if (data === undefined || data === null) { + return undefined; + } + + if (isArray) { + const result = []; + if (data.length === 0) { + return []; + } + + 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.every((x) => x === undefined) ? [] : 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; + }); + } + } + + module.exports = Keyv; + + /***/ + }, + + /***/ 9662: /***/ (module) => { + 'use strict'; + + module.exports = (object) => { + const result = {}; + + for (const [key, value] of Object.entries(object)) { + result[key.toLowerCase()] = value; + } + + return result; + }; + + /***/ + }, + + /***/ 2610: /***/ (module) => { + 'use strict'; + + // 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 knownProps = [ + 'destroy', + 'setTimeout', + 'socket', + 'headers', + 'trailers', + 'rawHeaders', + 'statusCode', + 'httpVersion', + 'httpVersionMinor', + 'httpVersionMajor', + 'rawTrailers', + 'statusMessage', + ]; + + module.exports = (fromStream, toStream) => { + const fromProps = new Set(Object.keys(fromStream).concat(knownProps)); + + for (const prop of fromProps) { + // Don't overwrite existing properties + if (prop in toStream) { + continue; + } + + toStream[prop] = + typeof fromStream[prop] === 'function' + ? fromStream[prop].bind(fromStream) + : fromStream[prop]; + } + }; + + /***/ + }, + + /***/ 1223: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + var wrappy = __nccwpck_require__(2940); + module.exports = wrappy(once); + module.exports.strict = wrappy(onceStrict); + + once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this); + }, + configurable: true, + }); + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this); + }, + configurable: true, + }); + }); + + function once(fn) { + var f = function () { + if (f.called) return f.value; + f.called = true; + return (f.value = fn.apply(this, arguments)); + }; + f.called = false; + return f; + } + + function onceStrict(fn) { + var f = function () { + if (f.called) throw new Error(f.onceError); + f.called = true; + return (f.value = fn.apply(this, arguments)); + }; + var name = fn.name || 'Function wrapped with `once`'; + f.onceError = name + " shouldn't be called more than once"; + f.called = false; + return f; + } + + /***/ + }, + + /***/ 9072: /***/ (module) => { + 'use strict'; + + class CancelError extends Error { + constructor(reason) { + super(reason || 'Promise was canceled'); + this.name = 'CancelError'; + } + + get isCanceled() { + return true; + } + } + + class PCancelable { + static fn(userFn) { + return (...arguments_) => { + return new PCancelable((resolve, reject, onCancel) => { + arguments_.push(onCancel); + // eslint-disable-next-line promise/prefer-await-to-then + userFn(...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) => { + 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; + }, + }, + }); + + return executor(onResolve, onReject, onCancel); + }); + } + + then(onFulfilled, onRejected) { + // eslint-disable-next-line promise/prefer-await-to-then + return this._promise.then(onFulfilled, onRejected); + } + + catch(onRejected) { + return this._promise.catch(onRejected); + } + + finally(onFinally) { + return this._promise.finally(onFinally); + } + + cancel(reason) { + if (!this._isPending || this._isCanceled) { + return; + } + + if (this._cancelHandlers.length > 0) { + try { + for (const handler of this._cancelHandlers) { + handler(); + } + } catch (error) { + this._reject(error); + } + } + + this._isCanceled = true; + if (this._rejectOnCancel) { + this._reject(new CancelError(reason)); + } + } + + get isCanceled() { + return this._isCanceled; + } + } + + Object.setPrototypeOf(PCancelable.prototype, Promise.prototype); + + module.exports = PCancelable; + module.exports.CancelError = CancelError; + + /***/ + }, + + /***/ 1940: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + var qs = __nccwpck_require__(3477), + url = __nccwpck_require__(7310), + xtend = __nccwpck_require__(1208); + + const PARSE_LINK_HEADER_MAXLEN = + parseInt(process.env.PARSE_LINK_HEADER_MAXLEN) || 2000; + const PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED = + process.env.PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED != null; + + function hasRel(x) { + return x && x.rel; + } + + function intoRels(acc, x) { + function splitRel(rel) { + acc[rel] = xtend(x, { rel: rel }); + } + + x.rel.split(/\s+/).forEach(splitRel); + + return acc; + } + + function createObjects(acc, p) { + // rel="next" => 1: rel 2: next + var m = p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/); + if (m) acc[m[1]] = m[2]; + return acc; + } + + function parseLink(link) { + try { + var m = link.match(/]*)>(.*)/), + linkUrl = m[1], + parts = m[2].split(';'), + parsedUrl = url.parse(linkUrl), + qry = qs.parse(parsedUrl.query); + + parts.shift(); + + var info = parts.reduce(createObjects, {}); + + info = xtend(qry, info); + info.url = linkUrl; + return info; + } catch (e) { + return null; + } + } + + function checkHeader(linkHeader) { + if (!linkHeader) return false; + + if (linkHeader.length > PARSE_LINK_HEADER_MAXLEN) { + if (PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED) { + throw new Error( + 'Input string too long, it should be under ' + + PARSE_LINK_HEADER_MAXLEN + + ' characters.' + ); + } else { + return false; + } + } + return true; + } + + module.exports = function (linkHeader) { + if (!checkHeader(linkHeader)) return null; + + return linkHeader + .split(/,\s* { + var once = __nccwpck_require__(1223); + var eos = __nccwpck_require__(1205); + var fs = __nccwpck_require__(7147); // we only need fs to get the ReadStream and WriteStream prototypes + + var noop = function () {}; + var ancient = /^v?\.0/.test(process.version); + + var isFn = function (fn) { + return typeof fn === 'function'; + }; + + var isFS = function (stream) { + if (!ancient) return false; // newer node version do not need to care about fs is a special way + if (!fs) return false; // browser + return ( + (stream instanceof (fs.ReadStream || noop) || + stream instanceof (fs.WriteStream || noop)) && + isFn(stream.close) + ); + }; + + var isRequest = function (stream) { + return stream.setHeader && isFn(stream.abort); + }; + + var destroyer = function (stream, reading, writing, callback) { + callback = once(callback); + + var closed = false; + stream.on('close', function () { + closed = true; + }); + + eos(stream, { readable: reading, writable: writing }, function (err) { + if (err) return callback(err); + closed = true; + callback(); + }); + + var destroyed = false; + return function (err) { + if (closed) return; + if (destroyed) return; + destroyed = true; + + if (isFS(stream)) return stream.close(noop); // use close for fs streams to avoid fd leaks + if (isRequest(stream)) return stream.abort(); // request.destroy just do .end - .abort is what we want + + if (isFn(stream.destroy)) return stream.destroy(); + + callback(err || new Error('stream was destroyed')); + }; + }; + + var call = function (fn) { + fn(); + }; + + var pipe = function (from, to) { + return from.pipe(to); + }; + + var pump = function () { + var streams = Array.prototype.slice.call(arguments); + var callback = + (isFn(streams[streams.length - 1] || noop) && streams.pop()) || noop; + + if (Array.isArray(streams[0])) streams = streams[0]; + if (streams.length < 2) + throw new Error('pump requires two streams per minimum'); + + var error; + var destroys = streams.map(function (stream, i) { + var reading = i < streams.length - 1; + var writing = i > 0; + return destroyer(stream, reading, writing, function (err) { + if (!error) error = err; + if (err) destroys.forEach(call); + if (reading) return; + destroys.forEach(call); + callback(error); + }); + }); + + return streams.reduce(pipe); + }; + + module.exports = pump; + + /***/ + }, + + /***/ 9273: /***/ (module) => { + 'use strict'; + + 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, + __nccwpck_require__ + ) => { + 'use strict'; + + const tls = __nccwpck_require__(4404); + + module.exports = (options = {}) => + new Promise((resolve, reject) => { + const socket = tls.connect(options, () => { + if (options.resolveSocket) { + socket.off('error', reject); + resolve({ alpnProtocol: socket.alpnProtocol, socket }); + } else { + socket.destroy(); + resolve({ alpnProtocol: socket.alpnProtocol }); + } + }); + + socket.on('error', reject); + }); + + /***/ + }, + + /***/ 9004: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict'; + + const Readable = __nccwpck_require__(2781).Readable; + const lowercaseKeys = __nccwpck_require__(9662); + + class Response extends Readable { + 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 Buffer)) { + throw new TypeError('Argument `body` should be a buffer'); + } + if (typeof url !== 'string') { + throw new TypeError('Argument `url` should be a string'); + } + + super(); + this.statusCode = statusCode; + this.headers = lowercaseKeys(headers); + this.body = body; + this.url = url; + } + + _read() { + this.push(this.body); + this.push(null); + } + } + + module.exports = Response; + + /***/ + }, + + /***/ 4294: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + module.exports = __nccwpck_require__(4219); + + /***/ + }, + + /***/ 4219: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict'; + + var net = __nccwpck_require__(1808); + var tls = __nccwpck_require__(4404); + var http = __nccwpck_require__(3685); + var https = __nccwpck_require__(5687); + var events = __nccwpck_require__(2361); + var assert = __nccwpck_require__(9491); + var util = __nccwpck_require__(3837); exports.httpOverHttp = httpOverHttp; exports.httpsOverHttp = httpsOverHttp; @@ -5188,7 +14453,7 @@ /***/ }, - /***/ 810: /***/ (module) => { + /***/ 8810: /***/ (module) => { /*! * Determine if an object is a Buffer * @@ -5208,7 +14473,7 @@ /***/ }, - /***/ 157: /***/ (module) => { + /***/ 2157: /***/ (module) => { /*! * Determine if an object is a Buffer * @@ -5228,7 +14493,69 @@ /***/ }, - /***/ 350: /***/ function ( + /***/ 2940: /***/ (module) => { + // Returns a wrapper function that returns a wrapped callback + // The wrapper function should do some stuff, and return a + // presumably different callback function. + // This makes sure that own properties are retained, so that + // decorations and such are not lost along the way. + module.exports = wrappy; + function wrappy(fn, cb) { + if (fn && cb) return wrappy(fn)(cb); + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function'); + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k]; + }); + + return wrapper; + + function wrapper() { + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + var ret = fn.apply(this, args); + var cb = args[args.length - 1]; + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k]; + }); + } + return ret; + } + } + + /***/ + }, + + /***/ 1208: /***/ (module) => { + module.exports = extend; + + var hasOwnProperty = Object.prototype.hasOwnProperty; + + function extend() { + var target = {}; + + for (var i = 0; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + } + + /***/ + }, + + /***/ 6350: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -5323,9 +14650,15 @@ ); }); }; + var __importDefault = + (this && this.__importDefault) || + function (mod) { + return mod && mod.__esModule ? mod : { default: mod }; + }; Object.defineProperty(exports, '__esModule', { value: true }); - const core = __importStar(__nccwpck_require__(186)); - const exec = __importStar(__nccwpck_require__(514)); + const core = __importStar(__nccwpck_require__(2186)); + const exec = __importStar(__nccwpck_require__(1514)); + const promises_1 = __importDefault(__nccwpck_require__(3292)); const { GITHUB_REPOSITORY, GITHUB_REF } = process.env; const branch = GITHUB_REF === null || GITHUB_REF === void 0 @@ -5407,13 +14740,27 @@ } }); } + pushNewFiles(files = []) { + return __awaiter(this, void 0, void 0, function* () { + if (!files.length) return; + yield this.pull(); + yield Promise.all( + files.map(({ filename, data }) => + promises_1.default.writeFile(filename, data) + ) + ); + yield this.add(files.map(({ filename }) => filename)); + yield this.commit(`chore(updates): updated entries in files`); + yield this.push(); + }); + } } exports['default'] = new Git(); /***/ }, - /***/ 15: /***/ function ( + /***/ 3015: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -5514,25 +14861,21 @@ }; var _a; Object.defineProperty(exports, '__esModule', { value: true }); - exports.pushNewFiles = - exports.MARKDOWN_FILENAME = + exports.MARKDOWN_FILENAME = exports.generateMd = exports.renderer = exports.API_STARRED_URL = exports.REPO_USERNAME = void 0; - const fs_1 = __importDefault(__nccwpck_require__(147)); - const ejs_1 = __importDefault(__nccwpck_require__(431)); - const core = __importStar(__nccwpck_require__(186)); - const remark_1 = __nccwpck_require__(752); - const remark_toc_1 = __importDefault(__nccwpck_require__(800)); - const git_1 = __importDefault(__nccwpck_require__(350)); + const ejs_1 = __importDefault(__nccwpck_require__(8431)); + const core = __importStar(__nccwpck_require__(2186)); + const remark_1 = __nccwpck_require__(7331); + const remark_toc_1 = __importDefault(__nccwpck_require__(6800)); exports.REPO_USERNAME = (_a = process.env.GITHUB_REPOSITORY) === null || _a === void 0 ? void 0 : _a.split('/')[0]; exports.API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${exports.REPO_USERNAME}/starred`; - const fsp = fs_1.default.promises; function renderer(data, templateString) { return __awaiter(this, void 0, void 0, function* () { try { @@ -5560,26 +14903,11 @@ } exports.generateMd = generateMd; exports.MARKDOWN_FILENAME = core.getInput('output-filename'); - function pushNewFiles(files = []) { - return __awaiter(this, void 0, void 0, function* () { - if (!files.length) return; - yield git_1.default.pull(); - yield Promise.all( - files.map(({ filename, data }) => fsp.writeFile(filename, data)) - ); - yield git_1.default.add(files.map(({ filename }) => filename)); - yield git_1.default.commit( - `chore(updates): updated entries in files` - ); - yield git_1.default.push(); - }); - } - exports.pushNewFiles = pushNewFiles; /***/ }, - /***/ 144: /***/ function ( + /***/ 6144: /***/ function ( __unused_webpack_module, exports, __nccwpck_require__ @@ -5680,15 +15008,19 @@ }; Object.defineProperty(exports, '__esModule', { value: true }); exports.run = exports.main = void 0; - const core = __importStar(__nccwpck_require__(186)); - const promises_1 = __nccwpck_require__(292); - const gh_star_fetch_1 = __importDefault(__nccwpck_require__(696)); - const helpers_1 = __nccwpck_require__(15); - const template_1 = __importDefault(__nccwpck_require__(932)); + const path_1 = __importDefault(__nccwpck_require__(1017)); + const core = __importStar(__nccwpck_require__(2186)); + const promises_1 = __nccwpck_require__(3292); + const gh_star_fetch_1 = __importDefault(__nccwpck_require__(6636)); + const helpers_1 = __nccwpck_require__(3015); + const git_1 = __importDefault(__nccwpck_require__(6350)); function main() { return __awaiter(this, void 0, void 0, function* () { // set default template - let template = template_1.default; + let template = yield (0, promises_1.readFile)( + path_1.default.resolve(__dirname, './TEMPLATE.md'), + 'utf8' + ); // get template if found in the repo const customTemplatePath = core.getInput('template-path'); core.info( @@ -5715,7 +15047,7 @@ template ); const markdown = yield (0, helpers_1.generateMd)(rendered); - yield (0, helpers_1.pushNewFiles)([ + yield git_1.default.pushNewFiles([ { filename: helpers_1.MARKDOWN_FILENAME, data: markdown, @@ -5749,135 +15081,154 @@ /***/ }, - /***/ 932: /***/ (__unused_webpack_module, exports) => { - 'use strict'; - - Object.defineProperty(exports, '__esModule', { value: true }); - exports[ - 'default' - ] = `# <%= username %> Awesome List [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) - -> :star: generated with [simonecorsi/mawesome](https://github.com/simonecorsi/mawesome) - -## Table of Contents - -<% for(let [language, repositories] of stars) { %> -## <%= language %> - -<% for(let repo of repositories) { %>- [<%= repo.full_name %>](<%= repo.html_url %>) - <%= repo.description %> -<% } %> - -<% } %> -`; - - /***/ - }, - - /***/ 696: /***/ (module) => { - module.exports = eval('require')('gh-star-fetch'); - - /***/ - }, - - /***/ 491: /***/ (module) => { + /***/ 9491: /***/ (module) => { 'use strict'; module.exports = require('assert'); /***/ }, - /***/ 81: /***/ (module) => { + /***/ 4300: /***/ (module) => { + 'use strict'; + module.exports = require('buffer'); + + /***/ + }, + + /***/ 2081: /***/ (module) => { 'use strict'; module.exports = require('child_process'); /***/ }, - /***/ 361: /***/ (module) => { + /***/ 9523: /***/ (module) => { + 'use strict'; + module.exports = require('dns'); + + /***/ + }, + + /***/ 2361: /***/ (module) => { 'use strict'; module.exports = require('events'); /***/ }, - /***/ 147: /***/ (module) => { + /***/ 7147: /***/ (module) => { 'use strict'; module.exports = require('fs'); /***/ }, - /***/ 292: /***/ (module) => { + /***/ 3292: /***/ (module) => { 'use strict'; module.exports = require('fs/promises'); /***/ }, - /***/ 685: /***/ (module) => { + /***/ 3685: /***/ (module) => { 'use strict'; module.exports = require('http'); /***/ }, - /***/ 687: /***/ (module) => { + /***/ 5158: /***/ (module) => { + 'use strict'; + module.exports = require('http2'); + + /***/ + }, + + /***/ 5687: /***/ (module) => { 'use strict'; module.exports = require('https'); /***/ }, - /***/ 808: /***/ (module) => { + /***/ 1808: /***/ (module) => { 'use strict'; module.exports = require('net'); /***/ }, - /***/ 37: /***/ (module) => { + /***/ 2037: /***/ (module) => { 'use strict'; module.exports = require('os'); /***/ }, - /***/ 17: /***/ (module) => { + /***/ 1017: /***/ (module) => { 'use strict'; module.exports = require('path'); /***/ }, - /***/ 576: /***/ (module) => { + /***/ 3477: /***/ (module) => { + 'use strict'; + module.exports = require('querystring'); + + /***/ + }, + + /***/ 2781: /***/ (module) => { + 'use strict'; + module.exports = require('stream'); + + /***/ + }, + + /***/ 1576: /***/ (module) => { 'use strict'; module.exports = require('string_decoder'); /***/ }, - /***/ 512: /***/ (module) => { + /***/ 9512: /***/ (module) => { 'use strict'; module.exports = require('timers'); /***/ }, - /***/ 404: /***/ (module) => { + /***/ 4404: /***/ (module) => { 'use strict'; module.exports = require('tls'); /***/ }, - /***/ 837: /***/ (module) => { + /***/ 7310: /***/ (module) => { + 'use strict'; + module.exports = require('url'); + + /***/ + }, + + /***/ 3837: /***/ (module) => { 'use strict'; module.exports = require('util'); /***/ }, - /***/ 165: /***/ ( + /***/ 9796: /***/ (module) => { + 'use strict'; + module.exports = require('zlib'); + + /***/ + }, + + /***/ 9165: /***/ ( __unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__ @@ -5946,7 +15297,7 @@ /***/ }, - /***/ 800: /***/ ( + /***/ 6800: /***/ ( __unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__ @@ -5963,9 +15314,9 @@ // EXTERNAL MODULE: ./node_modules/github-slugger/index.js var github_slugger = __nccwpck_require__(237); // EXTERNAL MODULE: ./node_modules/mdast-util-to-string/index.js - var mdast_util_to_string = __nccwpck_require__(165); + var mdast_util_to_string = __nccwpck_require__(9165); // EXTERNAL MODULE: ./node_modules/unist-util-is/index.js - var unist_util_is = __nccwpck_require__(481); // CONCATENATED MODULE: ./node_modules/mdast-util-toc/node_modules/unist-util-visit-parents/color.js + var unist_util_is = __nccwpck_require__(1481); // CONCATENATED MODULE: ./node_modules/mdast-util-toc/node_modules/unist-util-visit-parents/color.js /** * @param {string} d * @returns {string} @@ -6334,7 +15685,7 @@ } // EXTERNAL MODULE: ./node_modules/extend/index.js - var extend = __nccwpck_require__(171); // CONCATENATED MODULE: ./node_modules/mdast-util-toc/lib/contents.js + var extend = __nccwpck_require__(8171); // CONCATENATED MODULE: ./node_modules/mdast-util-toc/lib/contents.js /** * @typedef {import('mdast').Root|import('mdast').Content} Node * @typedef {import('mdast').List} List @@ -6587,7 +15938,7 @@ /***/ }, - /***/ 752: /***/ ( + /***/ 7331: /***/ ( __unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__ @@ -6630,9 +15981,9 @@ } // EXTERNAL MODULE: ./node_modules/unified/node_modules/is-buffer/index.js - var is_buffer = __nccwpck_require__(810); + var is_buffer = __nccwpck_require__(8810); // EXTERNAL MODULE: ./node_modules/extend/index.js - var extend = __nccwpck_require__(171); // CONCATENATED MODULE: ./node_modules/unified/node_modules/is-plain-obj/index.js + var extend = __nccwpck_require__(8171); // CONCATENATED MODULE: ./node_modules/unified/node_modules/is-plain-obj/index.js function isPlainObject(value) { if (Object.prototype.toString.call(value) !== '[object Object]') { return false; @@ -6806,7 +16157,7 @@ } // EXTERNAL MODULE: ./node_modules/vfile/node_modules/is-buffer/index.js - var node_modules_is_buffer = __nccwpck_require__(157); // CONCATENATED MODULE: ./node_modules/unist-util-stringify-position/index.js + var node_modules_is_buffer = __nccwpck_require__(2157); // CONCATENATED MODULE: ./node_modules/unist-util-stringify-position/index.js /** * @typedef {import('unist').Point} Point * @typedef {import('unist').Node} Node @@ -7024,7 +16375,7 @@ VFileMessage.prototype.position = null; // EXTERNAL MODULE: external "path" - var external_path_ = __nccwpck_require__(17); // CONCATENATED MODULE: external "process" + var external_path_ = __nccwpck_require__(1017); // CONCATENATED MODULE: external "process" const external_process_namespaceObject = require('process'); // CONCATENATED MODULE: ./node_modules/vfile/lib/minurl.shared.js /** * @typedef URL @@ -7058,9 +16409,10 @@ // @ts-expect-error: indexable. fileURLOrPath.origin ); - } // CONCATENATED MODULE: external "url" + } - const external_url_namespaceObject = require('url'); // CONCATENATED MODULE: ./node_modules/vfile/lib/index.js + // EXTERNAL MODULE: external "url" + var external_url_ = __nccwpck_require__(7310); // CONCATENATED MODULE: ./node_modules/vfile/lib/index.js /** * @typedef {import('unist').Node} Node * @typedef {import('unist').Position} Position @@ -7261,7 +16613,7 @@ */ set path(path) { if (isUrl(path)) { - path = (0, external_url_namespaceObject.fileURLToPath)(path); + path = (0, external_url_.fileURLToPath)(path); } assertNonEmpty(path, 'path'); @@ -8081,7 +17433,7 @@ } // EXTERNAL MODULE: ./node_modules/mdast-util-to-string/index.js - var mdast_util_to_string = __nccwpck_require__(165); // CONCATENATED MODULE: ./node_modules/micromark-util-chunked/index.js + var mdast_util_to_string = __nccwpck_require__(9165); // CONCATENATED MODULE: ./node_modules/micromark-util-chunked/index.js /** * Like `Array#splice`, but smarter for giant arrays. * @@ -19134,7 +28486,7 @@ } // EXTERNAL MODULE: ./node_modules/unist-util-is/index.js - var unist_util_is = __nccwpck_require__(481); // CONCATENATED MODULE: ./node_modules/unist-util-visit-parents/color.js + var unist_util_is = __nccwpck_require__(1481); // CONCATENATED MODULE: ./node_modules/unist-util-visit-parents/color.js /** * @param {string} d * @returns {string} @@ -20782,7 +30134,7 @@ /***/ }, - /***/ 481: /***/ ( + /***/ 1481: /***/ ( __unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__ @@ -21050,7 +30402,7 @@ /***/ }, - /***/ 558: /***/ (module) => { + /***/ 3558: /***/ (module) => { 'use strict'; module.exports = { i8: '3.1.7' }; @@ -21156,7 +30508,7 @@ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module is referenced by other modules so it can't be inlined - /******/ var __webpack_exports__ = __nccwpck_require__(144); + /******/ var __webpack_exports__ = __nccwpck_require__(6144); /******/ module.exports = __webpack_exports__; /******/ /******/ diff --git a/src/git.ts b/src/git.ts index 0dda424..7d1cbe7 100644 --- a/src/git.ts +++ b/src/git.ts @@ -2,10 +2,17 @@ import * as core from '@actions/core'; import * as exec from '@actions/exec'; +import fs from 'fs/promises'; const { GITHUB_REPOSITORY, GITHUB_REF } = process.env; const branch = GITHUB_REF?.replace('refs/heads/', ''); + +type File = { + filename: string; + data: string; +}; + class Git { constructor() { const githubToken = core.getInput('github-token', { required: true }); @@ -89,6 +96,20 @@ class Git { updateOrigin = (repo: string) => this.exec(`remote set-url origin ${repo}`); createTag = (tag: string) => this.exec(`tag -a ${tag} -m "${tag}"`); + + async pushNewFiles(files: File[] = []): Promise { + if (!files.length) return; + + await this.pull(); + + await Promise.all( + files.map(({ filename, data }) => fs.writeFile(filename, data)) + ); + + await this.add(files.map(({ filename }) => filename)); + await this.commit(`chore(updates): updated entries in files`); + await this.push(); + } } export default new Git(); diff --git a/src/helpers.ts b/src/helpers.ts index 3047551..adc6c61 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,15 +1,11 @@ -import fs from 'fs'; import ejs from 'ejs'; import * as core from '@actions/core'; import { remark } from 'remark'; import toc from 'remark-toc'; -import git from './git'; export const REPO_USERNAME = process.env.GITHUB_REPOSITORY?.split('/')[0]; export const API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${REPO_USERNAME}/starred`; -const fsp = fs.promises; - export async function renderer( data: { [key: string]: any }, templateString: string @@ -38,22 +34,3 @@ export function generateMd(data: string): Promise { } export const MARKDOWN_FILENAME: string = core.getInput('output-filename'); - -type File = { - filename: string; - data: string; -}; - -export async function pushNewFiles(files: File[] = []): Promise { - if (!files.length) return; - - await git.pull(); - - await Promise.all( - files.map(({ filename, data }) => fsp.writeFile(filename, data)) - ); - - await git.add(files.map(({ filename }) => filename)); - await git.commit(`chore(updates): updated entries in files`); - await git.push(); -} diff --git a/src/index.ts b/src/index.ts index 650cf16..daf9e9e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,9 +7,9 @@ import { renderer, REPO_USERNAME, generateMd, - pushNewFiles, MARKDOWN_FILENAME, } from './helpers'; +import git from './git'; export async function main() { // set default template @@ -43,7 +43,7 @@ export async function main() { const markdown: string = await generateMd(rendered); - await pushNewFiles([ + await git.pushNewFiles([ { filename: MARKDOWN_FILENAME, data: markdown, @@ -55,7 +55,7 @@ export async function main() { ]); } -export async function run(): Promise { +export async function run(): Promise { try { await main(); } catch (error) {