From 44c50457d4a57bf60ceb80d4663c8fc84cdc8912 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 11:16:20 +0000 Subject: [PATCH 1/3] Update all non-major dependencies --- cmd/gradle-cache/testdata/gradle-project/build.gradle.kts | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- go.mod | 8 ++++---- go.sum | 6 ++++++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cmd/gradle-cache/testdata/gradle-project/build.gradle.kts b/cmd/gradle-cache/testdata/gradle-project/build.gradle.kts index 6dd4308..1f9b38f 100644 --- a/cmd/gradle-cache/testdata/gradle-project/build.gradle.kts +++ b/cmd/gradle-cache/testdata/gradle-project/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - kotlin("jvm") version "2.3.20" + kotlin("jvm") version "2.4.21" id("com.example.included") } diff --git a/cmd/gradle-cache/testdata/gradle-project/gradle/wrapper/gradle-wrapper.properties b/cmd/gradle-cache/testdata/gradle-project/gradle/wrapper/gradle-wrapper.properties index c42672d..1a31fd1 100644 --- a/cmd/gradle-cache/testdata/gradle-project/gradle/wrapper/gradle-wrapper.properties +++ b/cmd/gradle-cache/testdata/gradle-project/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/cmd/gradle-cache/testdata/groovy-project/gradle/wrapper/gradle-wrapper.properties b/cmd/gradle-cache/testdata/groovy-project/gradle/wrapper/gradle-wrapper.properties index c42672d..1a31fd1 100644 --- a/cmd/gradle-cache/testdata/groovy-project/gradle/wrapper/gradle-wrapper.properties +++ b/cmd/gradle-cache/testdata/groovy-project/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/go.mod b/go.mod index 292ff9d..2fab9ee 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,14 @@ module github.com/block/bundle-cache -go 1.25.0 +go 1.26.0 require ( github.com/alecthomas/errors v0.9.1 github.com/alecthomas/kong v1.16.1 - github.com/klauspost/compress v1.20.0 + github.com/klauspost/compress v1.20.3 github.com/minio/crc64nvme v1.1.1 - golang.org/x/sync v0.22.0 - golang.org/x/sys v0.47.0 + golang.org/x/sync v0.24.0 + golang.org/x/sys v0.49.0 ) require github.com/klauspost/cpuid/v2 v2.2.9 // indirect diff --git a/go.sum b/go.sum index 438b9d8..1a42164 100644 --- a/go.sum +++ b/go.sum @@ -28,6 +28,8 @@ github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= +github.com/klauspost/compress v1.20.3 h1:zWNoFqq/lSuYQRim3dUXlXeA0IqwuZGicdG5ZTfY5j4= +github.com/klauspost/compress v1.20.3/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI= @@ -38,6 +40,8 @@ golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA= +golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= @@ -48,3 +52,5 @@ golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA= +golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= From aa284d10e5efaaae5aee0b7d47746f180839c175 Mon Sep 17 00:00:00 2001 From: Josh Friend Date: Tue, 20 Oct 2026 11:22:43 -0400 Subject: [PATCH 2/3] Fix dependency update tooling and rebuild the Action Signed-off-by: Josh Friend --- action/package-lock.json | 22 +- action/package.json | 2 +- action/src/helpers.js | 14 +- action/src/main.js | 8 +- action/src/post.js | 12 +- action/src/pre.js | 4 +- bin/{.go@1.25.pkg => .go-1.26.6.pkg} | 0 bin/go | 2 +- bin/gofmt | 2 +- dist/main/index.js | 73969 +++++++++++++++---------- dist/post/index.js | 73807 ++++++++++++++---------- dist/pre/index.js | 73785 ++++++++++++++---------- renovate.json | 10 +- 13 files changed, 137770 insertions(+), 83867 deletions(-) rename bin/{.go@1.25.pkg => .go-1.26.6.pkg} (100%) diff --git a/action/package-lock.json b/action/package-lock.json index 972da33..33bb334 100644 --- a/action/package-lock.json +++ b/action/package-lock.json @@ -13,13 +13,13 @@ "@actions/tool-cache": "^4.0.0" }, "devDependencies": { - "@vercel/ncc": "^0.38.1" + "@vercel/ncc": "^0.45.0" } }, "node_modules/@actions/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", - "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", + "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", "license": "MIT", "dependencies": { "@actions/exec": "^3.0.0", @@ -65,9 +65,9 @@ } }, "node_modules/@vercel/ncc": { - "version": "0.38.4", - "resolved": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@vercel/ncc/-/ncc-0.38.4.tgz", - "integrity": "sha512-8LwjnlP39s08C08J5NstzriPvW1SP8Zfpp1BvC2sI35kPeZnHfxVkCwu4/+Wodgnd60UtT1n8K8zw+Mp7J9JmQ==", + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.45.0.tgz", + "integrity": "sha512-8zPi1yO2mHpoKTD+e+Bf0ZT3e+sWHSOyGapm9s7b5R0gxJi3CiFTqmeQiMEyu6ejrz2s09M8JkEoUaTWjBJPQQ==", "dev": true, "license": "MIT", "bin": { @@ -88,7 +88,7 @@ }, "node_modules/tunnel": { "version": "0.0.6", - "resolved": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/tunnel/-/tunnel-0.0.6.tgz", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "license": "MIT", "engines": { @@ -96,9 +96,9 @@ } }, "node_modules/undici": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.1.0.tgz", - "integrity": "sha512-E9MkTS4xXLnRPYqxH2e6Hr2/49e7WFDKczKcCaFH4VaZs2iNvHMqeIkyUAD9vM8kujy9TjVrRlQ5KkdEJxB2pw==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.12.2.tgz", + "integrity": "sha512-XtuDWVdqTLr3NAxm2ly9/hU6kUsJOgGh1RASzMBbsw6aWCOaQzHdW+QQDfdERjfJ2V5vL5pRPa4RetO9UfivDg==", "license": "MIT", "engines": { "node": ">=22.19.0" diff --git a/action/package.json b/action/package.json index f59e6aa..457b203 100644 --- a/action/package.json +++ b/action/package.json @@ -17,6 +17,6 @@ "@vercel/ncc": "^0.45.0" }, "overrides": { - "undici": "^8.0.0" + "undici": "^8.12.2" } } diff --git a/action/src/helpers.js b/action/src/helpers.js index ef83497..3d97f62 100644 --- a/action/src/helpers.js +++ b/action/src/helpers.js @@ -1,9 +1,9 @@ -const core = require("@actions/core"); -const exec = require("@actions/exec"); -const tc = require("@actions/tool-cache"); -const fs = require("fs"); -const os = require("os"); -const path = require("path"); +import * as core from "@actions/core"; +import * as exec from "@actions/exec"; +import * as tc from "@actions/tool-cache"; +import * as fs from "node:fs"; +import * as os from "node:os"; +import * as path from "node:path"; /** * Install the gradle-cache binary. Skips download if it's already on PATH. @@ -176,7 +176,7 @@ function isDefaultBranchBuild() { return def !== "HEAD" && refName === def; } -module.exports = { +export { install, backendArgs, commonArgs, diff --git a/action/src/main.js b/action/src/main.js index f0df0e8..a7a3665 100644 --- a/action/src/main.js +++ b/action/src/main.js @@ -1,6 +1,6 @@ -const core = require("@actions/core"); -const exec = require("@actions/exec"); -const { +import * as core from "@actions/core"; +import * as exec from "@actions/exec"; +import { backendArgs, commonArgs, gradleHomeArgs, @@ -10,7 +10,7 @@ const { resolveBranch, defaultBranch, isDefaultBranchBuild, -} = require("./helpers"); +} from "./helpers.js"; async function run() { try { diff --git a/action/src/post.js b/action/src/post.js index 7fe8e48..da11aef 100644 --- a/action/src/post.js +++ b/action/src/post.js @@ -1,8 +1,8 @@ -const fs = require("fs"); -const path = require("path"); -const core = require("@actions/core"); -const exec = require("@actions/exec"); -const { +import * as fs from "node:fs"; +import * as path from "node:path"; +import * as core from "@actions/core"; +import * as exec from "@actions/exec"; +import { backendArgs, commonArgs, gradleHomeArgs, @@ -10,7 +10,7 @@ const { gitDirArgs, execOptions, resolveBranch, -} = require("./helpers"); +} from "./helpers.js"; async function run() { try { diff --git a/action/src/pre.js b/action/src/pre.js index 351cabb..bd46c6e 100644 --- a/action/src/pre.js +++ b/action/src/pre.js @@ -1,5 +1,5 @@ -const core = require("@actions/core"); -const { install } = require("./helpers"); +import * as core from "@actions/core"; +import { install } from "./helpers.js"; async function run() { try { diff --git a/bin/.go@1.25.pkg b/bin/.go-1.26.6.pkg similarity index 100% rename from bin/.go@1.25.pkg rename to bin/.go-1.26.6.pkg diff --git a/bin/go b/bin/go index f96d538..c65eb1b 120000 --- a/bin/go +++ b/bin/go @@ -1 +1 @@ -.go@1.25.pkg \ No newline at end of file +.go-1.26.6.pkg \ No newline at end of file diff --git a/bin/gofmt b/bin/gofmt index f96d538..c65eb1b 120000 --- a/bin/gofmt +++ b/bin/gofmt @@ -1 +1 @@ -.go@1.25.pkg \ No newline at end of file +.go-1.26.6.pkg \ No newline at end of file diff --git a/dist/main/index.js b/dist/main/index.js index cbf3ed9..095decd 100644 --- a/dist/main/index.js +++ b/dist/main/index.js @@ -1,34062 +1,52001 @@ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 4914: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 9379: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(857)); -const utils_1 = __nccwpck_require__(302); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; + +const ANY = Symbol('SemVer ANY') +// hoisted class for cyclic dependency +class Comparator { + static get ANY () { + return ANY + } + + constructor (comp, options) { + options = parseOptions(options) + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; + + comp = comp.trim().split(/\s+/).join(' ') + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version } + + debug('comp', this) + } + + parse (comp) { + const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + const m = comp.match(r) + + if (!m) { + throw new TypeError(`Invalid comparator: ${comp}`) + } + + this.operator = m[1] !== undefined ? m[1] : '' + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } + } + + toString () { + return this.value + } + + test (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY || version === ANY) { + return true + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + return cmp(version, this.operator, this.semver, this.options) + } + + intersects (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (this.operator === '') { + if (this.value === '') { + return true + } + return new Range(comp.value, options).test(this.value) + } else if (comp.operator === '') { + if (comp.value === '') { + return true + } + return new Range(this.value, options).test(comp.semver) + } + + options = parseOptions(options) + + // Special cases where nothing can possibly be lower + if (options.includePrerelease && + (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { + return false + } + if (!options.includePrerelease && + (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { + return false + } + + // Same direction increasing (> or >=) + if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { + return true + } + // Same direction decreasing (< or <=) + if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { + return true + } + // same SemVer and both sides are inclusive (<= or >=) + if ( + (this.semver.version === comp.semver.version) && + this.operator.includes('=') && comp.operator.includes('=')) { + return true + } + // opposite directions less than + if (cmp(this.semver, '<', comp.semver, options) && + this.operator.startsWith('>') && comp.operator.startsWith('<')) { + return true + } + // opposite directions greater than + if (cmp(this.semver, '>', comp.semver, options) && + this.operator.startsWith('<') && comp.operator.startsWith('>')) { + return true + } + return false + } } -function escapeData(s) { - return (0, utils_1.toCommandValue)(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return (0, utils_1.toCommandValue)(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map + +module.exports = Comparator + +const parseOptions = __nccwpck_require__(356) +const { safeRe: re, t } = __nccwpck_require__(5471) +const cmp = __nccwpck_require__(8646) +const debug = __nccwpck_require__(1159) +const SemVer = __nccwpck_require__(7163) +const Range = __nccwpck_require__(6782) + /***/ }), -/***/ 7484: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 6782: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.platform = exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = exports.markdownSummary = exports.summary = exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(4914); -const file_command_1 = __nccwpck_require__(4753); -const utils_1 = __nccwpck_require__(302); -const os = __importStar(__nccwpck_require__(857)); -const path = __importStar(__nccwpck_require__(6928)); -const oidc_utils_1 = __nccwpck_require__(5306); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode || (exports.ExitCode = ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = (0, utils_1.toCommandValue)(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return (0, file_command_1.issueFileCommand)('ENV', (0, file_command_1.prepareKeyValueMessage)(name, val)); + +const SPACE_CHARACTERS = /\s+/g + +// hoisted class for cyclic dependency +class Range { + constructor (range, options) { + options = parseOptions(options) + + if (range instanceof Range) { + if ( + range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease + ) { + return range + } else { + return new Range(range.raw, options) + } } - (0, command_1.issueCommand)('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - (0, command_1.issueCommand)('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - (0, file_command_1.issueFileCommand)('PATH', inputPath); + + if (range instanceof Comparator) { + // just put it in the set and return + this.raw = range.value + this.set = [[range]] + this.formatted = undefined + return this } - else { - (0, command_1.issueCommand)('add-path', {}, inputPath); + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. + this.raw = range.trim().replace(SPACE_CHARACTERS, ' ') + + // First, split on || + this.set = this.raw + .split('||') + // map the range to a 2d array of comparators + .map(r => this.parseRange(r.trim())) + // throw out any comparator lists that are empty + // this generally means that it was not a valid range, which is allowed + // in loose mode, but will still throw if the WHOLE range is invalid. + .filter(c => c.length) + + if (!this.set.length) { + throw new TypeError(`Invalid SemVer Range: ${this.raw}`) + } + + // if we have any that are not the null set, throw out null sets. + if (this.set.length > 1) { + // keep the first one, in case they're all null sets + const first = this.set[0] + this.set = this.set.filter(c => !isNullSet(c[0])) + if (this.set.length === 0) { + this.set = [first] + } else if (this.set.length > 1) { + // if we have any that are *, then the range is just * + for (const c of this.set) { + if (c.length === 1 && isAny(c[0])) { + this.set = [c] + break + } + } + } } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); + + this.formatted = undefined + } + + get range () { + if (this.formatted === undefined) { + this.formatted = '' + for (let i = 0; i < this.set.length; i++) { + if (i > 0) { + this.formatted += '||' + } + const comps = this.set[i] + for (let k = 0; k < comps.length; k++) { + if (k > 0) { + this.formatted += ' ' + } + this.formatted += comps[k].toString().trim() + } + } } - if (options && options.trimWhitespace === false) { - return val; + return this.formatted + } + + format () { + return this.range + } + + toString () { + return this.range + } + + parseRange (range) { + // memoize range parsing for performance. + // this is a very hot path, and fully deterministic. + const memoOpts = + (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | + (this.options.loose && FLAG_LOOSE) + const memoKey = memoOpts + ':' + range + const cached = cache.get(memoKey) + if (cached) { + return cached } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; + + const loose = this.options.loose + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] + range = range.replace(hr, hyphenReplace(this.options.includePrerelease)) + debug('hyphen replace', range) + + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + debug('tilde trim', range) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[t.CARETTRIM], caretTrimReplace) + debug('caret trim', range) + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + let rangeList = range + .split(' ') + .map(comp => parseComparator(comp, this.options)) + .join(' ') + .split(/\s+/) + // >=0.0.0 is equivalent to * + .map(comp => replaceGTE0(comp, this.options)) + + if (loose) { + // in loose mode, throw out any that are not valid comparators + rangeList = rangeList.filter(comp => { + debug('loose invalid filter', comp, this.options) + return !!comp.match(re[t.COMPARATORLOOSE]) + }) } - return inputs.map(input => input.trim()); -} -exports.getMultilineInput = getMultilineInput; -/** - * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. - * Support boolean input list: `true | True | TRUE | false | False | FALSE` . - * The return value is also in boolean type. - * ref: https://yaml.org/spec/1.2/spec.html#id2804923 - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns boolean - */ -function getBooleanInput(name, options) { - const trueValue = ['true', 'True', 'TRUE']; - const falseValue = ['false', 'False', 'FALSE']; - const val = getInput(name, options); - if (trueValue.includes(val)) - return true; - if (falseValue.includes(val)) - return false; - throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + - `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); -} -exports.getBooleanInput = getBooleanInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function setOutput(name, value) { - const filePath = process.env['GITHUB_OUTPUT'] || ''; - if (filePath) { - return (0, file_command_1.issueFileCommand)('OUTPUT', (0, file_command_1.prepareKeyValueMessage)(name, value)); + debug('range list', rangeList) + + // if any comparators are the null set, then replace with JUST null set + // if more than one comparator, remove any * comparators + // also, don't include the same comparator more than once + const rangeMap = new Map() + const comparators = rangeList.map(comp => new Comparator(comp, this.options)) + for (const comp of comparators) { + if (isNullSet(comp)) { + return [comp] + } + rangeMap.set(comp.value, comp) } - process.stdout.write(os.EOL); - (0, command_1.issueCommand)('set-output', { name }, (0, utils_1.toCommandValue)(value)); -} -exports.setOutput = setOutput; -/** - * Enables or disables the echoing of commands into stdout for the rest of the step. - * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. - * - */ -function setCommandEcho(enabled) { - (0, command_1.issue)('echo', enabled ? 'on' : 'off'); -} -exports.setCommandEcho = setCommandEcho; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - (0, command_1.issueCommand)('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function error(message, properties = {}) { - (0, command_1.issueCommand)('error', (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); -} -exports.error = error; -/** - * Adds a warning issue - * @param message warning issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function warning(message, properties = {}) { - (0, command_1.issueCommand)('warning', (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); -} -exports.warning = warning; -/** - * Adds a notice issue - * @param message notice issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function notice(message, properties = {}) { - (0, command_1.issueCommand)('notice', (0, utils_1.toCommandProperties)(properties), message instanceof Error ? message.toString() : message); -} -exports.notice = notice; -/** - * Writes info to log with console.log. - * @param message info message - */ -function info(message) { - process.stdout.write(message + os.EOL); -} -exports.info = info; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -function startGroup(name) { - (0, command_1.issue)('group', name); -} -exports.startGroup = startGroup; -/** - * End an output group. - */ -function endGroup() { - (0, command_1.issue)('endgroup'); -} -exports.endGroup = endGroup; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } - finally { - endGroup(); - } - return result; - }); -} -exports.group = group; -//----------------------------------------------------------------------- -// Wrapper action state -//----------------------------------------------------------------------- -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function saveState(name, value) { - const filePath = process.env['GITHUB_STATE'] || ''; - if (filePath) { - return (0, file_command_1.issueFileCommand)('STATE', (0, file_command_1.prepareKeyValueMessage)(name, value)); + if (rangeMap.size > 1 && rangeMap.has('')) { + rangeMap.delete('') } - (0, command_1.issueCommand)('save-state', { name }, (0, utils_1.toCommandValue)(value)); -} -exports.saveState = saveState; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -function getState(name) { - return process.env[`STATE_${name}`] || ''; -} -exports.getState = getState; -function getIDToken(aud) { - return __awaiter(this, void 0, void 0, function* () { - return yield oidc_utils_1.OidcClient.getIDToken(aud); - }); -} -exports.getIDToken = getIDToken; -/** - * Summary exports - */ -var summary_1 = __nccwpck_require__(1847); -Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); -/** - * @deprecated use core.summary - */ -var summary_2 = __nccwpck_require__(1847); -Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); -/** - * Path exports - */ -var path_utils_1 = __nccwpck_require__(1976); -Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); -Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); -Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); -/** - * Platform utilities exports - */ -exports.platform = __importStar(__nccwpck_require__(8968)); -//# sourceMappingURL=core.js.map -/***/ }), + const result = [...rangeMap.values()] + cache.set(memoKey, result) + return result + } -/***/ 4753: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + intersects (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } -"use strict"; + return this.set.some((thisComparators) => { + return ( + isSatisfiable(thisComparators, options) && + range.set.some((rangeComparators) => { + return ( + isSatisfiable(rangeComparators, options) && + thisComparators.every((thisComparator) => { + return rangeComparators.every((rangeComparator) => { + return thisComparator.intersects(rangeComparator, options) + }) + }) + ) + }) + ) + }) + } -// For internal use, subject to change. -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -const crypto = __importStar(__nccwpck_require__(6982)); -const fs = __importStar(__nccwpck_require__(9896)); -const os = __importStar(__nccwpck_require__(857)); -const utils_1 = __nccwpck_require__(302); -function issueFileCommand(command, message) { - const filePath = process.env[`GITHUB_${command}`]; - if (!filePath) { - throw new Error(`Unable to find environment variable for file command ${command}`); - } - if (!fs.existsSync(filePath)) { - throw new Error(`Missing file at path: ${filePath}`); + // if ANY of the sets match ALL of its comparators, then pass + test (version) { + if (!version) { + return false } - fs.appendFileSync(filePath, `${(0, utils_1.toCommandValue)(message)}${os.EOL}`, { - encoding: 'utf8' - }); -} -exports.issueFileCommand = issueFileCommand; -function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto.randomUUID()}`; - const convertedValue = (0, utils_1.toCommandValue)(value); - // These should realistically never happen, but just in case someone finds a - // way to exploit uuid generation let's not allow keys or values that contain - // the delimiter. - if (key.includes(delimiter)) { - throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } } - if (convertedValue.includes(delimiter)) { - throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + + for (let i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } } - return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; + return false + } } -exports.prepareKeyValueMessage = prepareKeyValueMessage; -//# sourceMappingURL=file-command.js.map -/***/ }), +module.exports = Range -/***/ 5306: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +const LRU = __nccwpck_require__(1383) +const cache = new LRU() -"use strict"; +const parseOptions = __nccwpck_require__(356) +const Comparator = __nccwpck_require__(9379) +const debug = __nccwpck_require__(1159) +const SemVer = __nccwpck_require__(7163) +const { + safeRe: re, + t, + comparatorTrimReplace, + tildeTrimReplace, + caretTrimReplace, +} = __nccwpck_require__(5471) +const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = __nccwpck_require__(5101) -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.OidcClient = void 0; -const http_client_1 = __nccwpck_require__(4844); -const auth_1 = __nccwpck_require__(4552); -const core_1 = __nccwpck_require__(7484); -class OidcClient { - static createHttpClient(allowRetry = true, maxRetry = 10) { - const requestOptions = { - allowRetries: allowRetry, - maxRetries: maxRetry - }; - return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); - } - static getRequestToken() { - const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; - if (!token) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); - } - return token; - } - static getIDTokenUrl() { - const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; - if (!runtimeUrl) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); - } - return runtimeUrl; - } - static getCall(id_token_url) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const httpclient = OidcClient.createHttpClient(); - const res = yield httpclient - .getJson(id_token_url) - .catch(error => { - throw new Error(`Failed to get ID Token. \n - Error Code : ${error.statusCode}\n - Error Message: ${error.message}`); - }); - const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; - if (!id_token) { - throw new Error('Response json body do not have ID Token field'); - } - return id_token; - }); - } - static getIDToken(audience) { - return __awaiter(this, void 0, void 0, function* () { - try { - // New ID Token is requested from action service - let id_token_url = OidcClient.getIDTokenUrl(); - if (audience) { - const encodedAudience = encodeURIComponent(audience); - id_token_url = `${id_token_url}&audience=${encodedAudience}`; - } - (0, core_1.debug)(`ID token url is ${id_token_url}`); - const id_token = yield OidcClient.getCall(id_token_url); - (0, core_1.setSecret)(id_token); - return id_token; - } - catch (error) { - throw new Error(`Error message: ${error.message}`); - } - }); - } -} -exports.OidcClient = OidcClient; -//# sourceMappingURL=oidc-utils.js.map +const isNullSet = c => c.value === '<0.0.0-0' +const isAny = c => c.value === '' -/***/ }), +// take a set of comparators and determine whether there +// exists a version which can satisfy it +const isSatisfiable = (comparators, options) => { + let result = true + const remainingComparators = comparators.slice() + let testComparator = remainingComparators.pop() -/***/ 1976: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + while (result && remainingComparators.length) { + result = remainingComparators.every((otherComparator) => { + return testComparator.intersects(otherComparator, options) + }) -"use strict"; + testComparator = remainingComparators.pop() + } -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; -const path = __importStar(__nccwpck_require__(6928)); -/** - * toPosixPath converts the given path to the posix form. On Windows, \\ will be - * replaced with /. - * - * @param pth. Path to transform. - * @return string Posix path. - */ -function toPosixPath(pth) { - return pth.replace(/[\\]/g, '/'); -} -exports.toPosixPath = toPosixPath; -/** - * toWin32Path converts the given path to the win32 form. On Linux, / will be - * replaced with \\. - * - * @param pth. Path to transform. - * @return string Win32 path. - */ -function toWin32Path(pth) { - return pth.replace(/[/]/g, '\\'); + return result } -exports.toWin32Path = toWin32Path; -/** - * toPlatformPath converts the given path to a platform-specific path. It does - * this by replacing instances of / and \ with the platform-specific path - * separator. - * - * @param pth The path to platformize. - * @return string The platform-specific path. - */ -function toPlatformPath(pth) { - return pth.replace(/[/\\]/g, path.sep); + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +const parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], '') + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp } -exports.toPlatformPath = toPlatformPath; -//# sourceMappingURL=path-utils.js.map -/***/ }), +const isX = id => !id || id.toLowerCase() === 'x' || id === '*' -/***/ 8968: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 +// ~0.0.1 --> >=0.0.1 <0.1.0-0 +const replaceTildes = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceTilde(c, options)) + .join(' ') +} -"use strict"; +const replaceTilde = (comp, options) => { + const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + return comp.replace(r, (_, M, m, p, pr) => { + debug('tilde', comp, _, M, m, p, pr) + let ret -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getDetails = exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0; -const os_1 = __importDefault(__nccwpck_require__(857)); -const exec = __importStar(__nccwpck_require__(5236)); -const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () { - const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, { - silent: true - }); - const { stdout: name } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"', undefined, { - silent: true - }); - return { - name: name.trim(), - version: version.trim() - }; -}); -const getMacOsInfo = () => __awaiter(void 0, void 0, void 0, function* () { - var _a, _b, _c, _d; - const { stdout } = yield exec.getExecOutput('sw_vers', undefined, { - silent: true - }); - const version = (_b = (_a = stdout.match(/ProductVersion:\s*(.+)/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : ''; - const name = (_d = (_c = stdout.match(/ProductName:\s*(.+)/)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : ''; - return { - name, - version - }; -}); -const getLinuxInfo = () => __awaiter(void 0, void 0, void 0, function* () { - const { stdout } = yield exec.getExecOutput('lsb_release', ['-i', '-r', '-s'], { - silent: true - }); - const [name, version] = stdout.trim().split('\n'); - return { - name, - version - }; -}); -exports.platform = os_1.default.platform(); -exports.arch = os_1.default.arch(); -exports.isWindows = exports.platform === 'win32'; -exports.isMacOS = exports.platform === 'darwin'; -exports.isLinux = exports.platform === 'linux'; -function getDetails() { - return __awaiter(this, void 0, void 0, function* () { - return Object.assign(Object.assign({}, (yield (exports.isWindows - ? getWindowsInfo() - : exports.isMacOS - ? getMacOsInfo() - : getLinuxInfo()))), { platform: exports.platform, - arch: exports.arch, - isWindows: exports.isWindows, - isMacOS: exports.isMacOS, - isLinux: exports.isLinux }); - }); -} -exports.getDetails = getDetails; -//# sourceMappingURL=platform.js.map + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = `>=${M}.0.0 <${+M + 1}.0.0-0` + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0-0 + ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0` + } else if (pr) { + debug('replaceTilde pr', pr) + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0` + } else { + // ~1.2.3 == >=1.2.3 <1.3.0-0 + ret = `>=${M}.${m}.${p + } <${M}.${+m + 1}.0-0` + } -/***/ }), + debug('tilde return', ret) + return ret + }) +} -/***/ 1847: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 +// ^1.2.3 --> >=1.2.3 <2.0.0-0 +// ^1.2.0 --> >=1.2.0 <2.0.0-0 +// ^0.0.1 --> >=0.0.1 <0.0.2-0 +// ^0.1.0 --> >=0.1.0 <0.2.0-0 +const replaceCarets = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceCaret(c, options)) + .join(' ') +} -"use strict"; +const replaceCaret = (comp, options) => { + debug('caret', comp, options) + const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] + const z = options.includePrerelease ? '-0' : '' + return comp.replace(r, (_, M, m, p, pr) => { + debug('caret', comp, _, M, m, p, pr) + let ret -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; -const os_1 = __nccwpck_require__(857); -const fs_1 = __nccwpck_require__(9896); -const { access, appendFile, writeFile } = fs_1.promises; -exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; -exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; -class Summary { - constructor() { - this._buffer = ''; - } - /** - * Finds the summary file path from the environment, rejects if env var is not found or file does not exist - * Also checks r/w permissions. - * - * @returns step summary file path - */ - filePath() { - return __awaiter(this, void 0, void 0, function* () { - if (this._filePath) { - return this._filePath; - } - const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; - if (!pathFromEnv) { - throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); - } - try { - yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); - } - catch (_a) { - throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); - } - this._filePath = pathFromEnv; - return this._filePath; - }); - } - /** - * Wraps content in an HTML tag, adding any HTML attributes - * - * @param {string} tag HTML tag to wrap - * @param {string | null} content content within the tag - * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add - * - * @returns {string} content wrapped in HTML element - */ - wrap(tag, content, attrs = {}) { - const htmlAttrs = Object.entries(attrs) - .map(([key, value]) => ` ${key}="${value}"`) - .join(''); - if (!content) { - return `<${tag}${htmlAttrs}>`; + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0` + } else if (isX(p)) { + if (M === '0') { + ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0` + } else { + ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0` + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${m}.${+p + 1}-0` + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0` } - return `<${tag}${htmlAttrs}>${content}`; + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${+M + 1}.0.0-0` + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p + }${z} <${M}.${m}.${+p + 1}-0` + } else { + ret = `>=${M}.${m}.${p + }${z} <${M}.${+m + 1}.0-0` + } + } else { + ret = `>=${M}.${m}.${p + } <${+M + 1}.0.0-0` + } } - /** - * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. - * - * @param {SummaryWriteOptions} [options] (optional) options for write operation - * - * @returns {Promise} summary instance - */ - write(options) { - return __awaiter(this, void 0, void 0, function* () { - const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); - const filePath = yield this.filePath(); - const writeFunc = overwrite ? writeFile : appendFile; - yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); - return this.emptyBuffer(); - }); + + debug('caret return', ret) + return ret + }) +} + +const replaceXRanges = (comp, options) => { + debug('replaceXRanges', comp, options) + return comp + .split(/\s+/) + .map((c) => replaceXRange(c, options)) + .join(' ') +} + +const replaceXRange = (comp, options) => { + comp = comp.trim() + const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] + return comp.replace(r, (ret, gtlt, M, m, p, pr) => { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + const xM = isX(M) + const xm = xM || isX(m) + const xp = xm || isX(p) + const anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' } - /** - * Clears the summary buffer and wipes the summary file - * - * @returns {Summary} summary instance - */ - clear() { - return __awaiter(this, void 0, void 0, function* () { - return this.emptyBuffer().write({ overwrite: true }); - }); + + // if we're including prereleases in the match, then we need + // to fix this to -0, the lowest possible prerelease value + pr = options.includePrerelease ? '-0' : '' + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0-0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + if (gtlt === '<') { + pr = '-0' + } + + ret = `${gtlt + M}.${m}.${p}${pr}` + } else if (xm) { + ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0` + } else if (xp) { + ret = `>=${M}.${m}.0${pr + } <${M}.${+m + 1}.0-0` } - /** - * Returns the current summary buffer as a string - * - * @returns {string} string of summary buffer - */ - stringify() { - return this._buffer; + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +const replaceStars = (comp, options) => { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp + .trim() + .replace(re[t.STAR], '') +} + +const replaceGTE0 = (comp, options) => { + debug('replaceGTE0', comp, options) + return comp + .trim() + .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') +} + +// This function is passed to string.replace(re[t.HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0-0 +// TODO build? +const hyphenReplace = incPr => ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr) => { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = `>=${fM}.0.0${incPr ? '-0' : ''}` + } else if (isX(fp)) { + from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}` + } else if (fpr) { + from = `>=${from}` + } else { + from = `>=${from}${incPr ? '-0' : ''}` + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = `<${+tM + 1}.0.0-0` + } else if (isX(tp)) { + to = `<${tM}.${+tm + 1}.0-0` + } else if (tpr) { + to = `<=${tM}.${tm}.${tp}-${tpr}` + } else if (incPr) { + to = `<${tM}.${tm}.${+tp + 1}-0` + } else { + to = `<=${to}` + } + + return `${from} ${to}`.trim() +} + +const testSet = (set, version, options) => { + for (let i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false } - /** - * If the summary buffer is empty - * - * @returns {boolen} true if the buffer is empty - */ - isEmptyBuffer() { - return this._buffer.length === 0; + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (let i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === Comparator.ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + const allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } } - /** - * Resets the summary buffer without writing to summary file - * - * @returns {Summary} summary instance - */ - emptyBuffer() { - this._buffer = ''; - return this; + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} + + +/***/ }), + +/***/ 7163: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const debug = __nccwpck_require__(1159) +const { MAX_LENGTH, MAX_SAFE_INTEGER } = __nccwpck_require__(5101) +const { safeRe: re, t } = __nccwpck_require__(5471) + +const parseOptions = __nccwpck_require__(356) +const { compareIdentifiers } = __nccwpck_require__(3348) +class SemVer { + constructor (version, options) { + options = parseOptions(options) + + if (version instanceof SemVer) { + if (version.loose === !!options.loose && + version.includePrerelease === !!options.includePrerelease) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) } - /** - * Adds raw text to the summary buffer - * - * @param {string} text content to add - * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) - * - * @returns {Summary} summary instance - */ - addRaw(text, addEOL = false) { - this._buffer += text; - return addEOL ? this.addEOL() : this; + + if (version.length > MAX_LENGTH) { + throw new TypeError( + `version is longer than ${MAX_LENGTH} characters` + ) } - /** - * Adds the operating system-specific end-of-line marker to the buffer - * - * @returns {Summary} summary instance - */ - addEOL() { - return this.addRaw(os_1.EOL); + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + // this isn't actually relevant for versions, but keep it so that we + // don't run into trouble passing this.options around. + this.includePrerelease = !!options.includePrerelease + + const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) + + if (!m) { + throw new TypeError(`Invalid Version: ${version}`) } - /** - * Adds an HTML codeblock to the summary buffer - * - * @param {string} code content to render within fenced code block - * @param {string} lang (optional) language to syntax highlight code - * - * @returns {Summary} summary instance - */ - addCodeBlock(code, lang) { - const attrs = Object.assign({}, (lang && { lang })); - const element = this.wrap('pre', this.wrap('code', code), attrs); - return this.addRaw(element).addEOL(); + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') } - /** - * Adds an HTML list to the summary buffer - * - * @param {string[]} items list of items to render - * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) - * - * @returns {Summary} summary instance - */ - addList(items, ordered = false) { - const tag = ordered ? 'ol' : 'ul'; - const listItems = items.map(item => this.wrap('li', item)).join(''); - const element = this.wrap(tag, listItems); - return this.addRaw(element).addEOL(); + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') } - /** - * Adds an HTML table to the summary buffer - * - * @param {SummaryTableCell[]} rows table rows - * - * @returns {Summary} summary instance - */ - addTable(rows) { - const tableBody = rows - .map(row => { - const cells = row - .map(cell => { - if (typeof cell === 'string') { - return this.wrap('td', cell); - } - const { header, data, colspan, rowspan } = cell; - const tag = header ? 'th' : 'td'; - const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); - return this.wrap(tag, data, attrs); - }) - .join(''); - return this.wrap('tr', cells); - }) - .join(''); - const element = this.wrap('table', tableBody); - return this.addRaw(element).addEOL(); + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') } - /** - * Adds a collapsable HTML details element to the summary buffer - * - * @param {string} label text for the closed state - * @param {string} content collapsable content - * - * @returns {Summary} summary instance - */ - addDetails(label, content) { - const element = this.wrap('details', this.wrap('summary', label) + content); - return this.addRaw(element).addEOL(); + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map((id) => { + if (/^[0-9]+$/.test(id)) { + const num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) } - /** - * Adds an HTML image tag to the summary buffer - * - * @param {string} src path to the image you to embed - * @param {string} alt text description of the image - * @param {SummaryImageOptions} options (optional) addition image attributes - * - * @returns {Summary} summary instance - */ - addImage(src, alt, options) { - const { width, height } = options || {}; - const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); - const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); - return this.addRaw(element).addEOL(); + + this.build = m[5] ? m[5].split('.') : [] + this.format() + } + + format () { + this.version = `${this.major}.${this.minor}.${this.patch}` + if (this.prerelease.length) { + this.version += `-${this.prerelease.join('.')}` } - /** - * Adds an HTML section heading element - * - * @param {string} text heading text - * @param {number | string} [level=1] (optional) the heading level, default: 1 - * - * @returns {Summary} summary instance - */ - addHeading(text, level) { - const tag = `h${level}`; - const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) - ? tag - : 'h1'; - const element = this.wrap(allowedTag, text); - return this.addRaw(element).addEOL(); + return this.version + } + + toString () { + return this.version + } + + compare (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + if (typeof other === 'string' && other === this.version) { + return 0 + } + other = new SemVer(other, this.options) } - /** - * Adds an HTML thematic break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addSeparator() { - const element = this.wrap('hr', null); - return this.addRaw(element).addEOL(); + + if (other.version === this.version) { + return 0 } - /** - * Adds an HTML line break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addBreak() { - const element = this.wrap('br', null); - return this.addRaw(element).addEOL(); + + return this.compareMain(other) || this.comparePre(other) + } + + compareMain (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) } - /** - * Adds an HTML blockquote to the summary buffer - * - * @param {string} text quote text - * @param {string} cite (optional) citation url - * - * @returns {Summary} summary instance - */ - addQuote(text, cite) { - const attrs = Object.assign({}, (cite && { cite })); - const element = this.wrap('blockquote', text, attrs); - return this.addRaw(element).addEOL(); + + if (this.major < other.major) { + return -1 } - /** - * Adds an HTML anchor tag to the summary buffer - * - * @param {string} text link text/content - * @param {string} href hyperlink - * - * @returns {Summary} summary instance - */ - addLink(text, href) { - const element = this.wrap('a', text, { href }); - return this.addRaw(element).addEOL(); + if (this.major > other.major) { + return 1 } -} -const _summary = new Summary(); -/** - * @deprecated use `core.summary` - */ -exports.markdownSummary = _summary; -exports.summary = _summary; -//# sourceMappingURL=summary.js.map + if (this.minor < other.minor) { + return -1 + } + if (this.minor > other.minor) { + return 1 + } + if (this.patch < other.patch) { + return -1 + } + if (this.patch > other.patch) { + return 1 + } + return 0 + } -/***/ }), + comparePre (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } -/***/ 302: -/***/ ((__unused_webpack_module, exports) => { + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } -"use strict"; + let i = 0 + do { + const a = this.prerelease[i] + const b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toCommandProperties = exports.toCommandValue = void 0; -/** - * Sanitizes an input into a string so it can be passed into issueCommand safely - * @param input input to sanitize into a string - */ -function toCommandValue(input) { - if (input === null || input === undefined) { - return ''; - } - else if (typeof input === 'string' || input instanceof String) { - return input; - } - return JSON.stringify(input); -} -exports.toCommandValue = toCommandValue; -/** - * - * @param annotationProperties - * @returns The command properties to send with the actual annotation command - * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 - */ -function toCommandProperties(annotationProperties) { - if (!Object.keys(annotationProperties).length) { - return {}; + compareBuild (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) } - return { - title: annotationProperties.title, - file: annotationProperties.file, - line: annotationProperties.startLine, - endLine: annotationProperties.endLine, - col: annotationProperties.startColumn, - endColumn: annotationProperties.endColumn - }; -} -exports.toCommandProperties = toCommandProperties; -//# sourceMappingURL=utils.js.map -/***/ }), + let i = 0 + do { + const a = this.build[i] + const b = other.build[i] + debug('build compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } -/***/ 5236: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + // preminor will bump the version up to the next minor release, and immediately + // down to pre-release. premajor and prepatch work the same way. + inc (release, identifier, identifierBase) { + if (release.startsWith('pre')) { + if (!identifier && identifierBase === false) { + throw new Error('invalid increment argument: identifier is empty') + } + // Avoid an invalid semver results + if (identifier) { + const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE]) + if (!match || match[1] !== identifier) { + throw new Error(`invalid identifier: ${identifier}`) + } + } + } -"use strict"; + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier, identifierBase) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier, identifierBase) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier, identifierBase) + this.inc('pre', identifier, identifierBase) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier, identifierBase) + } + this.inc('pre', identifier, identifierBase) + break + case 'release': + if (this.prerelease.length === 0) { + throw new Error(`version ${this.raw} is not a prerelease`) + } + this.prerelease.length = 0 + break -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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getExecOutput = exports.exec = void 0; -const string_decoder_1 = __nccwpck_require__(3193); -const tr = __importStar(__nccwpck_require__(6665)); -/** - * Exec a command. - * Output will be streamed to the live console. - * Returns promise with return code - * - * @param commandLine command to execute (can include additional args). Must be correctly escaped. - * @param args optional arguments for tool. Escaping is handled by the lib. - * @param options optional exec options. See ExecOptions - * @returns Promise exit code - */ -function exec(commandLine, args, options) { - return __awaiter(this, void 0, void 0, function* () { - const commandArgs = tr.argStringToArray(commandLine); - if (commandArgs.length === 0) { - throw new Error(`Parameter 'commandLine' cannot be null or empty.`); + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if ( + this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0 + ) { + this.major++ } - // Path to tool to execute should be first arg - const toolPath = commandArgs[0]; - args = commandArgs.slice(1).concat(args || []); - const runner = new tr.ToolRunner(toolPath, args, options); - return runner.exec(); - }); -} -exports.exec = exec; -/** - * Exec a command and get the output. - * Output will be streamed to the live console. - * Returns promise with the exit code and collected stdout and stderr - * - * @param commandLine command to execute (can include additional args). Must be correctly escaped. - * @param args optional arguments for tool. Escaping is handled by the lib. - * @param options optional exec options. See ExecOptions - * @returns Promise exit code, stdout, and stderr - */ -function getExecOutput(commandLine, args, options) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - let stdout = ''; - let stderr = ''; - //Using string decoder covers the case where a mult-byte character is split - const stdoutDecoder = new string_decoder_1.StringDecoder('utf8'); - const stderrDecoder = new string_decoder_1.StringDecoder('utf8'); - const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout; - const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr; - const stdErrListener = (data) => { - stderr += stderrDecoder.write(data); - if (originalStdErrListener) { - originalStdErrListener(data); + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. + case 'pre': { + const base = Number(identifierBase) ? 1 : 0 + + if (this.prerelease.length === 0) { + this.prerelease = [base] + } else { + let i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 } - }; - const stdOutListener = (data) => { - stdout += stdoutDecoder.write(data); - if (originalStdoutListener) { - originalStdoutListener(data); + } + if (i === -1) { + // didn't increment anything + if (identifier === this.prerelease.join('.') && identifierBase === false) { + throw new Error('invalid increment argument: identifier already exists') } - }; - const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener }); - const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners })); - //flush any remaining characters - stdout += stdoutDecoder.end(); - stderr += stderrDecoder.end(); - return { - exitCode, - stdout, - stderr - }; - }); + this.prerelease.push(base) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + let prerelease = [identifier, base] + if (identifierBase === false) { + prerelease = [identifier] + } + if (compareIdentifiers(this.prerelease[0], identifier) === 0) { + if (isNaN(this.prerelease[1])) { + this.prerelease = prerelease + } + } else { + this.prerelease = prerelease + } + } + break + } + default: + throw new Error(`invalid increment argument: ${release}`) + } + this.raw = this.format() + if (this.build.length) { + this.raw += `+${this.build.join('.')}` + } + return this + } } -exports.getExecOutput = getExecOutput; -//# sourceMappingURL=exec.js.map + +module.exports = SemVer + /***/ }), -/***/ 6665: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 1799: +/***/ ((module, __unused_webpack_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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.argStringToArray = exports.ToolRunner = void 0; -const os = __importStar(__nccwpck_require__(857)); -const events = __importStar(__nccwpck_require__(4434)); -const child = __importStar(__nccwpck_require__(5317)); -const path = __importStar(__nccwpck_require__(6928)); -const io = __importStar(__nccwpck_require__(4994)); -const ioUtil = __importStar(__nccwpck_require__(5207)); -const timers_1 = __nccwpck_require__(3557); -/* eslint-disable @typescript-eslint/unbound-method */ -const IS_WINDOWS = process.platform === 'win32'; -/* - * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. - */ -class ToolRunner extends events.EventEmitter { - constructor(toolPath, args, options) { - super(); - if (!toolPath) { - throw new Error("Parameter 'toolPath' cannot be null or empty."); - } - this.toolPath = toolPath; - this.args = args || []; - this.options = options || {}; - } - _debug(message) { - if (this.options.listeners && this.options.listeners.debug) { - this.options.listeners.debug(message); - } - } - _getCommandString(options, noPrefix) { - const toolPath = this._getSpawnFileName(); - const args = this._getSpawnArgs(options); - let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool - if (IS_WINDOWS) { - // Windows + cmd file - if (this._isCmdFile()) { - cmd += toolPath; - for (const a of args) { - cmd += ` ${a}`; - } - } - // Windows + verbatim - else if (options.windowsVerbatimArguments) { - cmd += `"${toolPath}"`; - for (const a of args) { - cmd += ` ${a}`; - } - } - // Windows (regular) - else { - cmd += this._windowsQuoteCmdArg(toolPath); - for (const a of args) { - cmd += ` ${this._windowsQuoteCmdArg(a)}`; - } - } - } - else { - // OSX/Linux - this can likely be improved with some form of quoting. - // creating processes on Unix is fundamentally different than Windows. - // on Unix, execvp() takes an arg array. - cmd += toolPath; - for (const a of args) { - cmd += ` ${a}`; - } - } - return cmd; - } - _processLineBuffer(data, strBuffer, onLine) { - try { - let s = strBuffer + data.toString(); - let n = s.indexOf(os.EOL); - while (n > -1) { - const line = s.substring(0, n); - onLine(line); - // the rest of the string ... - s = s.substring(n + os.EOL.length); - n = s.indexOf(os.EOL); - } - return s; - } - catch (err) { - // streaming lines to console is best effort. Don't fail a build. - this._debug(`error processing line. Failed with error ${err}`); - return ''; - } - } - _getSpawnFileName() { - if (IS_WINDOWS) { - if (this._isCmdFile()) { - return process.env['COMSPEC'] || 'cmd.exe'; - } - } - return this.toolPath; - } - _getSpawnArgs(options) { - if (IS_WINDOWS) { - if (this._isCmdFile()) { - let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; - for (const a of this.args) { - argline += ' '; - argline += options.windowsVerbatimArguments - ? a - : this._windowsQuoteCmdArg(a); - } - argline += '"'; - return [argline]; - } - } - return this.args; + +const parse = __nccwpck_require__(6353) +const clean = (version, options) => { + const s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} +module.exports = clean + + +/***/ }), + +/***/ 8646: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const eq = __nccwpck_require__(2701) +const neq = __nccwpck_require__(4974) +const gt = __nccwpck_require__(6599) +const gte = __nccwpck_require__(1236) +const lt = __nccwpck_require__(3872) +const lte = __nccwpck_require__(6717) + +const cmp = (a, op, b, loose) => { + switch (op) { + case '===': + if (typeof a === 'object') { + a = a.version + } + if (typeof b === 'object') { + b = b.version + } + return a === b + + case '!==': + if (typeof a === 'object') { + a = a.version + } + if (typeof b === 'object') { + b = b.version + } + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError(`Invalid operator: ${op}`) + } +} +module.exports = cmp + + +/***/ }), + +/***/ 5385: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const parse = __nccwpck_require__(6353) +const { safeRe: re, t } = __nccwpck_require__(5471) + +const coerce = (version, options) => { + if (version instanceof SemVer) { + return version + } + + if (typeof version === 'number') { + version = String(version) + } + + if (typeof version !== 'string') { + return null + } + + options = options || {} + + let match = null + if (!options.rtl) { + match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]) + } else { + // Find the right-most coercible string that does not share + // a terminus with a more left-ward coercible string. + // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4' + // + // Walk through the string checking with a /g regexp + // Manually set the index so as to pick up overlapping matches. + // Stop when we get a match that ends at the string end, since no + // coercible string can be more right-ward without the same terminus. + const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL] + let next + while ((next = coerceRtlRegex.exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next + } + coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length } - _endsWith(str, end) { - return str.endsWith(end); + // leave it in a clean state + coerceRtlRegex.lastIndex = -1 + } + + if (match === null) { + return null + } + + const major = match[2] + const minor = match[3] || '0' + const patch = match[4] || '0' + const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : '' + const build = options.includePrerelease && match[6] ? `+${match[6]}` : '' + + return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options) +} +module.exports = coerce + + +/***/ }), + +/***/ 7648: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const compareBuild = (a, b, loose) => { + const versionA = new SemVer(a, loose) + const versionB = new SemVer(b, loose) + return versionA.compare(versionB) || versionA.compareBuild(versionB) +} +module.exports = compareBuild + + +/***/ }), + +/***/ 6874: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const compareLoose = (a, b) => compare(a, b, true) +module.exports = compareLoose + + +/***/ }), + +/***/ 8469: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const compare = (a, b, loose) => + new SemVer(a, loose).compare(new SemVer(b, loose)) + +module.exports = compare + + +/***/ }), + +/***/ 711: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const parse = __nccwpck_require__(6353) + +const diff = (version1, version2) => { + const v1 = parse(version1, null, true) + const v2 = parse(version2, null, true) + const comparison = v1.compare(v2) + + if (comparison === 0) { + return null + } + + const v1Higher = comparison > 0 + const highVersion = v1Higher ? v1 : v2 + const lowVersion = v1Higher ? v2 : v1 + const highHasPre = !!highVersion.prerelease.length + const lowHasPre = !!lowVersion.prerelease.length + + if (lowHasPre && !highHasPre) { + // Going from prerelease -> no prerelease requires some special casing + + // If the low version has only a major, then it will always be a major + // Some examples: + // 1.0.0-1 -> 1.0.0 + // 1.0.0-1 -> 1.1.1 + // 1.0.0-1 -> 2.0.0 + if (!lowVersion.patch && !lowVersion.minor) { + return 'major' } - _isCmdFile() { - const upperToolPath = this.toolPath.toUpperCase(); - return (this._endsWith(upperToolPath, '.CMD') || - this._endsWith(upperToolPath, '.BAT')); + + // If the main part has no difference + if (lowVersion.compareMain(highVersion) === 0) { + if (lowVersion.minor && !lowVersion.patch) { + return 'minor' + } + return 'patch' } - _windowsQuoteCmdArg(arg) { - // for .exe, apply the normal quoting rules that libuv applies - if (!this._isCmdFile()) { - return this._uvQuoteCmdArg(arg); + } + + // add the `pre` prefix if we are going to a prerelease version + const prefix = highHasPre ? 'pre' : '' + + if (v1.major !== v2.major) { + return prefix + 'major' + } + + if (v1.minor !== v2.minor) { + return prefix + 'minor' + } + + if (v1.patch !== v2.patch) { + return prefix + 'patch' + } + + // high and low are prereleases + return 'prerelease' +} + +module.exports = diff + + +/***/ }), + +/***/ 2701: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const eq = (a, b, loose) => compare(a, b, loose) === 0 +module.exports = eq + + +/***/ }), + +/***/ 6599: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const gt = (a, b, loose) => compare(a, b, loose) > 0 +module.exports = gt + + +/***/ }), + +/***/ 1236: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const gte = (a, b, loose) => compare(a, b, loose) >= 0 +module.exports = gte + + +/***/ }), + +/***/ 2338: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) + +const inc = (version, release, options, identifier, identifierBase) => { + if (typeof (options) === 'string') { + identifierBase = identifier + identifier = options + options = undefined + } + + try { + return new SemVer( + version instanceof SemVer ? version.version : version, + options + ).inc(release, identifier, identifierBase).version + } catch (er) { + return null + } +} +module.exports = inc + + +/***/ }), + +/***/ 3872: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const lt = (a, b, loose) => compare(a, b, loose) < 0 +module.exports = lt + + +/***/ }), + +/***/ 6717: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const lte = (a, b, loose) => compare(a, b, loose) <= 0 +module.exports = lte + + +/***/ }), + +/***/ 8511: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const major = (a, loose) => new SemVer(a, loose).major +module.exports = major + + +/***/ }), + +/***/ 2603: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const minor = (a, loose) => new SemVer(a, loose).minor +module.exports = minor + + +/***/ }), + +/***/ 4974: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const neq = (a, b, loose) => compare(a, b, loose) !== 0 +module.exports = neq + + +/***/ }), + +/***/ 6353: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const parse = (version, options, throwErrors = false) => { + if (version instanceof SemVer) { + return version + } + try { + return new SemVer(version, options) + } catch (er) { + if (!throwErrors) { + return null + } + throw er + } +} + +module.exports = parse + + +/***/ }), + +/***/ 8756: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const patch = (a, loose) => new SemVer(a, loose).patch +module.exports = patch + + +/***/ }), + +/***/ 5714: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const parse = __nccwpck_require__(6353) +const prerelease = (version, options) => { + const parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} +module.exports = prerelease + + +/***/ }), + +/***/ 2173: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compare = __nccwpck_require__(8469) +const rcompare = (a, b, loose) => compare(b, a, loose) +module.exports = rcompare + + +/***/ }), + +/***/ 7192: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compareBuild = __nccwpck_require__(7648) +const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)) +module.exports = rsort + + +/***/ }), + +/***/ 8011: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Range = __nccwpck_require__(6782) +const satisfies = (version, range, options) => { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} +module.exports = satisfies + + +/***/ }), + +/***/ 9872: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const compareBuild = __nccwpck_require__(7648) +const sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose)) +module.exports = sort + + +/***/ }), + +/***/ 8780: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const parse = __nccwpck_require__(6353) +const valid = (version, options) => { + const v = parse(version, options) + return v ? v.version : null +} +module.exports = valid + + +/***/ }), + +/***/ 2088: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +// just pre-load all the stuff that index.js lazily exports +const internalRe = __nccwpck_require__(5471) +const constants = __nccwpck_require__(5101) +const SemVer = __nccwpck_require__(7163) +const identifiers = __nccwpck_require__(3348) +const parse = __nccwpck_require__(6353) +const valid = __nccwpck_require__(8780) +const clean = __nccwpck_require__(1799) +const inc = __nccwpck_require__(2338) +const diff = __nccwpck_require__(711) +const major = __nccwpck_require__(8511) +const minor = __nccwpck_require__(2603) +const patch = __nccwpck_require__(8756) +const prerelease = __nccwpck_require__(5714) +const compare = __nccwpck_require__(8469) +const rcompare = __nccwpck_require__(2173) +const compareLoose = __nccwpck_require__(6874) +const compareBuild = __nccwpck_require__(7648) +const sort = __nccwpck_require__(9872) +const rsort = __nccwpck_require__(7192) +const gt = __nccwpck_require__(6599) +const lt = __nccwpck_require__(3872) +const eq = __nccwpck_require__(2701) +const neq = __nccwpck_require__(4974) +const gte = __nccwpck_require__(1236) +const lte = __nccwpck_require__(6717) +const cmp = __nccwpck_require__(8646) +const coerce = __nccwpck_require__(5385) +const Comparator = __nccwpck_require__(9379) +const Range = __nccwpck_require__(6782) +const satisfies = __nccwpck_require__(8011) +const toComparators = __nccwpck_require__(4750) +const maxSatisfying = __nccwpck_require__(3193) +const minSatisfying = __nccwpck_require__(8595) +const minVersion = __nccwpck_require__(1866) +const validRange = __nccwpck_require__(4737) +const outside = __nccwpck_require__(280) +const gtr = __nccwpck_require__(2276) +const ltr = __nccwpck_require__(5213) +const intersects = __nccwpck_require__(3465) +const simplifyRange = __nccwpck_require__(2028) +const subset = __nccwpck_require__(1489) +module.exports = { + parse, + valid, + clean, + inc, + diff, + major, + minor, + patch, + prerelease, + compare, + rcompare, + compareLoose, + compareBuild, + sort, + rsort, + gt, + lt, + eq, + neq, + gte, + lte, + cmp, + coerce, + Comparator, + Range, + satisfies, + toComparators, + maxSatisfying, + minSatisfying, + minVersion, + validRange, + outside, + gtr, + ltr, + intersects, + simplifyRange, + subset, + SemVer, + re: internalRe.re, + src: internalRe.src, + tokens: internalRe.t, + SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, + compareIdentifiers: identifiers.compareIdentifiers, + rcompareIdentifiers: identifiers.rcompareIdentifiers, +} + + +/***/ }), + +/***/ 5101: +/***/ ((module) => { + +"use strict"; + + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +const SEMVER_SPEC_VERSION = '2.0.0' + +const MAX_LENGTH = 256 +const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || +/* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +const MAX_SAFE_COMPONENT_LENGTH = 16 + +// Max safe length for a build identifier. The max length minus 6 characters for +// the shortest version with a build 0.0.0+BUILD. +const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + +const RELEASE_TYPES = [ + 'major', + 'premajor', + 'minor', + 'preminor', + 'patch', + 'prepatch', + 'prerelease', +] + +module.exports = { + MAX_LENGTH, + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 0b001, + FLAG_LOOSE: 0b010, +} + + +/***/ }), + +/***/ 1159: +/***/ ((module) => { + +"use strict"; + + +const debug = ( + typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG) +) ? (...args) => console.error('SEMVER', ...args) + : () => {} + +module.exports = debug + + +/***/ }), + +/***/ 3348: +/***/ ((module) => { + +"use strict"; + + +const numeric = /^[0-9]+$/ +const compareIdentifiers = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') { + return a === b ? 0 : a < b ? -1 : 1 + } + + const anum = numeric.test(a) + const bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a) + +module.exports = { + compareIdentifiers, + rcompareIdentifiers, +} + + +/***/ }), + +/***/ 1383: +/***/ ((module) => { + +"use strict"; + + +class LRUCache { + constructor () { + this.max = 1000 + this.map = new Map() + } + + get (key) { + const value = this.map.get(key) + if (value === undefined) { + return undefined + } else { + // Remove the key from the map and add it to the end + this.map.delete(key) + this.map.set(key, value) + return value + } + } + + delete (key) { + return this.map.delete(key) + } + + set (key, value) { + const deleted = this.delete(key) + + if (!deleted && value !== undefined) { + // If cache is full, delete the least recently used item + if (this.map.size >= this.max) { + const firstKey = this.map.keys().next().value + this.delete(firstKey) + } + + this.map.set(key, value) + } + + return this + } +} + +module.exports = LRUCache + + +/***/ }), + +/***/ 356: +/***/ ((module) => { + +"use strict"; + + +// parse out just the options we care about +const looseOption = Object.freeze({ loose: true }) +const emptyOpts = Object.freeze({ }) +const parseOptions = options => { + if (!options) { + return emptyOpts + } + + if (typeof options !== 'object') { + return looseOption + } + + return options +} +module.exports = parseOptions + + +/***/ }), + +/***/ 5471: +/***/ ((module, exports, __nccwpck_require__) => { + +"use strict"; + + +const { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH, +} = __nccwpck_require__(5101) +const debug = __nccwpck_require__(1159) +exports = module.exports = {} + +// The actual regexps go on exports.re +const re = exports.re = [] +const safeRe = exports.safeRe = [] +const src = exports.src = [] +const safeSrc = exports.safeSrc = [] +const t = exports.t = {} +let R = 0 + +const LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`).join(`${token}{0,${max}}`) + .split(`${token}+`).join(`${token}{1,${max}}`) + } + return value +} + +const createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value) + const index = R++ + debug(name, index, value) + t[name] = index + src[index] = value + safeSrc[index] = safe + re[index] = new RegExp(value, isGlobal ? 'g' : undefined) + safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) +} + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') +createToken('NUMERICIDENTIFIERLOOSE', '\\d+') + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) + +// ## Main Version +// Three dot-separated numeric identifiers. + +createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})`) + +createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})`) + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. +// Non-numeric identifiers include numeric identifiers but can be longer. +// Therefore non-numeric identifiers must go first. + +createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIER]})`) + +createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIERLOOSE]})`) + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] +}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`) + +createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] +}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`) + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] +}(?:\\.${src[t.BUILDIDENTIFIER]})*))`) + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +createToken('FULLPLAIN', `v?${src[t.MAINVERSION] +}${src[t.PRERELEASE]}?${ + src[t.BUILD]}?`) + +createToken('FULL', `^${src[t.FULLPLAIN]}$`) + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] +}${src[t.PRERELEASELOOSE]}?${ + src[t.BUILD]}?`) + +createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`) + +createToken('GTLT', '((?:<|>)?=?)') + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`) +createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`) + +createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:${src[t.PRERELEASE]})?${ + src[t.BUILD]}?` + + `)?)?`) + +createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:${src[t.PRERELEASELOOSE]})?${ + src[t.BUILD]}?` + + `)?)?`) + +createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`) +createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +createToken('COERCEPLAIN', `${'(^|[^\\d])' + + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) +createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) +createToken('COERCEFULL', src[t.COERCEPLAIN] + + `(?:${src[t.PRERELEASE]})?` + + `(?:${src[t.BUILD]})?` + + `(?:$|[^\\d])`) +createToken('COERCERTL', src[t.COERCE], true) +createToken('COERCERTLFULL', src[t.COERCEFULL], true) + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +createToken('LONETILDE', '(?:~>?)') + +createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true) +exports.tildeTrimReplace = '$1~' + +createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`) +createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`) + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +createToken('LONECARET', '(?:\\^)') + +createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true) +exports.caretTrimReplace = '$1^' + +createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`) +createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`) + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`) +createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`) + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] +}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true) +exports.comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAIN]})` + + `\\s*$`) + +createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAINLOOSE]})` + + `\\s*$`) + +// Star ranges basically just allow anything at all. +createToken('STAR', '(<|>)?=?\\s*\\*') +// >=0.0.0 is like a star +createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$') +createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$') + + +/***/ }), + +/***/ 2276: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +// Determine if version is greater than all the versions possible in the range. +const outside = __nccwpck_require__(280) +const gtr = (version, range, options) => outside(version, range, '>', options) +module.exports = gtr + + +/***/ }), + +/***/ 3465: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Range = __nccwpck_require__(6782) +const intersects = (r1, r2, options) => { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2, options) +} +module.exports = intersects + + +/***/ }), + +/***/ 5213: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const outside = __nccwpck_require__(280) +// Determine if version is less than all the versions possible in the range +const ltr = (version, range, options) => outside(version, range, '<', options) +module.exports = ltr + + +/***/ }), + +/***/ 3193: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const Range = __nccwpck_require__(6782) + +const maxSatisfying = (versions, range, options) => { + let max = null + let maxSV = null + let rangeObj = null + try { + rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} +module.exports = maxSatisfying + + +/***/ }), + +/***/ 8595: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const Range = __nccwpck_require__(6782) +const minSatisfying = (versions, range, options) => { + let min = null + let minSV = null + let rangeObj = null + try { + rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} +module.exports = minSatisfying + + +/***/ }), + +/***/ 1866: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const Range = __nccwpck_require__(6782) +const gt = __nccwpck_require__(6599) + +const minVersion = (range, loose) => { + range = new Range(range, loose) + + let minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i] + + let setMin = null + comparators.forEach((comparator) => { + // Clone to avoid manipulating the comparator's semver object. + const compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!setMin || gt(compver, setMin)) { + setMin = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error(`Unexpected operation: ${comparator.operator}`) + } + }) + if (setMin && (!minver || gt(minver, setMin))) { + minver = setMin + } + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} +module.exports = minVersion + + +/***/ }), + +/***/ 280: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const SemVer = __nccwpck_require__(7163) +const Comparator = __nccwpck_require__(9379) +const { ANY } = Comparator +const Range = __nccwpck_require__(6782) +const satisfies = __nccwpck_require__(8011) +const gt = __nccwpck_require__(6599) +const lt = __nccwpck_require__(3872) +const lte = __nccwpck_require__(6717) +const gte = __nccwpck_require__(1236) + +const outside = (version, range, hilo, options) => { + version = new SemVer(version, options) + range = new Range(range, options) + + let gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisfies the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i] + + let high = null + let low = null + + comparators.forEach((comparator) => { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +module.exports = outside + + +/***/ }), + +/***/ 2028: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +// given a set of versions and a range, create a "simplified" range +// that includes the same versions that the original range does +// If the original range is shorter than the simplified one, return that. +const satisfies = __nccwpck_require__(8011) +const compare = __nccwpck_require__(8469) +module.exports = (versions, range, options) => { + const set = [] + let first = null + let prev = null + const v = versions.sort((a, b) => compare(a, b, options)) + for (const version of v) { + const included = satisfies(version, range, options) + if (included) { + prev = version + if (!first) { + first = version + } + } else { + if (prev) { + set.push([first, prev]) + } + prev = null + first = null + } + } + if (first) { + set.push([first, null]) + } + + const ranges = [] + for (const [min, max] of set) { + if (min === max) { + ranges.push(min) + } else if (!max && min === v[0]) { + ranges.push('*') + } else if (!max) { + ranges.push(`>=${min}`) + } else if (min === v[0]) { + ranges.push(`<=${max}`) + } else { + ranges.push(`${min} - ${max}`) + } + } + const simplified = ranges.join(' || ') + const original = typeof range.raw === 'string' ? range.raw : String(range) + return simplified.length < original.length ? simplified : range +} + + +/***/ }), + +/***/ 1489: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Range = __nccwpck_require__(6782) +const Comparator = __nccwpck_require__(9379) +const { ANY } = Comparator +const satisfies = __nccwpck_require__(8011) +const compare = __nccwpck_require__(8469) + +// Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: +// - Every simple range `r1, r2, ...` is a null set, OR +// - Every simple range `r1, r2, ...` which is not a null set is a subset of +// some `R1, R2, ...` +// +// Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: +// - If c is only the ANY comparator +// - If C is only the ANY comparator, return true +// - Else if in prerelease mode, return false +// - else replace c with `[>=0.0.0]` +// - If C is only the ANY comparator +// - if in prerelease mode, return true +// - else replace C with `[>=0.0.0]` +// - Let EQ be the set of = comparators in c +// - If EQ is more than one, return true (null set) +// - Let GT be the highest > or >= comparator in c +// - Let LT be the lowest < or <= comparator in c +// - If GT and LT, and GT.semver > LT.semver, return true (null set) +// - If any C is a = range, and GT or LT are set, return false +// - If EQ +// - If GT, and EQ does not satisfy GT, return true (null set) +// - If LT, and EQ does not satisfy LT, return true (null set) +// - If EQ satisfies every C, return true +// - Else return false +// - If GT +// - If GT.semver is lower than any > or >= comp in C, return false +// - If GT is >=, and GT.semver does not satisfy every C, return false +// - If GT.semver has a prerelease, and not in prerelease mode +// - If no C has a prerelease and the GT.semver tuple, return false +// - If LT +// - If LT.semver is greater than any < or <= comp in C, return false +// - If LT is <=, and LT.semver does not satisfy every C, return false +// - If LT.semver has a prerelease, and not in prerelease mode +// - If no C has a prerelease and the LT.semver tuple, return false +// - Else return true + +const subset = (sub, dom, options = {}) => { + if (sub === dom) { + return true + } + + sub = new Range(sub, options) + dom = new Range(dom, options) + let sawNonNull = false + + OUTER: for (const simpleSub of sub.set) { + for (const simpleDom of dom.set) { + const isSub = simpleSubset(simpleSub, simpleDom, options) + sawNonNull = sawNonNull || isSub !== null + if (isSub) { + continue OUTER + } + } + // the null set is a subset of everything, but null simple ranges in + // a complex range should be ignored. so if we saw a non-null range, + // then we know this isn't a subset, but if EVERY simple range was null, + // then it is a subset. + if (sawNonNull) { + return false + } + } + return true +} + +const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] +const minimumVersion = [new Comparator('>=0.0.0')] + +const simpleSubset = (sub, dom, options) => { + if (sub === dom) { + return true + } + + if (sub.length === 1 && sub[0].semver === ANY) { + if (dom.length === 1 && dom[0].semver === ANY) { + return true + } else if (options.includePrerelease) { + sub = minimumVersionWithPreRelease + } else { + sub = minimumVersion + } + } + + if (dom.length === 1 && dom[0].semver === ANY) { + if (options.includePrerelease) { + return true + } else { + dom = minimumVersion + } + } + + const eqSet = new Set() + let gt, lt + for (const c of sub) { + if (c.operator === '>' || c.operator === '>=') { + gt = higherGT(gt, c, options) + } else if (c.operator === '<' || c.operator === '<=') { + lt = lowerLT(lt, c, options) + } else { + eqSet.add(c.semver) + } + } + + if (eqSet.size > 1) { + return null + } + + let gtltComp + if (gt && lt) { + gtltComp = compare(gt.semver, lt.semver, options) + if (gtltComp > 0) { + return null + } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) { + return null + } + } + + // will iterate one or zero times + for (const eq of eqSet) { + if (gt && !satisfies(eq, String(gt), options)) { + return null + } + + if (lt && !satisfies(eq, String(lt), options)) { + return null + } + + for (const c of dom) { + if (!satisfies(eq, String(c), options)) { + return false + } + } + + return true + } + + let higher, lower + let hasDomLT, hasDomGT + // if the subset has a prerelease, we need a comparator in the superset + // with the same tuple and a prerelease, or it's not a subset + let needDomLTPre = lt && + !options.includePrerelease && + lt.semver.prerelease.length ? lt.semver : false + let needDomGTPre = gt && + !options.includePrerelease && + gt.semver.prerelease.length ? gt.semver : false + // exception: <1.2.3-0 is the same as <1.2.3 + if (needDomLTPre && needDomLTPre.prerelease.length === 1 && + lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { + needDomLTPre = false + } + + for (const c of dom) { + hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>=' + hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<=' + if (gt) { + if (needDomGTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomGTPre.major && + c.semver.minor === needDomGTPre.minor && + c.semver.patch === needDomGTPre.patch) { + needDomGTPre = false + } + } + if (c.operator === '>' || c.operator === '>=') { + higher = higherGT(gt, c, options) + if (higher === c && higher !== gt) { + return false + } + } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) { + return false + } + } + if (lt) { + if (needDomLTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomLTPre.major && + c.semver.minor === needDomLTPre.minor && + c.semver.patch === needDomLTPre.patch) { + needDomLTPre = false + } + } + if (c.operator === '<' || c.operator === '<=') { + lower = lowerLT(lt, c, options) + if (lower === c && lower !== lt) { + return false + } + } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) { + return false + } + } + if (!c.operator && (lt || gt) && gtltComp !== 0) { + return false + } + } + + // if there was a < or >, and nothing in the dom, then must be false + // UNLESS it was limited by another range in the other direction. + // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 + if (gt && hasDomLT && !lt && gtltComp !== 0) { + return false + } + + if (lt && hasDomGT && !gt && gtltComp !== 0) { + return false + } + + // we needed a prerelease range in a specific tuple, but didn't get one + // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, + // because it includes prereleases in the 1.2.3 tuple + if (needDomGTPre || needDomLTPre) { + return false + } + + return true +} + +// >=1.2.3 is lower than >1.2.3 +const higherGT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare(a.semver, b.semver, options) + return comp > 0 ? a + : comp < 0 ? b + : b.operator === '>' && a.operator === '>=' ? b + : a +} + +// <=1.2.3 is higher than <1.2.3 +const lowerLT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare(a.semver, b.semver, options) + return comp < 0 ? a + : comp > 0 ? b + : b.operator === '<' && a.operator === '<=' ? b + : a +} + +module.exports = subset + + +/***/ }), + +/***/ 4750: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Range = __nccwpck_require__(6782) + +// Mostly just for testing and legacy API reasons +const toComparators = (range, options) => + new Range(range, options).set + .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')) + +module.exports = toComparators + + +/***/ }), + +/***/ 4737: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Range = __nccwpck_require__(6782) +const validRange = (range, options) => { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} +module.exports = validRange + + +/***/ }), + +/***/ 770: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +/* unused reexport */ __nccwpck_require__(218); + + +/***/ }), + +/***/ 218: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; +var __webpack_unused_export__; + + +var net = __nccwpck_require__(9278); +var tls = __nccwpck_require__(4756); +var http = __nccwpck_require__(8611); +var https = __nccwpck_require__(5692); +var events = __nccwpck_require__(4434); +var assert = __nccwpck_require__(2613); +var util = __nccwpck_require__(9023); + + +__webpack_unused_export__ = httpOverHttp; +__webpack_unused_export__ = httpsOverHttp; +__webpack_unused_export__ = httpOverHttps; +__webpack_unused_export__ = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +__webpack_unused_export__ = debug; // for test + + +/***/ }), + +/***/ 6752: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +var __webpack_unused_export__; + + +const Client = __nccwpck_require__(3701) +const Dispatcher = __nccwpck_require__(883) +const Pool = __nccwpck_require__(628) +const BalancedPool = __nccwpck_require__(837) +const RoundRobinPool = __nccwpck_require__(5520) +const Agent = __nccwpck_require__(7405) +const Dispatcher1Wrapper = __nccwpck_require__(3650) +const ProxyAgent = __nccwpck_require__(6672) +const Socks5ProxyAgent = __nccwpck_require__(7223) +const EnvHttpProxyAgent = __nccwpck_require__(3137) +const RetryAgent = __nccwpck_require__(50) +const H2CClient = __nccwpck_require__(6815) +const errors = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) +const { InvalidArgumentError } = errors +const api = __nccwpck_require__(6615) +const buildConnector = __nccwpck_require__(9136) +const MockClient = __nccwpck_require__(7365) +const { MockCallHistory, MockCallHistoryLog } = __nccwpck_require__(431) +const MockAgent = __nccwpck_require__(7501) +const MockPool = __nccwpck_require__(4004) +const SnapshotAgent = __nccwpck_require__(5095) +const mockErrors = __nccwpck_require__(2429) +const RetryHandler = __nccwpck_require__(7816) +const { getGlobalDispatcher, setGlobalDispatcher } = __nccwpck_require__(2581) +const DecoratorHandler = __nccwpck_require__(8155) +const RedirectHandler = __nccwpck_require__(8754) + +Object.assign(Dispatcher.prototype, api) + +__webpack_unused_export__ = Dispatcher +__webpack_unused_export__ = Client +__webpack_unused_export__ = Pool +__webpack_unused_export__ = BalancedPool +__webpack_unused_export__ = RoundRobinPool +__webpack_unused_export__ = Agent +__webpack_unused_export__ = Dispatcher1Wrapper +__webpack_unused_export__ = ProxyAgent +__webpack_unused_export__ = Socks5ProxyAgent +__webpack_unused_export__ = EnvHttpProxyAgent +__webpack_unused_export__ = RetryAgent +__webpack_unused_export__ = H2CClient +__webpack_unused_export__ = RetryHandler + +__webpack_unused_export__ = DecoratorHandler +__webpack_unused_export__ = RedirectHandler +__webpack_unused_export__ = { + redirect: __nccwpck_require__(1514), + responseError: __nccwpck_require__(8918), + retry: __nccwpck_require__(2026), + dump: __nccwpck_require__(8060), + dns: __nccwpck_require__(379), + cache: __nccwpck_require__(5542), + decompress: __nccwpck_require__(557), + deduplicate: __nccwpck_require__(7240) +} + +__webpack_unused_export__ = { + MemoryCacheStore: __nccwpck_require__(4889) +} + +const SqliteCacheStore = __nccwpck_require__(1522) +__webpack_unused_export__ = SqliteCacheStore + +__webpack_unused_export__ = buildConnector +__webpack_unused_export__ = errors +__webpack_unused_export__ = { + parseHeaders: util.parseHeaders, + headerNameToString: util.headerNameToString +} + +function makeDispatcher (fn) { + return (url, opts, handler) => { + if (typeof opts === 'function') { + handler = opts + opts = null + } + + if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { + throw new InvalidArgumentError('invalid url') + } + + if (opts != null && typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (opts && opts.path != null) { + if (typeof opts.path !== 'string') { + throw new InvalidArgumentError('invalid opts.path') + } + + let path = opts.path + if (!opts.path.startsWith('/')) { + path = `/${path}` + } + + url = new URL(util.parseOrigin(url).origin + path) + } else { + if (!opts) { + opts = typeof url === 'object' ? url : {} + } + + url = util.parseURL(url) + } + + const { agent, dispatcher = getGlobalDispatcher(), ...restOpts } = opts + + if (agent) { + throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') + } + + return fn.call(dispatcher, { + ...restOpts, + origin: url.origin, + path: url.search ? `${url.pathname}${url.search}` : url.pathname, + method: opts.method || (opts.body ? 'PUT' : 'GET') + }, handler) + } +} + +__webpack_unused_export__ = setGlobalDispatcher +__webpack_unused_export__ = getGlobalDispatcher + +const fetchImpl = (__nccwpck_require__(4398).fetch) + +// Capture __filename at module load time for stack trace augmentation. +// This may be undefined when bundled in environments like Node.js internals. +const currentFilename = typeof __filename !== 'undefined' ? __filename : undefined + +function appendFetchStackTrace (err, filename) { + if (!err || typeof err !== 'object') { + return + } + + const stack = typeof err.stack === 'string' ? err.stack : '' + const normalizedFilename = filename.replace(/\\/g, '/') + + if (stack && (stack.includes(filename) || stack.includes(normalizedFilename))) { + return + } + + const capture = {} + Error.captureStackTrace(capture, appendFetchStackTrace) + + if (!capture.stack) { + return + } + + const captureLines = capture.stack.split('\n').slice(1).join('\n') + + err.stack = stack ? `${stack}\n${captureLines}` : capture.stack +} + +module.exports.hd = function fetch (init, options = undefined) { + return fetchImpl(init, options).catch(err => { + if (currentFilename) { + appendFetchStackTrace(err, currentFilename) + } else if (err && typeof err === 'object') { + Error.captureStackTrace(err, module.exports.hd) + } + throw err + }) +} +module.exports.Headers = __nccwpck_require__(660).Headers +module.exports.Response = __nccwpck_require__(9051).Response +module.exports.Request = __nccwpck_require__(9967).Request +module.exports.FormData = __nccwpck_require__(5910).FormData + +const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1059) + +__webpack_unused_export__ = setGlobalOrigin +__webpack_unused_export__ = getGlobalOrigin + +const { CacheStorage } = __nccwpck_require__(3245) +const { kConstruct } = __nccwpck_require__(6443) + +__webpack_unused_export__ = new CacheStorage(kConstruct) + +const { deleteCookie, getCookies, getSetCookies, setCookie, parseCookie } = __nccwpck_require__(9061) + +__webpack_unused_export__ = deleteCookie +__webpack_unused_export__ = getCookies +__webpack_unused_export__ = getSetCookies +__webpack_unused_export__ = setCookie +__webpack_unused_export__ = parseCookie + +const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(1900) + +__webpack_unused_export__ = parseMIMEType +__webpack_unused_export__ = serializeAMimeType + +const { CloseEvent, ErrorEvent, MessageEvent } = __nccwpck_require__(5188) +const { WebSocket, ping } = __nccwpck_require__(3726) +module.exports.kb = WebSocket +module.exports.rd = CloseEvent +module.exports.NN = ErrorEvent +module.exports.aM = MessageEvent +__webpack_unused_export__ = ping + +/* unused reexport */ __nccwpck_require__(2873).WebSocketStream +/* unused reexport */ __nccwpck_require__(6919).WebSocketError + +__webpack_unused_export__ = makeDispatcher(api.request) +__webpack_unused_export__ = makeDispatcher(api.stream) +__webpack_unused_export__ = makeDispatcher(api.pipeline) +__webpack_unused_export__ = makeDispatcher(api.connect) +__webpack_unused_export__ = makeDispatcher(api.upgrade) + +__webpack_unused_export__ = MockClient +__webpack_unused_export__ = MockCallHistory +__webpack_unused_export__ = MockCallHistoryLog +__webpack_unused_export__ = MockPool +__webpack_unused_export__ = MockAgent +__webpack_unused_export__ = SnapshotAgent +__webpack_unused_export__ = mockErrors + +const { EventSource } = __nccwpck_require__(1238) + +module.exports.GD = EventSource + +function install () { + globalThis.fetch = module.exports.hd + globalThis.Headers = module.exports.Headers + globalThis.Response = module.exports.Response + globalThis.Request = module.exports.Request + globalThis.FormData = module.exports.FormData + globalThis.WebSocket = module.exports.kb + globalThis.CloseEvent = module.exports.rd + globalThis.ErrorEvent = module.exports.NN + globalThis.MessageEvent = module.exports.aM + globalThis.EventSource = module.exports.GD +} + +__webpack_unused_export__ = install + + +/***/ }), + +/***/ 158: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { addAbortListener } = __nccwpck_require__(3440) +const { RequestAbortedError } = __nccwpck_require__(8707) + +const kListener = Symbol('kListener') +const kSignal = Symbol('kSignal') + +function abort (self) { + if (self.abort) { + self.abort(self[kSignal]?.reason) + } else { + self.reason = self[kSignal]?.reason ?? new RequestAbortedError() + } + removeSignal(self) +} + +function addSignal (self, signal) { + self.reason = null + + self[kSignal] = null + self[kListener] = null + + if (!signal) { + return + } + + if (signal.aborted) { + abort(self) + return + } + + self[kSignal] = signal + self[kListener] = () => { + abort(self) + } + + addAbortListener(self[kSignal], self[kListener]) +} + +function removeSignal (self) { + if (!self[kSignal]) { + return + } + + if ('removeEventListener' in self[kSignal]) { + self[kSignal].removeEventListener('abort', self[kListener]) + } else { + self[kSignal].removeListener('abort', self[kListener]) + } + + self[kSignal] = null + self[kListener] = null +} + +module.exports = { + addSignal, + removeSignal +} + + +/***/ }), + +/***/ 2279: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(4589) +const { AsyncResource } = __nccwpck_require__(6698) +const { InvalidArgumentError, SocketError } = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) +const { addSignal, removeSignal } = __nccwpck_require__(158) + +class ConnectHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + const { signal, opaque, responseHeaders } = opts + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + super('UNDICI_CONNECT') + + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.callback = callback + this.abort = null + + addSignal(this, signal) + } + + onRequestStart (controller, context) { + if (this.reason) { + controller.abort(this.reason) + return + } + + assert(this.callback) + + this.abort = (reason) => controller.abort(reason) + this.context = context + } + + onResponseStart () { + throw new SocketError('bad connect', null) + } + + onRequestUpgrade (controller, statusCode, headers, socket) { + const { callback, opaque, context } = this + + removeSignal(this) + + this.callback = null + + let responseHeaders = headers + const rawHeaders = controller?.rawHeaders + // Indicates is an HTTP2Session + if (responseHeaders != null) { + responseHeaders = this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : headers + } + + this.runInAsyncScope(callback, null, null, { + statusCode, + headers: responseHeaders, + socket, + opaque, + context + }) + } + + onResponseError (_controller, err) { + const { callback, opaque } = this + + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } +} + +function connect (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + connect.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const connectHandler = new ConnectHandler(opts, callback) + const connectOptions = { ...opts, method: 'CONNECT' } + this.dispatch(connectOptions, connectHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = connect + + +/***/ }), + +/***/ 6862: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + Readable, + Duplex, + PassThrough +} = __nccwpck_require__(7075) +const assert = __nccwpck_require__(4589) +const { AsyncResource } = __nccwpck_require__(6698) +const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError +} = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) +const { kBodyUsed } = __nccwpck_require__(6443) +const { addSignal, removeSignal } = __nccwpck_require__(158) + +function noop () {} + +const kResume = Symbol('resume') + +class PipelineRequest extends Readable { + constructor () { + super({ autoDestroy: true }) + + this[kResume] = null + // Pipeline request bodies come from a live writable side and cannot be + // replayed across redirects or retries, even before any bytes are read. + this[kBodyUsed] = true + } + + _read () { + const { [kResume]: resume } = this + + if (resume) { + this[kResume] = null + resume() + } + } + + _destroy (err, callback) { + this._read() + + callback(err) + } +} + +class PipelineResponse extends Readable { + constructor (resume) { + super({ autoDestroy: true }) + this[kResume] = resume + } + + _read () { + this[kResume]() + } + + _destroy (err, callback) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() + } + + callback(err) + } +} + +class PipelineHandler extends AsyncResource { + constructor (opts, handler) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof handler !== 'function') { + throw new InvalidArgumentError('invalid handler') + } + + const { signal, method, opaque, onInfo, responseHeaders } = opts + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_PIPELINE') + + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.handler = handler + this.abort = null + this.context = null + this.onInfo = onInfo || null + + this.req = new PipelineRequest().on('error', noop) + + this.ret = new Duplex({ + readableObjectMode: opts.objectMode, + autoDestroy: true, + read: () => { + const { body } = this + + if (body?.resume) { + body.resume() + } + }, + write: (chunk, encoding, callback) => { + const { req } = this + + if (req.push(chunk, encoding) || req._readableState.destroyed) { + callback() + } else { + req[kResume] = callback + } + }, + destroy: (err, callback) => { + const { body, req, res, ret, abort } = this + + if (!err && !ret._readableState.endEmitted) { + err = new RequestAbortedError() + } + + if (abort && err) { + abort() + } + + util.destroy(body, err) + util.destroy(req, err) + util.destroy(res, err) + + removeSignal(this) + + callback(err) + } + }).on('prefinish', () => { + const { req } = this + + // Node < 15 does not call _final in same tick. + req.push(null) + }) + + this.res = null + + addSignal(this, signal) + } + + onRequestStart (controller, context) { + const { res } = this + + if (this.reason) { + controller.abort(this.reason) + return + } + + assert(!res, 'pipeline cannot be retried') + + this.abort = (reason) => controller.abort(reason) + this.context = context + } + + onResponseStart (controller, statusCode, headers, _statusMessage) { + const { opaque, handler, context } = this + + if (statusCode < 200) { + if (this.onInfo) { + const rawHeaders = controller?.rawHeaders + const responseHeaders = this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : headers + this.onInfo({ statusCode, headers: responseHeaders }) + } + return + } + + this.res = new PipelineResponse(() => controller.resume()) + + let body + try { + this.handler = null + const rawHeaders = controller?.rawHeaders + const responseHeaders = this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : headers + body = this.runInAsyncScope(handler, null, { + statusCode, + headers: responseHeaders, + opaque, + body: this.res, + context + }) + } catch (err) { + this.res.on('error', noop) + throw err + } + + if (!body || typeof body.on !== 'function') { + throw new InvalidReturnValueError('expected Readable') + } + + body + .on('data', (chunk) => { + const { ret, body } = this + + if (!ret.push(chunk) && body.pause) { + body.pause() + } + }) + .on('error', (err) => { + const { ret } = this + + util.destroy(ret, err) + }) + .on('end', () => { + const { ret } = this + + ret.push(null) + }) + .on('close', () => { + const { ret } = this + + if (!ret._readableState.ended) { + util.destroy(ret, new RequestAbortedError()) + } + }) + + this.body = body + } + + onResponseData (controller, chunk) { + const { res } = this + + if (res.push(chunk) === false) { + controller.pause() + } + } + + onResponseEnd (_controller, _trailers) { + const { res } = this + res.push(null) + } + + onResponseError (_controller, err) { + const { ret } = this + this.handler = null + util.destroy(ret, err) + } +} + +function pipeline (opts, handler) { + try { + const pipelineHandler = new PipelineHandler(opts, handler) + this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) + return pipelineHandler.ret + } catch (err) { + return new PassThrough().destroy(err) + } +} + +module.exports = pipeline + + +/***/ }), + +/***/ 4043: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(4589) +const { AsyncResource } = __nccwpck_require__(6698) +const { Readable } = __nccwpck_require__(9927) +const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) + +function noop () {} + +class RequestHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + const { signal, method, opaque, body, onInfo, responseHeaders, highWaterMark } = opts + + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (highWaterMark != null && (!Number.isFinite(highWaterMark) || highWaterMark < 0)) { + throw new InvalidArgumentError('invalid highWaterMark') + } + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_REQUEST') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', noop), err) + } + throw err + } + + this.method = method + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.res = null + this.abort = null + this.body = body + this.trailers = {} + this.context = null + this.controller = null + this.onInfo = onInfo || null + this.highWaterMark = highWaterMark + this.reason = null + this.removeAbortListener = null + + if (signal?.aborted) { + this.reason = signal.reason ?? new RequestAbortedError() + } else if (signal) { + this.removeAbortListener = util.addAbortListener(signal, () => { + this.reason = signal.reason ?? new RequestAbortedError() + if (this.res) { + // Null the reference before destroying, mirroring onResponseError, so + // that chunks flushed after the abort (e.g. an async decompressor + // flush) are dropped by the `!this.res` guard in onResponseData + // instead of being pushed into the torn-down stream. + const res = this.res + this.res = null + util.destroy(res.on('error', noop), this.reason) + } else if (this.abort) { + this.abort(this.reason) + } + }) + } + } + + onRequestStart (controller, context) { + if (this.reason) { + controller.abort(this.reason) + return + } + + assert(this.callback) + + this.controller = controller + this.abort = (reason) => controller.abort(reason) + this.context = context + } + + onResponseStart (controller, statusCode, headers, statusText) { + const { callback, opaque, context, responseHeaders, highWaterMark } = this + + const rawHeaders = controller?.rawHeaders + const responseHeaderData = responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : headers + + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers: responseHeaderData }) + } + return + } + + const parsedHeaders = headers + const contentType = parsedHeaders?.['content-type'] + const contentLength = parsedHeaders?.['content-length'] + const res = new Readable({ + resume: () => controller.resume(), + abort: (reason) => controller.abort(reason), + contentType, + contentLength: this.method !== 'HEAD' && contentLength + ? Number(contentLength) + : null, + highWaterMark + }) + + if (this.removeAbortListener) { + res.on('close', this.removeAbortListener) + this.removeAbortListener = null + } + + this.callback = null + this.res = res + if (callback !== null) { + try { + this.runInAsyncScope(callback, null, null, { + statusCode, + statusText, + headers: responseHeaderData, + trailers: this.trailers, + opaque, + body: res, + context + }) + } catch (err) { + // If the callback throws synchronously, we need to handle it + // Remove reference to res to allow res being garbage collected + this.res = null + + // Destroy the response stream + util.destroy(res.on('error', noop), err) + + // Use queueMicrotask to re-throw the error so it reaches uncaughtException + queueMicrotask(() => { + throw err + }) + } + } + } + + onResponseData (controller, chunk) { + if (!this.res) { + return + } + + if (this.res.push(chunk) === false) { + controller.pause() + } + } + + onResponseEnd (_controller, trailers) { + if (trailers && typeof trailers === 'object') { + for (const key of Object.keys(trailers)) { + if (key === '__proto__') { + Object.defineProperty(this.trailers, key, { + value: trailers[key], + enumerable: true, + configurable: true, + writable: true + }) + } else { + this.trailers[key] = trailers[key] + } + } + } + this.res?.push(null) + } + + onResponseError (_controller, err) { + const { res, callback, body, opaque } = this + + if (callback) { + // TODO: Does this need queueMicrotask? + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + + if (res) { + this.res = null + // Ensure all queued handlers are invoked before destroying res. + queueMicrotask(() => { + util.destroy(res.on('error', noop), err) + }) + } + + if (body) { + this.body = null + + if (util.isStream(body)) { + body.on('error', noop) + util.destroy(body, err) + } + } + + if (this.removeAbortListener) { + this.removeAbortListener() + this.removeAbortListener = null + } + } +} + +function request (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + request.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const handler = new RequestHandler(opts, callback) + + this.dispatch(opts, handler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = request +module.exports.RequestHandler = RequestHandler + + +/***/ }), + +/***/ 3560: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(4589) +const { AsyncResource } = __nccwpck_require__(6698) +const { InvalidArgumentError, InvalidReturnValueError } = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) +const { addSignal, removeSignal } = __nccwpck_require__(158) + +function noop () {} + +function getWritableError (stream) { + return stream.errored ?? stream.writableErrored ?? stream._writableState?.errored +} + +function createPrematureCloseError () { + const err = new Error('Premature close') + err.code = 'ERR_STREAM_PREMATURE_CLOSE' + return err +} + +function trackWritableLifecycle (stream, callback) { + let done = false + + const cleanup = () => { + stream.removeListener('close', onClose) + stream.removeListener('error', onError) + stream.removeListener('finish', onFinish) + } + + const finish = (err, fromErrorEvent = false) => { + if (done) { + return + } + + done = true + cleanup() + callback(err, fromErrorEvent) + } + + const onClose = () => { + const err = getWritableError(stream) + finish(err ?? (!stream.writableFinished ? createPrematureCloseError() : undefined)) + } + + const onError = (err) => finish(err, true) + const onFinish = () => finish() + + stream.on('close', onClose) + stream.on('error', onError) + stream.on('finish', onFinish) + + if (stream.closed) { + process.nextTick(onClose) + } else if (stream.writableFinished) { + process.nextTick(onFinish) + } +} + +class StreamHandler extends AsyncResource { + constructor (opts, factory, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + const { signal, method, opaque, body, onInfo, responseHeaders } = opts + + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('invalid factory') + } + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_STREAM') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', noop), err) + } + throw err + } + + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.factory = factory + this.callback = callback + this.res = null + this.abort = null + this.context = null + this.controller = null + this.trailers = null + this.body = body + this.onInfo = onInfo || null + + if (util.isStream(body)) { + body.on('error', (err) => { + this.onResponseError(this.controller, err) + }) + } + + addSignal(this, signal) + } + + onRequestStart (controller, context) { + if (this.reason) { + controller.abort(this.reason) + return + } + + assert(this.callback) + + this.controller = controller + this.abort = (reason) => controller.abort(reason) + this.context = context + } + + onResponseStart (controller, statusCode, headers, _statusMessage) { + const { factory, opaque, context, responseHeaders } = this + + const rawHeaders = controller?.rawHeaders + const responseHeaderData = responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : headers + + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers: responseHeaderData }) + } + return + } + + this.factory = null + + if (factory === null) { + return + } + + const res = this.runInAsyncScope(factory, null, { + statusCode, + headers: responseHeaderData, + opaque, + context + }) + + if ( + !res || + typeof res.write !== 'function' || + typeof res.end !== 'function' || + typeof res.on !== 'function' + ) { + throw new InvalidReturnValueError('expected Writable') + } + + trackWritableLifecycle(res, (err, fromErrorEvent) => { + const { callback, res, opaque, trailers, abort } = this + + this.res = null + if (err || !res?.readable) { + util.destroy(res, fromErrorEvent ? undefined : err) + } + + this.callback = null + this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) + + if (err) { + abort(err) + } + }) + + res.on('drain', () => controller.resume()) + + this.res = res + + const needDrain = res.writableNeedDrain !== undefined + ? res.writableNeedDrain + : res._writableState?.needDrain + + if (needDrain === true) { + controller.pause() + } + } + + onResponseData (controller, chunk) { + const { res } = this + + if (!res) { + return + } + + if (res.write(chunk) === false) { + controller.pause() + } + } + + onResponseEnd (_controller, trailers) { + const { res } = this + + removeSignal(this) + + if (!res) { + return + } + + if (trailers && typeof trailers === 'object') { + this.trailers = trailers + } + + res.end() + } + + onResponseError (_controller, err) { + const { res, callback, opaque, body } = this + + removeSignal(this) + + this.factory = null + + if (res) { + this.res = null + util.destroy(res, err) + } else if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + + if (body) { + this.body = null + util.destroy(body, err) + } + } +} + +function stream (opts, factory, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + stream.call(this, opts, factory, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const handler = new StreamHandler(opts, factory, callback) + + this.dispatch(opts, handler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = stream + + +/***/ }), + +/***/ 1882: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { InvalidArgumentError, SocketError } = __nccwpck_require__(8707) +const { AsyncResource } = __nccwpck_require__(6698) +const assert = __nccwpck_require__(4589) +const util = __nccwpck_require__(3440) +const { kHTTP2Stream } = __nccwpck_require__(6443) +const { addSignal, removeSignal } = __nccwpck_require__(158) + +class UpgradeHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + const { signal, opaque, responseHeaders } = opts + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + super('UNDICI_UPGRADE') + + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.abort = null + this.context = null + + addSignal(this, signal) + } + + onRequestStart (controller, context) { + if (this.reason) { + controller.abort(this.reason) + return + } + + assert(this.callback) + + this.abort = (reason) => controller.abort(reason) + this.context = context + } + + onResponseStart () { + throw new SocketError('bad upgrade', null) + } + + onRequestUpgrade (controller, statusCode, headers, socket) { + const expectedStatusCode = socket[kHTTP2Stream] === true ? 200 : 101 + + if (statusCode !== expectedStatusCode) { + const socketInfo = socket[kHTTP2Stream] === true ? null : util.getSocketInfo(socket) + controller.abort(new SocketError('bad upgrade', socketInfo)) + return + } + + const { callback, opaque, context } = this + + removeSignal(this) + + this.callback = null + + const rawHeaders = controller?.rawHeaders + const responseHeaders = this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : headers + + this.runInAsyncScope(callback, null, null, { + headers: responseHeaders, + socket, + opaque, + context + }) + } + + onResponseError (_controller, err) { + const { callback, opaque } = this + + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } +} + +function upgrade (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + upgrade.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const upgradeHandler = new UpgradeHandler(opts, callback) + const upgradeOpts = { + ...opts, + method: opts.method || 'GET', + upgrade: opts.protocol || 'Websocket' + } + this.dispatch(upgradeOpts, upgradeHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts?.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = upgrade + + +/***/ }), + +/***/ 6615: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +module.exports.request = __nccwpck_require__(4043) +module.exports.stream = __nccwpck_require__(3560) +module.exports.pipeline = __nccwpck_require__(6862) +module.exports.upgrade = __nccwpck_require__(1882) +module.exports.connect = __nccwpck_require__(2279) + + +/***/ }), + +/***/ 9927: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(4589) +const { addAbortListener } = __nccwpck_require__(8474) +const { Readable } = __nccwpck_require__(7075) +const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) + +const kConsume = Symbol('kConsume') +const kReading = Symbol('kReading') +const kBody = Symbol('kBody') +const kAbort = Symbol('kAbort') +const kContentType = Symbol('kContentType') +const kContentLength = Symbol('kContentLength') +const kUsed = Symbol('kUsed') +const kBytesRead = Symbol('kBytesRead') + +const noop = () => {} + +/** + * @class + * @extends {Readable} + * @see https://fetch.spec.whatwg.org/#body + */ +class BodyReadable extends Readable { + /** + * @param {object} opts + * @param {(this: Readable, size: number) => void} opts.resume + * @param {() => (void | null)} opts.abort + * @param {string} [opts.contentType = ''] + * @param {number} [opts.contentLength] + * @param {number} [opts.highWaterMark = 64 * 1024] + */ + constructor ({ + resume, + abort, + contentType = '', + contentLength, + highWaterMark = 64 * 1024 // Same as nodejs fs streams. + }) { + super({ + autoDestroy: true, + read: resume, + highWaterMark + }) + + this._readableState.dataEmitted = false + + this[kAbort] = abort + + /** @type {Consume | null} */ + this[kConsume] = null + + /** @type {number} */ + this[kBytesRead] = 0 + + /** @type {ReadableStream|null} */ + this[kBody] = null + + /** @type {boolean} */ + this[kUsed] = false + + /** @type {string} */ + this[kContentType] = contentType + + /** @type {number|null} */ + this[kContentLength] = Number.isFinite(contentLength) ? contentLength : null + + /** + * Is stream being consumed through Readable API? + * This is an optimization so that we avoid checking + * for 'data' and 'readable' listeners in the hot path + * inside push(). + * + * @type {boolean} + */ + this[kReading] = false + } + + /** + * @param {Error|null} err + * @param {(error:(Error|null)) => void} callback + * @returns {void} + */ + _destroy (err, callback) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() + } + + if (err) { + this[kAbort]() + } + + // Workaround for Node "bug". If the stream is destroyed in same + // tick as it is created, then a user who is waiting for a + // promise (i.e micro tick) for installing an 'error' listener will + // never get a chance and will always encounter an unhandled exception. + if (!this[kUsed]) { + setImmediate(callback, err) + } else { + callback(err) + } + } + + /** + * @param {string|symbol} event + * @param {(...args: any[]) => void} listener + * @returns {this} + */ + on (event, listener) { + if (event === 'data' || event === 'readable') { + this[kReading] = true + this[kUsed] = true + } + return super.on(event, listener) + } + + /** + * @param {string|symbol} event + * @param {(...args: any[]) => void} listener + * @returns {this} + */ + addListener (event, listener) { + return this.on(event, listener) + } + + /** + * @param {string|symbol} event + * @param {(...args: any[]) => void} listener + * @returns {this} + */ + off (event, listener) { + const ret = super.off(event, listener) + if (event === 'data' || event === 'readable') { + this[kReading] = ( + this.listenerCount('data') > 0 || + this.listenerCount('readable') > 0 + ) + } + return ret + } + + /** + * @param {string|symbol} event + * @param {(...args: any[]) => void} listener + * @returns {this} + */ + removeListener (event, listener) { + return this.off(event, listener) + } + + /** + * @param {Buffer|null} chunk + * @returns {boolean} + */ + push (chunk) { + if (chunk) { + this[kBytesRead] += chunk.length + if (this[kConsume]) { + consumePush(this[kConsume], chunk) + return this[kReading] ? super.push(chunk) : true + } + } + + return super.push(chunk) + } + + /** + * Consumes and returns the body as a string. + * + * @see https://fetch.spec.whatwg.org/#dom-body-text + * @returns {Promise} + */ + text () { + return consume(this, 'text') + } + + /** + * Consumes and returns the body as a JavaScript Object. + * + * @see https://fetch.spec.whatwg.org/#dom-body-json + * @returns {Promise} + */ + json () { + return consume(this, 'json') + } + + /** + * Consumes and returns the body as a Blob + * + * @see https://fetch.spec.whatwg.org/#dom-body-blob + * @returns {Promise} + */ + blob () { + return consume(this, 'blob') + } + + /** + * Consumes and returns the body as an Uint8Array. + * + * @see https://fetch.spec.whatwg.org/#dom-body-bytes + * @returns {Promise} + */ + bytes () { + return consume(this, 'bytes') + } + + /** + * Consumes and returns the body as an ArrayBuffer. + * + * @see https://fetch.spec.whatwg.org/#dom-body-arraybuffer + * @returns {Promise} + */ + arrayBuffer () { + return consume(this, 'arrayBuffer') + } + + /** + * Not implemented + * + * @see https://fetch.spec.whatwg.org/#dom-body-formdata + * @throws {NotSupportedError} + */ + async formData () { + // TODO: Implement. + throw new NotSupportedError() + } + + /** + * Returns true if the body is not null and the body has been consumed. + * Otherwise, returns false. + * + * @see https://fetch.spec.whatwg.org/#dom-body-bodyused + * @readonly + * @returns {boolean} + */ + get bodyUsed () { + return util.isDisturbed(this) + } + + /** + * @see https://fetch.spec.whatwg.org/#dom-body-body + * @readonly + * @returns {ReadableStream} + */ + get body () { + if (!this[kBody]) { + this[kBody] = ReadableStream.from(this) + if (this[kConsume]) { + // TODO: Is this the best way to force a lock? + this[kBody].getReader() // Ensure stream is locked. + assert(this[kBody].locked) + } + } + return this[kBody] + } + + /** + * Dumps the response body by reading `limit` number of bytes. + * @param {object} opts + * @param {number} [opts.limit = 131072] Number of bytes to read. + * @param {AbortSignal} [opts.signal] An AbortSignal to cancel the dump. + * @returns {Promise} + */ + dump (opts) { + const signal = opts?.signal + + if (signal != null && (typeof signal !== 'object' || !('aborted' in signal))) { + return Promise.reject(new InvalidArgumentError('signal must be an AbortSignal')) + } + + const limit = opts?.limit && Number.isFinite(opts.limit) + ? opts.limit + : 128 * 1024 + + if (signal?.aborted) { + return Promise.reject(signal.reason ?? new AbortError()) + } + + if (this._readableState.closeEmitted) { + return Promise.resolve(null) + } + + return new Promise((resolve, reject) => { + if ( + (this[kContentLength] && (this[kContentLength] > limit)) || + this[kBytesRead] > limit + ) { + this.destroy(new AbortError()) + } + + if (signal) { + const onAbort = () => { + this.destroy(signal.reason ?? new AbortError()) + } + const abortListener = addAbortListener(signal, onAbort) + this + .on('close', function () { + abortListener[Symbol.dispose]() + if (signal.aborted) { + reject(signal.reason ?? new AbortError()) + } else { + resolve(null) + } + }) + } else { + this.on('close', resolve) + } + + this + .on('error', noop) + .on('data', () => { + if (this[kBytesRead] > limit) { + this.destroy() + } + }) + .resume() + }) + } + + /** + * @param {BufferEncoding} encoding + * @returns {this} + */ + setEncoding (encoding) { + if (Buffer.isEncoding(encoding)) { + // Delegate to Node.js Readable.setEncoding() which initializes a + // StringDecoder and re-encodes already-buffered chunks. This properly + // handles multi-byte sequences split at chunk boundaries for the + // for-await / on('data') paths. Without this, Node.js uses + // buf.toString(encoding) on each chunk, producing U+FFFD for split chars. + // + // The consume path (body.text(), body.json(), ...) copes with the + // decoded strings this leaves in state.buffer, see consumeStart(). + super.setEncoding(encoding) + } + return this + } +} + +/** + * @see https://streams.spec.whatwg.org/#readablestream-locked + * @param {BodyReadable} bodyReadable + * @returns {boolean} + */ +function isLocked (bodyReadable) { + // Consume is an implicit lock. + return bodyReadable[kBody]?.locked === true || bodyReadable[kConsume] !== null +} + +/** + * @see https://fetch.spec.whatwg.org/#body-unusable + * @param {BodyReadable} bodyReadable + * @returns {boolean} + */ +function isUnusable (bodyReadable) { + return util.isDisturbed(bodyReadable) || isLocked(bodyReadable) +} + +/** + * @typedef {'text' | 'json' | 'blob' | 'bytes' | 'arrayBuffer'} ConsumeType + */ + +/** + * @template {ConsumeType} T + * @typedef {T extends 'text' ? string : + * T extends 'json' ? unknown : + * T extends 'blob' ? Blob : + * T extends 'arrayBuffer' ? ArrayBuffer : + * T extends 'bytes' ? Uint8Array : + * never + * } ConsumeReturnType + */ +/** + * @typedef {object} Consume + * @property {ConsumeType} type + * @property {BodyReadable} stream + * @property {((value?: any) => void)} resolve + * @property {((err: Error) => void)} reject + * @property {number} length + * @property {Buffer[]} body + */ + +/** + * @template {ConsumeType} T + * @param {BodyReadable} stream + * @param {T} type + * @returns {Promise>} + */ +function consume (stream, type) { + assert(!stream[kConsume]) + + return new Promise((resolve, reject) => { + if (isUnusable(stream)) { + const rState = stream._readableState + if (rState.destroyed && rState.closeEmitted === false) { + stream + .on('error', reject) + .on('close', () => { + reject(new TypeError('unusable')) + }) + } else { + reject(rState.errored ?? new TypeError('unusable')) + } + } else { + queueMicrotask(() => { + stream[kConsume] = { + type, + stream, + resolve, + reject, + length: 0, + body: [] + } + + stream + .on('error', function (err) { + consumeFinish(this[kConsume], err) + }) + .on('close', function () { + if (this[kConsume].body !== null) { + consumeFinish(this[kConsume], new RequestAbortedError()) + } + }) + + consumeStart(stream[kConsume]) + }) + } + }) +} + +/** + * @param {Consume} consume + * @returns {void} + */ +function consumeStart (consume) { + if (consume.body === null) { + return + } + + const { _readableState: state } = consume.stream + + if (state.bufferIndex) { + const start = state.bufferIndex + const end = state.buffer.length + for (let n = start; n < end; n++) { + consumePush(consume, state.buffer[n]) + } + } else { + for (const chunk of state.buffer) { + consumePush(consume, chunk) + } + } + + // If setEncoding() was called, state.buffer holds decoded strings, which + // consumePush() turns back into bytes. The trailing bytes of a multi-byte + // sequence split across a chunk boundary are not part of any of those + // strings, they are held inside the decoder until the rest arrives, so + // take them from there. + const decoder = state.decoder + if (decoder != null && decoder.lastNeed > 0) { + consumePush(consume, Buffer.from(decoder.lastChar.subarray(0, decoder.lastTotal - decoder.lastNeed))) + } + + if (state.endEmitted) { + // No `this` to read the consume off here: consumeStart is a free function, called from + // the queueMicrotask above. The callback below does have one, because the emitter passes + // the stream as its receiver. Returning matters too - consumeEnd() clears consume.stream, + // which the resume() below would then dereference. + consumeEnd(consume, state.encoding) + return + } + + consume.stream.on('end', function () { + consumeEnd(this[kConsume], this._readableState.encoding) + }) + + consume.stream.resume() + + while (consume.stream.read() != null) { + // Loop + } +} + +/** + * @param {Buffer[]} chunks + * @param {number} length + * @param {BufferEncoding} [encoding='utf8'] + * @returns {string} + */ +function chunksDecode (chunks, length, encoding) { + if (chunks.length === 0 || length === 0) { + return '' + } + const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, length) + const bufferLength = buffer.length + + // Skip BOM. + const start = + bufferLength > 2 && + buffer[0] === 0xef && + buffer[1] === 0xbb && + buffer[2] === 0xbf + ? 3 + : 0 + if (!encoding || encoding === 'utf8' || encoding === 'utf-8') { + return buffer.utf8Slice(start, bufferLength) + } else { + return buffer.subarray(start, bufferLength).toString(encoding) + } +} + +/** + * @param {Buffer[]} chunks + * @param {number} length + * @returns {Uint8Array} + */ +function chunksConcat (chunks, length) { + if (chunks.length === 0 || length === 0) { + return new Uint8Array(0) + } + if (chunks.length === 1) { + // fast-path + return new Uint8Array(chunks[0]) + } + const buffer = new Uint8Array(Buffer.allocUnsafeSlow(length).buffer) + + let offset = 0 + for (let i = 0; i < chunks.length; ++i) { + const chunk = chunks[i] + buffer.set(chunk, offset) + offset += chunk.length + } + + return buffer +} + +/** + * @param {Consume} consume + * @param {BufferEncoding} encoding + * @returns {void} + */ +function consumeEnd (consume, encoding) { + const { type, body, resolve, stream, length } = consume + + try { + if (type === 'text') { + resolve(chunksDecode(body, length, encoding)) + } else if (type === 'json') { + resolve(JSON.parse(chunksDecode(body, length, encoding))) + } else if (type === 'arrayBuffer') { + resolve(chunksConcat(body, length).buffer) + } else if (type === 'blob') { + resolve(new Blob(body, { type: stream[kContentType] })) + } else if (type === 'bytes') { + resolve(chunksConcat(body, length)) + } + + consumeFinish(consume) + } catch (err) { + stream.destroy(err) + } +} + +/** + * @param {Consume} consume + * @param {Buffer|string} chunk + * @returns {void} + */ +function consumePush (consume, chunk) { + if (consume.body === null) { + return + } + + if (typeof chunk === 'string') { + // Buffered before the consume started, while an encoding was set. + // consume.length has to stay a byte count and chunksDecode()/chunksConcat() + // only work on bytes, so re-encode. A string's own length is in UTF-16 code + // units and Uint8Array.prototype.set() ignores a string argument entirely. + chunk = Buffer.from(chunk, consume.stream._readableState.encoding) + } + + consume.length += chunk.length + consume.body.push(chunk) +} + +/** + * @param {Consume} consume + * @param {Error} [err] + * @returns {void} + */ +function consumeFinish (consume, err) { + if (consume.body === null) { + return + } + + if (err) { + consume.reject(err) + } else { + consume.resolve() + } + + // Reset the consume object to allow for garbage collection. + consume.type = null + consume.stream = null + consume.resolve = null + consume.reject = null + consume.length = 0 + consume.body = null +} + +module.exports = { + Readable: BodyReadable, + chunksDecode +} + + +/***/ }), + +/***/ 4889: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { Writable } = __nccwpck_require__(7075) +const { EventEmitter } = __nccwpck_require__(8474) +const { assertCacheKey, assertCacheValue } = __nccwpck_require__(7659) + +/** + * @typedef {import('../../types/cache-interceptor.d.ts').default.CacheKey} CacheKey + * @typedef {import('../../types/cache-interceptor.d.ts').default.CacheValue} CacheValue + * @typedef {import('../../types/cache-interceptor.d.ts').default.CacheStore} CacheStore + * @typedef {import('../../types/cache-interceptor.d.ts').default.GetResult} GetResult + */ + +/** + * @implements {CacheStore} + * @extends {EventEmitter} + */ +class MemoryCacheStore extends EventEmitter { + #maxCount = 1024 + #maxSize = 104857600 // 100MB + #maxEntrySize = 5242880 // 5MB + + #size = 0 + #count = 0 + #entries = new Map() + #hasEmittedMaxSizeEvent = false + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.MemoryCacheStoreOpts | undefined} [opts] + */ + constructor (opts) { + super() + if (opts) { + if (typeof opts !== 'object') { + throw new TypeError('MemoryCacheStore options must be an object') + } + + if (opts.maxCount !== undefined) { + if ( + typeof opts.maxCount !== 'number' || + !Number.isInteger(opts.maxCount) || + opts.maxCount < 0 + ) { + throw new TypeError('MemoryCacheStore options.maxCount must be a non-negative integer') + } + this.#maxCount = opts.maxCount + } + + if (opts.maxSize !== undefined) { + if ( + typeof opts.maxSize !== 'number' || + !Number.isInteger(opts.maxSize) || + opts.maxSize < 0 + ) { + throw new TypeError('MemoryCacheStore options.maxSize must be a non-negative integer') + } + this.#maxSize = opts.maxSize + } + + if (opts.maxEntrySize !== undefined) { + if ( + typeof opts.maxEntrySize !== 'number' || + !Number.isInteger(opts.maxEntrySize) || + opts.maxEntrySize < 0 + ) { + throw new TypeError('MemoryCacheStore options.maxEntrySize must be a non-negative integer') + } + this.#maxEntrySize = opts.maxEntrySize + } + } + } + + /** + * Get the current size of the cache in bytes + * @returns {number} The current size of the cache in bytes + */ + get size () { + return this.#size + } + + /** + * Check if the cache is full (either max size or max count reached) + * @returns {boolean} True if the cache is full, false otherwise + */ + isFull () { + return this.#size >= this.#maxSize || this.#count >= this.#maxCount + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + * @returns {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined} + */ + get (key) { + assertCacheKey(key) + + const topLevelKey = `${key.origin}:${key.path}` + + const now = Date.now() + const entries = this.#entries.get(topLevelKey) + + const entry = entries ? findEntry(key, entries, now) : null + + if (entry != null) { + this.#entries.delete(topLevelKey) + this.#entries.set(topLevelKey, entries) + } + + return entry == null + ? undefined + : { + statusMessage: entry.statusMessage, + statusCode: entry.statusCode, + headers: entry.headers, + body: entry.body, + vary: entry.vary ? entry.vary : undefined, + etag: entry.etag, + cacheControlDirectives: entry.cacheControlDirectives, + cachedAt: entry.cachedAt, + staleAt: entry.staleAt, + deleteAt: entry.deleteAt + } + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + * @param {import('../../types/cache-interceptor.d.ts').default.CacheValue} val + * @returns {Writable | undefined} + */ + createWriteStream (key, val) { + assertCacheKey(key) + assertCacheValue(val) + + const topLevelKey = `${key.origin}:${key.path}` + + const store = this + const entry = { ...key, ...val, body: [], size: 0 } + + return new Writable({ + write (chunk, encoding, callback) { + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding) + } + + entry.size += chunk.byteLength + + if (entry.size > store.#maxEntrySize) { + this.destroy() + } else { + entry.body.push(chunk) + } + + callback(null) + }, + final (callback) { + let entries = store.#entries.get(topLevelKey) + if (entries) { + store.#entries.delete(topLevelKey) + } else { + entries = [] + } + store.#entries.set(topLevelKey, entries) + const previousEntry = findEntry(key, entries, -Infinity) + if (previousEntry) { + const index = entries.indexOf(previousEntry) + entries.splice(index, 1, entry) + store.#size -= previousEntry.size + } else { + entries.push(entry) + store.#count += 1 + } + + store.#size += entry.size + + // Check if cache is full and emit event if needed + if (store.#size > store.#maxSize || store.#count > store.#maxCount) { + // Emit maxSizeExceeded event if we haven't already + if (!store.#hasEmittedMaxSizeEvent) { + store.emit('maxSizeExceeded', { + size: store.#size, + maxSize: store.#maxSize, + count: store.#count, + maxCount: store.#maxCount + }) + store.#hasEmittedMaxSizeEvent = true + } + + store.#evict(entry) + + // Reset the event flag after eviction + if (store.#size < store.#maxSize && store.#count < store.#maxCount) { + store.#hasEmittedMaxSizeEvent = false + } + } + + callback(null) + } + }) + } + + #evict (keep) { + const targetSize = this.#maxSize / 2 + const targetCount = this.#maxCount / 2 + + for (const [key, entries] of this.#entries) { + for (let i = 0; i < entries.length && (this.#size > targetSize || this.#count > targetCount);) { + const entry = entries[i] + if (entry === keep) { + i++ + continue + } + entries.splice(i, 1) + this.#size -= entry.size + this.#count -= 1 + } + + if (entries.length === 0) { + this.#entries.delete(key) + } + + if (this.#size <= targetSize && this.#count <= targetCount) { + return + } + } + + if (this.#size > this.#maxSize || this.#count > this.#maxCount) { + const topLevelKey = `${keep.origin}:${keep.path}` + const entries = this.#entries.get(topLevelKey) + entries.splice(entries.indexOf(keep), 1) + this.#size -= keep.size + this.#count -= 1 + if (entries.length === 0) { + this.#entries.delete(topLevelKey) + } + } + } + + /** + * @param {CacheKey} key + */ + delete (key) { + if (typeof key !== 'object') { + throw new TypeError(`expected key to be object, got ${typeof key}`) + } + + const topLevelKey = `${key.origin}:${key.path}` + + for (const entry of this.#entries.get(topLevelKey) ?? []) { + this.#size -= entry.size + this.#count -= 1 + } + this.#entries.delete(topLevelKey) + } +} + +function findEntry (key, entries, now) { + for (let i = 0; i < entries.length; i++) { + const entry = entries[i] + if ( + entry.deleteAt > now && + entry.method === key.method && + varyMatches(key, entry) + ) { + return entry + } + } +} + +function varyMatches (key, entry) { + if (entry.vary == null) { + return true + } + + for (const headerName in entry.vary) { + if (Object.hasOwn(entry.vary, headerName) && !headerValueEquals(key.headers?.[headerName], entry.vary[headerName])) { + return false + } + } + + return true +} + +/** + * @param {string|string[]|null|undefined} lhs + * @param {string|string[]|null|undefined} rhs + * @returns {boolean} + */ +function headerValueEquals (lhs, rhs) { + if (lhs == null && rhs == null) { + return true + } + + if ((lhs == null && rhs != null) || + (lhs != null && rhs == null)) { + return false + } + + if (Array.isArray(lhs) && Array.isArray(rhs)) { + if (lhs.length !== rhs.length) { + return false + } + + for (let i = 0; i < lhs.length; i++) { + if (lhs[i] !== rhs[i]) { + return false + } + } + + return true + } + + return lhs === rhs +} + +module.exports = MemoryCacheStore + + +/***/ }), + +/***/ 1522: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { Writable } = __nccwpck_require__(7075) +const { assertCacheKey, assertCacheValue } = __nccwpck_require__(7659) +const { zstdCompressSync, zstdDecompressSync } = __nccwpck_require__(8522) + +let DatabaseSync + +const VERSION = 4 + +// 2gb +const MAX_ENTRY_SIZE = 2 * 1000 * 1000 * 1000 + +// 1MiB +const COMPRESS_THRESHOLD = 1024 * 1024 + +// zstd support landed in Node 22.19.0/23.4.0, so it may be missing even when +// node:sqlite is available. +const hasZstd = typeof zstdCompressSync === 'function' && typeof zstdDecompressSync === 'function' + +/** + * @typedef {import('../../types/cache-interceptor.d.ts').default.CacheStore} CacheStore + * @implements {CacheStore} + * + * @typedef {{ + * id: Readonly, + * body?: Uint8Array + * compressed?: string + * statusCode: number + * statusMessage: string + * headers?: string + * vary?: string + * etag?: string + * cacheControlDirectives?: string + * cachedAt: number + * staleAt: number + * deleteAt: number + * }} SqliteStoreValue + */ +module.exports = class SqliteCacheStore { + #maxEntrySize = MAX_ENTRY_SIZE + #maxCount = Infinity + #compressThreshold = COMPRESS_THRESHOLD + + /** + * @type {import('node:sqlite').DatabaseSync} + */ + #db + + /** + * @type {import('node:sqlite').StatementSync} + */ + #getValuesQuery + + /** + * @type {import('node:sqlite').StatementSync} + */ + #updateValueQuery + + /** + * @type {import('node:sqlite').StatementSync} + */ + #insertValueQuery + + /** + * @type {import('node:sqlite').StatementSync} + */ + #deleteExpiredValuesQuery + + /** + * @type {import('node:sqlite').StatementSync} + */ + #deleteByUrlQuery + + /** + * @type {import('node:sqlite').StatementSync} + */ + #countEntriesQuery + + /** + * @type {import('node:sqlite').StatementSync | null} + */ + #deleteOldValuesQuery + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.SqliteCacheStoreOpts | undefined} opts + */ + constructor (opts) { + if (opts) { + if (typeof opts !== 'object') { + throw new TypeError('SqliteCacheStore options must be an object') + } + + if (opts.maxEntrySize !== undefined) { + if ( + typeof opts.maxEntrySize !== 'number' || + !Number.isInteger(opts.maxEntrySize) || + opts.maxEntrySize < 0 + ) { + throw new TypeError('SqliteCacheStore options.maxEntrySize must be a non-negative integer') + } + + if (opts.maxEntrySize > MAX_ENTRY_SIZE) { + throw new TypeError('SqliteCacheStore options.maxEntrySize must be less than 2gb') + } + + this.#maxEntrySize = opts.maxEntrySize + } + + if (opts.maxCount !== undefined) { + if ( + typeof opts.maxCount !== 'number' || + !Number.isInteger(opts.maxCount) || + opts.maxCount < 0 + ) { + throw new TypeError('SqliteCacheStore options.maxCount must be a non-negative integer') + } + this.#maxCount = opts.maxCount + } + + if (opts.compressThreshold !== undefined) { + if ( + typeof opts.compressThreshold !== 'number' || + !Number.isInteger(opts.compressThreshold) || + opts.compressThreshold < 0 + ) { + throw new TypeError('SqliteCacheStore options.compressThreshold must be a non-negative integer') + } + this.#compressThreshold = opts.compressThreshold + } + } + + if (!DatabaseSync) { + DatabaseSync = (__nccwpck_require__(99).DatabaseSync) + } + this.#db = new DatabaseSync(opts?.location ?? ':memory:') + + this.#db.exec(` + PRAGMA journal_mode = WAL; + PRAGMA synchronous = NORMAL; + PRAGMA temp_store = memory; + PRAGMA optimize; + + CREATE TABLE IF NOT EXISTS cacheInterceptorV${VERSION} ( + -- Data specific to us + id INTEGER PRIMARY KEY AUTOINCREMENT, + url TEXT NOT NULL, + method TEXT NOT NULL, + + -- Data returned to the interceptor + body BUF NULL, + compressed TEXT NULL, + deleteAt INTEGER NOT NULL, + statusCode INTEGER NOT NULL, + statusMessage TEXT NOT NULL, + headers TEXT NULL, + cacheControlDirectives TEXT NULL, + etag TEXT NULL, + vary TEXT NULL, + cachedAt INTEGER NOT NULL, + staleAt INTEGER NOT NULL + ); + + CREATE INDEX IF NOT EXISTS idx_cacheInterceptorV${VERSION}_getValuesQuery ON cacheInterceptorV${VERSION}(url, method, deleteAt); + CREATE INDEX IF NOT EXISTS idx_cacheInterceptorV${VERSION}_deleteByUrlQuery ON cacheInterceptorV${VERSION}(deleteAt); + `) + + this.#getValuesQuery = this.#db.prepare(` + SELECT + id, + body, + compressed, + deleteAt, + statusCode, + statusMessage, + headers, + etag, + cacheControlDirectives, + vary, + cachedAt, + staleAt + FROM cacheInterceptorV${VERSION} + WHERE + url = ? + AND method = ? + ORDER BY + deleteAt ASC + `) + + this.#updateValueQuery = this.#db.prepare(` + UPDATE cacheInterceptorV${VERSION} SET + body = ?, + compressed = ?, + deleteAt = ?, + statusCode = ?, + statusMessage = ?, + headers = ?, + etag = ?, + cacheControlDirectives = ?, + vary = ?, + cachedAt = ?, + staleAt = ? + WHERE + id = ? + `) + + this.#insertValueQuery = this.#db.prepare(` + INSERT INTO cacheInterceptorV${VERSION} ( + url, + method, + body, + compressed, + deleteAt, + statusCode, + statusMessage, + headers, + etag, + cacheControlDirectives, + vary, + cachedAt, + staleAt + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `) + + this.#deleteByUrlQuery = this.#db.prepare( + `DELETE FROM cacheInterceptorV${VERSION} WHERE url = ?` + ) + + this.#countEntriesQuery = this.#db.prepare( + `SELECT COUNT(*) AS total FROM cacheInterceptorV${VERSION}` + ) + + this.#deleteExpiredValuesQuery = this.#db.prepare( + `DELETE FROM cacheInterceptorV${VERSION} WHERE deleteAt <= ?` + ) + + this.#deleteOldValuesQuery = this.#maxCount === Infinity + ? null + : this.#db.prepare(` + DELETE FROM cacheInterceptorV${VERSION} + WHERE id IN ( + SELECT + id + FROM cacheInterceptorV${VERSION} + ORDER BY cachedAt ASC + LIMIT ? + ) + `) + } + + close () { + this.#db.close() + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + * @returns {(import('../../types/cache-interceptor.d.ts').default.GetResult & { body?: Buffer }) | undefined} + */ + get (key) { + assertCacheKey(key) + + const value = this.#findValue(key) + return value + ? { + body: value.body + ? value.compressed === 'zstd' + ? zstdDecompressSync(Buffer.from(value.body.buffer, value.body.byteOffset, value.body.byteLength)) + : Buffer.from(value.body.buffer, value.body.byteOffset, value.body.byteLength) + : undefined, + statusCode: value.statusCode, + statusMessage: value.statusMessage, + headers: value.headers ? JSON.parse(value.headers) : undefined, + etag: value.etag ? value.etag : undefined, + vary: value.vary ? JSON.parse(value.vary) : undefined, + cacheControlDirectives: value.cacheControlDirectives + ? JSON.parse(value.cacheControlDirectives) + : undefined, + cachedAt: value.cachedAt, + staleAt: value.staleAt, + deleteAt: value.deleteAt + } + : undefined + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + * @param {import('../../types/cache-interceptor.d.ts').default.CacheValue & { body: null | Buffer | Array}} value + */ + set (key, value) { + assertCacheKey(key) + + const url = this.#makeValueUrl(key) + const body = Array.isArray(value.body) ? Buffer.concat(value.body) : value.body + const size = body?.byteLength + + if (size && size > this.#maxEntrySize) { + return + } + + let compressed = null + let storedBody = body + if (body && hasZstd && (size > this.#compressThreshold || isCompressibleContentType(getContentType(value.headers)))) { + const candidate = zstdCompressSync(body) + if (candidate.byteLength < body.byteLength) { + storedBody = candidate + compressed = 'zstd' + } + } + + const existingValue = this.#findValue(key, true) + if (existingValue) { + // Updating an existing response, let's overwrite it + this.#updateValueQuery.run( + storedBody, + compressed, + value.deleteAt, + value.statusCode, + value.statusMessage, + value.headers ? JSON.stringify(value.headers) : null, + value.etag ? value.etag : null, + value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null, + value.vary ? JSON.stringify(value.vary) : null, + value.cachedAt, + value.staleAt, + existingValue.id + ) + } else { + // New response, let's insert it + this.#insertValueQuery.run( + url, + key.method, + storedBody, + compressed, + value.deleteAt, + value.statusCode, + value.statusMessage, + value.headers ? JSON.stringify(value.headers) : null, + value.etag ? value.etag : null, + value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null, + value.vary ? JSON.stringify(value.vary) : null, + value.cachedAt, + value.staleAt + ) + this.#prune() + } + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + * @param {import('../../types/cache-interceptor.d.ts').default.CacheValue} value + * @returns {Writable | undefined} + */ + createWriteStream (key, value) { + assertCacheKey(key) + assertCacheValue(value) + + let size = 0 + /** + * @type {Buffer[] | null} + */ + const body = [] + const store = this + + return new Writable({ + decodeStrings: true, + write (chunk, encoding, callback) { + size += chunk.byteLength + + if (size <= store.#maxEntrySize) { + body.push(chunk) + } else { + this.destroy() + } + + callback() + }, + final (callback) { + store.set(key, { ...value, body }) + callback() + } + }) + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + */ + delete (key) { + if (typeof key !== 'object') { + throw new TypeError(`expected key to be object, got ${typeof key}`) + } + + this.#deleteByUrlQuery.run(this.#makeValueUrl(key)) + } + + #prune () { + if (Number.isFinite(this.#maxCount) && this.size <= this.#maxCount) { + return 0 + } + + { + const removed = this.#deleteExpiredValuesQuery.run(Date.now()).changes + if (removed) { + return removed + } + } + + { + const removed = this.#deleteOldValuesQuery?.run(Math.max(Math.floor(this.#maxCount * 0.1), 1)).changes + if (removed) { + return removed + } + } + + return 0 + } + + /** + * Counts the number of rows in the cache + * @returns {Number} + */ + get size () { + const { total } = this.#countEntriesQuery.get() + return total + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + * @returns {string} + */ + #makeValueUrl (key) { + return `${key.origin}/${key.path}` + } + + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key + * @param {boolean} [canBeExpired=false] + * @returns {SqliteStoreValue | undefined} + */ + #findValue (key, canBeExpired = false) { + const url = this.#makeValueUrl(key) + const { headers, method } = key + + /** + * @type {SqliteStoreValue[]} + */ + const values = this.#getValuesQuery.all(url, method) + + if (values.length === 0) { + return undefined + } + + const now = Date.now() + for (const value of values) { + if (now >= value.deleteAt && !canBeExpired) { + continue + } + + let matches = true + + if (value.vary) { + const vary = JSON.parse(value.vary) + + for (const header in vary) { + if (!headerValueEquals(headers[header], vary[header])) { + matches = false + break + } + } + } + + if (matches) { + return value + } + } + + return undefined + } +} + +/** + * @param {string|string[]|null|undefined} lhs + * @param {string|string[]|null|undefined} rhs + * @returns {boolean} + */ +function headerValueEquals (lhs, rhs) { + if (lhs == null && rhs == null) { + return true + } + + if ((lhs == null && rhs != null) || + (lhs != null && rhs == null)) { + return false + } + + if (Array.isArray(lhs) && Array.isArray(rhs)) { + if (lhs.length !== rhs.length) { + return false + } + + for (let i = 0; i < lhs.length; i++) { + if (lhs[i] !== rhs[i]) { + return false + } + } + + return true + } + + return lhs === rhs +} + +/** + * @param {Record|null|undefined} headers + * @returns {string|undefined} + */ +function getContentType (headers) { + if (headers == null) { + return undefined + } + + for (const key in headers) { + if (key.toLowerCase() === 'content-type') { + const value = headers[key] + return Array.isArray(value) ? value[0] : value + } + } + + return undefined +} + +/** + * @param {string|undefined} contentType + * @returns {boolean} + */ +function isCompressibleContentType (contentType) { + if (contentType == null) { + return false + } + + const type = contentType.toLowerCase() + + // text/* and application/json, xml, javascript, ... are easily compressible + // even at smaller sizes, so ignore the compressThreshold for them. + return /^text\//.test(type) || + /^application\/(json|xml|javascript|x-www-form-urlencoded|graphql)(\s|;|$)/.test(type) || + /\+(json|xml)(\s|;|$)/.test(type) +} + + +/***/ }), + +/***/ 9136: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const net = __nccwpck_require__(7030) +const assert = __nccwpck_require__(4589) +const util = __nccwpck_require__(3440) +const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8707) + +let tls // include tls conditionally since it is not always available + +// TODO: session re-use does not wait for the first +// connection to resolve the session and might therefore +// resolve the same servername multiple times even when +// re-use is enabled. + +const SessionCache = class WeakSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + this._sessionRegistry = new FinalizationRegistry((key) => { + if (this._sessionCache.size < this._maxCachedSessions) { + return + } + + const ref = this._sessionCache.get(key) + if (ref !== undefined && ref.deref() === undefined) { + this._sessionCache.delete(key) + } + }) + } + + get (sessionKey) { + const ref = this._sessionCache.get(sessionKey) + return ref ? ref.deref() : null + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return + } + + if (this._sessionCache.has(sessionKey)) { + this._sessionCache.delete(sessionKey) + } else if (this._sessionCache.size >= this._maxCachedSessions) { + // Make room for the new session: prefer an entry whose session has + // already been collected, otherwise evict the oldest one. + let evicted = false + for (const [key, ref] of this._sessionCache) { + if (ref.deref() === undefined) { + this._sessionCache.delete(key) + evicted = true + break + } + } + + if (!evicted) { + const oldest = this._sessionCache.keys().next() + if (!oldest.done) { + this._sessionCache.delete(oldest.value) + } + } + } + + this._sessionCache.set(sessionKey, new WeakRef(session)) + this._sessionRegistry.register(session, sessionKey) + } +} + +function buildConnector ({ allowH2, preferH2, useH2c, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { + if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { + throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') + } + + const options = { path: socketPath, ...opts } + const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) + timeout = timeout == null ? 10e3 : timeout + allowH2 = allowH2 != null ? allowH2 : true + return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { + let socket + if (protocol === 'https:') { + if (!tls) { + tls = __nccwpck_require__(1692) + } + servername = servername || options.servername || util.getServerName(host) || null + + const sessionKey = servername || hostname + assert(sessionKey) + + const session = customSession || sessionCache.get(sessionKey) || null + + port = port || 443 + + socket = tls.connect({ + highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... + ...options, + servername, + session, + localAddress, + ALPNProtocols: allowH2 ? (preferH2 ? ['h2', 'http/1.1'] : ['http/1.1', 'h2']) : ['http/1.1'], + socket: httpSocket, // upgrade socket connection + port, + host: hostname + }) + + socket + .on('session', function (session) { + // TODO (fix): Can a session become invalid once established? Don't think so? + sessionCache.set(sessionKey, session) + }) + } else { + assert(!httpSocket, 'httpSocket can only be sent on TLS update') + + port = port || 80 + + const connectOptions = { + highWaterMark: 64 * 1024, // Same as nodejs fs streams. + ...options, + localAddress, + port, + host: hostname + } + + const family = net.isIP(hostname) + if (family !== 0 && servername && servername !== hostname) { + connectOptions.host = servername + connectOptions.lookup = (_hostname, lookupOptions, cb) => { + if (lookupOptions.all) { + cb(null, [{ address: hostname, family }]) + } else { + cb(null, hostname, family) + } + } + } + + socket = net.connect(connectOptions) + if (useH2c === true) { + socket.alpnProtocol = 'h2' + } + } + + // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket + if (options.keepAlive == null || options.keepAlive) { + const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay + socket.setKeepAlive(true, keepAliveInitialDelay) + } + + const clearConnectTimeout = util.setupConnectTimeout(new WeakRef(socket), { timeout, hostname, port }) + + socket + .setNoDelay(true) + .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { + queueMicrotask(clearConnectTimeout) + + if (callback) { + const cb = callback + callback = null + cb(null, this) + } + }) + .on('error', function (err) { + queueMicrotask(clearConnectTimeout) + + if (callback) { + const cb = callback + callback = null + cb(maybeNormalizeConnectError(err, this, { timeout, hostname, port })) + } + }) + + return socket + } +} + +// `net.connect` with `autoSelectFamily` raises an `AggregateError` when every +// attempted address fails. If any of those failures is a timeout, surface the +// error as a `ConnectTimeoutError` so callers see the same error regardless of +// which timer (Node's internal one or undici's `connectTimeout`) wins the race. +// The original `AggregateError` is preserved on `.cause`. +function maybeNormalizeConnectError (err, socket, opts) { + if ( + err instanceof AggregateError && + (err.code === 'ETIMEDOUT' || err.errors.some((e) => e != null && e.code === 'ETIMEDOUT')) + ) { + let message = 'Connect Timeout Error' + if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { + message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')},` + } else { + message += ` (attempted address: ${opts.hostname}:${opts.port},` + } + message += ` timeout: ${opts.timeout}ms)` + + const wrapped = new ConnectTimeoutError(message) + wrapped.cause = err + return wrapped + } + return err +} + +module.exports = buildConnector + + +/***/ }), + +/***/ 735: +/***/ ((module) => { + +"use strict"; + + +/** + * @see https://developer.mozilla.org/docs/Web/HTTP/Headers + */ +const wellknownHeaderNames = /** @type {const} */ ([ + 'Accept', + 'Accept-Encoding', + 'Accept-Language', + 'Accept-Ranges', + 'Access-Control-Allow-Credentials', + 'Access-Control-Allow-Headers', + 'Access-Control-Allow-Methods', + 'Access-Control-Allow-Origin', + 'Access-Control-Expose-Headers', + 'Access-Control-Max-Age', + 'Access-Control-Request-Headers', + 'Access-Control-Request-Method', + 'Age', + 'Allow', + 'Alt-Svc', + 'Alt-Used', + 'Authorization', + 'Cache-Control', + 'Clear-Site-Data', + 'Connection', + 'Content-Disposition', + 'Content-Encoding', + 'Content-Language', + 'Content-Length', + 'Content-Location', + 'Content-Range', + 'Content-Security-Policy', + 'Content-Security-Policy-Report-Only', + 'Content-Type', + 'Cookie', + 'Cross-Origin-Embedder-Policy', + 'Cross-Origin-Opener-Policy', + 'Cross-Origin-Resource-Policy', + 'Date', + 'Device-Memory', + 'Downlink', + 'ECT', + 'ETag', + 'Expect', + 'Expect-CT', + 'Expires', + 'Forwarded', + 'From', + 'Host', + 'If-Match', + 'If-Modified-Since', + 'If-None-Match', + 'If-Range', + 'If-Unmodified-Since', + 'Keep-Alive', + 'Last-Modified', + 'Link', + 'Location', + 'Max-Forwards', + 'Origin', + 'Permissions-Policy', + 'Pragma', + 'Proxy-Authenticate', + 'Proxy-Authorization', + 'RTT', + 'Range', + 'Referer', + 'Referrer-Policy', + 'Refresh', + 'Retry-After', + 'Sec-WebSocket-Accept', + 'Sec-WebSocket-Extensions', + 'Sec-WebSocket-Key', + 'Sec-WebSocket-Protocol', + 'Sec-WebSocket-Version', + 'Server', + 'Server-Timing', + 'Service-Worker-Allowed', + 'Service-Worker-Navigation-Preload', + 'Set-Cookie', + 'SourceMap', + 'Strict-Transport-Security', + 'Supports-Loading-Mode', + 'TE', + 'Timing-Allow-Origin', + 'Trailer', + 'Transfer-Encoding', + 'Upgrade', + 'Upgrade-Insecure-Requests', + 'User-Agent', + 'Vary', + 'Via', + 'WWW-Authenticate', + 'X-Content-Type-Options', + 'X-DNS-Prefetch-Control', + 'X-Frame-Options', + 'X-Permitted-Cross-Domain-Policies', + 'X-Powered-By', + 'X-Requested-With', + 'X-XSS-Protection' +]) + +/** @type {Record, string>} */ +const headerNameLowerCasedRecord = {} + +// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. +Object.setPrototypeOf(headerNameLowerCasedRecord, null) + +for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = wellknownHeaderNames[i] + const lowerCasedKey = key.toLowerCase() + headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] = + lowerCasedKey +} + +/** + * Default WebSocket receive limits (see `webSocket` in Client.md). Used by + * DispatcherBase#webSocketOptions and by the WebSocket parser when the + * dispatcher doesn't provide a value, so a dispatcher without + * `webSocketOptions` (a custom one, or a wrapper) doesn't remove the limits. + */ +const defaultWebSocketMaxFragments = 131072 +const defaultWebSocketMaxPayloadSize = 128 * 1024 * 1024 // 128 MB + +module.exports = { + wellknownHeaderNames, + headerNameLowerCasedRecord, + defaultWebSocketMaxFragments, + defaultWebSocketMaxPayloadSize +} + + +/***/ }), + +/***/ 2414: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const diagnosticsChannel = __nccwpck_require__(3053) +const util = __nccwpck_require__(7975) + +const undiciDebugLog = util.debuglog('undici') +const fetchDebuglog = util.debuglog('fetch') +const websocketDebuglog = util.debuglog('websocket') + +const channels = { + // Client + beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), + connected: diagnosticsChannel.channel('undici:client:connected'), + connectError: diagnosticsChannel.channel('undici:client:connectError'), + sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), + // Request + create: diagnosticsChannel.channel('undici:request:create'), + bodySent: diagnosticsChannel.channel('undici:request:bodySent'), + bodyChunkSent: diagnosticsChannel.channel('undici:request:bodyChunkSent'), + bodyChunkReceived: diagnosticsChannel.channel('undici:request:bodyChunkReceived'), + headers: diagnosticsChannel.channel('undici:request:headers'), + trailers: diagnosticsChannel.channel('undici:request:trailers'), + error: diagnosticsChannel.channel('undici:request:error'), + // WebSocket + open: diagnosticsChannel.channel('undici:websocket:open'), + close: diagnosticsChannel.channel('undici:websocket:close'), + socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), + ping: diagnosticsChannel.channel('undici:websocket:ping'), + pong: diagnosticsChannel.channel('undici:websocket:pong'), + // ProxyAgent + proxyConnected: diagnosticsChannel.channel('undici:proxy:connected') +} + +let isTrackingClientEvents = false + +function trackClientEvents (debugLog = undiciDebugLog) { + if (isTrackingClientEvents) { + return + } + + // Check if any of the channels already have subscribers to prevent duplicate subscriptions + // This can happen when both Node.js built-in undici and undici as a dependency are present + if (channels.beforeConnect.hasSubscribers || channels.connected.hasSubscribers || + channels.connectError.hasSubscribers || channels.sendHeaders.hasSubscribers) { + isTrackingClientEvents = true + return + } + + isTrackingClientEvents = true + + diagnosticsChannel.subscribe('undici:client:beforeConnect', + evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + debugLog( + 'connecting to %s%s using %s%s', + host, + port ? `:${port}` : '', + protocol, + version + ) + }) + + diagnosticsChannel.subscribe('undici:client:connected', + evt => { + const { + connectParams: { version, protocol, port, host } + } = evt + debugLog( + 'connected to %s%s using %s%s', + host, + port ? `:${port}` : '', + protocol, + version + ) + }) + + diagnosticsChannel.subscribe('undici:client:connectError', + evt => { + const { + connectParams: { version, protocol, port, host }, + error + } = evt + debugLog( + 'connection to %s%s using %s%s errored - %s', + host, + port ? `:${port}` : '', + protocol, + version, + error.message + ) + }) + + diagnosticsChannel.subscribe('undici:client:sendHeaders', + evt => { + const { + request: { method, path, origin } + } = evt + debugLog('sending request to %s %s%s', method, origin, path) + }) +} + +let isTrackingRequestEvents = false + +function trackRequestEvents (debugLog = undiciDebugLog) { + if (isTrackingRequestEvents) { + return + } + + // Check if any of the channels already have subscribers to prevent duplicate subscriptions + // This can happen when both Node.js built-in undici and undici as a dependency are present + if (channels.headers.hasSubscribers || channels.trailers.hasSubscribers || + channels.error.hasSubscribers) { + isTrackingRequestEvents = true + return + } + + isTrackingRequestEvents = true + + diagnosticsChannel.subscribe('undici:request:headers', + evt => { + const { + request: { method, path, origin }, + response: { statusCode } + } = evt + debugLog( + 'received response to %s %s%s - HTTP %d', + method, + origin, + path, + statusCode + ) + }) + + diagnosticsChannel.subscribe('undici:request:trailers', + evt => { + const { + request: { method, path, origin } + } = evt + debugLog('trailers received from %s %s%s', method, origin, path) + }) + + diagnosticsChannel.subscribe('undici:request:error', + evt => { + const { + request: { method, path, origin }, + error + } = evt + debugLog( + 'request to %s %s%s errored - %s', + method, + origin, + path, + error.message + ) + }) +} + +let isTrackingWebSocketEvents = false + +function trackWebSocketEvents (debugLog = websocketDebuglog) { + if (isTrackingWebSocketEvents) { + return + } + + // Check if any of the channels already have subscribers to prevent duplicate subscriptions + // This can happen when both Node.js built-in undici and undici as a dependency are present + if (channels.open.hasSubscribers || channels.close.hasSubscribers || + channels.socketError.hasSubscribers || channels.ping.hasSubscribers || + channels.pong.hasSubscribers) { + isTrackingWebSocketEvents = true + return + } + + isTrackingWebSocketEvents = true + + diagnosticsChannel.subscribe('undici:websocket:open', + evt => { + if (evt.address != null) { + const { address, port } = evt.address + debugLog('connection opened %s%s', address, port ? `:${port}` : '') + } else { + debugLog('connection opened') + } + }) + + diagnosticsChannel.subscribe('undici:websocket:close', + evt => { + const { websocket, code, reason } = evt + debugLog( + 'closed connection to %s - %s %s', + websocket.url, + code, + reason + ) + }) + + diagnosticsChannel.subscribe('undici:websocket:socket_error', + err => { + debugLog('connection errored - %s', err.message) + }) + + diagnosticsChannel.subscribe('undici:websocket:ping', + evt => { + debugLog('ping received') + }) + + diagnosticsChannel.subscribe('undici:websocket:pong', + evt => { + debugLog('pong received') + }) +} + +if (undiciDebugLog.enabled || fetchDebuglog.enabled) { + trackClientEvents(fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog) + trackRequestEvents(fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog) +} + +if (websocketDebuglog.enabled) { + trackClientEvents(undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog) + trackWebSocketEvents(websocketDebuglog) +} + +module.exports = { + channels +} + + +/***/ }), + +/***/ 8707: +/***/ ((module) => { + +"use strict"; + + +const kUndiciError = Symbol.for('undici.error.UND_ERR') +class UndiciError extends Error { + constructor (message, options) { + super(message, options) + this.name = 'UndiciError' + this.code = 'UND_ERR' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kUndiciError] === true + } + + get [kUndiciError] () { + return true + } +} + +const kConnectTimeoutError = Symbol.for('undici.error.UND_ERR_CONNECT_TIMEOUT') +class ConnectTimeoutError extends UndiciError { + constructor (message) { + super(message) + this.name = 'ConnectTimeoutError' + this.message = message || 'Connect Timeout Error' + this.code = 'UND_ERR_CONNECT_TIMEOUT' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kConnectTimeoutError] === true + } + + get [kConnectTimeoutError] () { + return true + } +} + +const kHeadersTimeoutError = Symbol.for('undici.error.UND_ERR_HEADERS_TIMEOUT') +class HeadersTimeoutError extends UndiciError { + constructor (message) { + super(message) + this.name = 'HeadersTimeoutError' + this.message = message || 'Headers Timeout Error' + this.code = 'UND_ERR_HEADERS_TIMEOUT' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kHeadersTimeoutError] === true + } + + get [kHeadersTimeoutError] () { + return true + } +} + +const kHeadersOverflowError = Symbol.for('undici.error.UND_ERR_HEADERS_OVERFLOW') +class HeadersOverflowError extends UndiciError { + constructor (message) { + super(message) + this.name = 'HeadersOverflowError' + this.message = message || 'Headers Overflow Error' + this.code = 'UND_ERR_HEADERS_OVERFLOW' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kHeadersOverflowError] === true + } + + get [kHeadersOverflowError] () { + return true + } +} + +const kBodyTimeoutError = Symbol.for('undici.error.UND_ERR_BODY_TIMEOUT') +class BodyTimeoutError extends UndiciError { + constructor (message) { + super(message) + this.name = 'BodyTimeoutError' + this.message = message || 'Body Timeout Error' + this.code = 'UND_ERR_BODY_TIMEOUT' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kBodyTimeoutError] === true + } + + get [kBodyTimeoutError] () { + return true + } +} + +const kInvalidArgumentError = Symbol.for('undici.error.UND_ERR_INVALID_ARG') +class InvalidArgumentError extends UndiciError { + constructor (message) { + super(message) + this.name = 'InvalidArgumentError' + this.message = message || 'Invalid Argument Error' + this.code = 'UND_ERR_INVALID_ARG' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kInvalidArgumentError] === true + } + + get [kInvalidArgumentError] () { + return true + } +} + +const kInvalidReturnValueError = Symbol.for('undici.error.UND_ERR_INVALID_RETURN_VALUE') +class InvalidReturnValueError extends UndiciError { + constructor (message) { + super(message) + this.name = 'InvalidReturnValueError' + this.message = message || 'Invalid Return Value Error' + this.code = 'UND_ERR_INVALID_RETURN_VALUE' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kInvalidReturnValueError] === true + } + + get [kInvalidReturnValueError] () { + return true + } +} + +const kAbortError = Symbol.for('undici.error.UND_ERR_ABORT') +class AbortError extends UndiciError { + constructor (message) { + super(message) + this.name = 'AbortError' + this.message = message || 'The operation was aborted' + this.code = 'UND_ERR_ABORT' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kAbortError] === true + } + + get [kAbortError] () { + return true + } +} + +const kRequestAbortedError = Symbol.for('undici.error.UND_ERR_ABORTED') +class RequestAbortedError extends AbortError { + constructor (message) { + super(message) + this.name = 'AbortError' + this.message = message || 'Request aborted' + this.code = 'UND_ERR_ABORTED' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kRequestAbortedError] === true + } + + get [kRequestAbortedError] () { + return true + } +} + +const kInformationalError = Symbol.for('undici.error.UND_ERR_INFO') +class InformationalError extends UndiciError { + constructor (message, options) { + super(message, options) + this.name = 'InformationalError' + this.message = message || 'Request information' + this.code = 'UND_ERR_INFO' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kInformationalError] === true + } + + get [kInformationalError] () { + return true + } +} + +const kRequestContentLengthMismatchError = Symbol.for('undici.error.UND_ERR_REQ_CONTENT_LENGTH_MISMATCH') +class RequestContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + this.name = 'RequestContentLengthMismatchError' + this.message = message || 'Request body length does not match content-length header' + this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kRequestContentLengthMismatchError] === true + } + + get [kRequestContentLengthMismatchError] () { + return true + } +} + +const kResponseContentLengthMismatchError = Symbol.for('undici.error.UND_ERR_RES_CONTENT_LENGTH_MISMATCH') +class ResponseContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + this.name = 'ResponseContentLengthMismatchError' + this.message = message || 'Response body length does not match content-length header' + this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kResponseContentLengthMismatchError] === true + } + + get [kResponseContentLengthMismatchError] () { + return true + } +} + +const kClientDestroyedError = Symbol.for('undici.error.UND_ERR_DESTROYED') +class ClientDestroyedError extends UndiciError { + constructor (message) { + super(message) + this.name = 'ClientDestroyedError' + this.message = message || 'The client is destroyed' + this.code = 'UND_ERR_DESTROYED' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kClientDestroyedError] === true + } + + get [kClientDestroyedError] () { + return true + } +} + +const kClientClosedError = Symbol.for('undici.error.UND_ERR_CLOSED') +class ClientClosedError extends UndiciError { + constructor (message) { + super(message) + this.name = 'ClientClosedError' + this.message = message || 'The client is closed' + this.code = 'UND_ERR_CLOSED' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kClientClosedError] === true + } + + get [kClientClosedError] () { + return true + } +} + +const kSocketError = Symbol.for('undici.error.UND_ERR_SOCKET') +class SocketError extends UndiciError { + constructor (message, socket) { + super(message) + this.name = 'SocketError' + this.message = message || 'Socket error' + this.code = 'UND_ERR_SOCKET' + this.socket = socket + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kSocketError] === true + } + + get [kSocketError] () { + return true + } +} + +const kNotSupportedError = Symbol.for('undici.error.UND_ERR_NOT_SUPPORTED') +class NotSupportedError extends UndiciError { + constructor (message) { + super(message) + this.name = 'NotSupportedError' + this.message = message || 'Not supported error' + this.code = 'UND_ERR_NOT_SUPPORTED' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kNotSupportedError] === true + } + + get [kNotSupportedError] () { + return true + } +} + +const kBalancedPoolMissingUpstreamError = Symbol.for('undici.error.UND_ERR_BPL_MISSING_UPSTREAM') +class BalancedPoolMissingUpstreamError extends UndiciError { + constructor (message) { + super(message) + this.name = 'MissingUpstreamError' + this.message = message || 'No upstream has been added to the BalancedPool' + this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kBalancedPoolMissingUpstreamError] === true + } + + get [kBalancedPoolMissingUpstreamError] () { + return true + } +} + +const kWebAssemblyNotSupportedError = Symbol.for('undici.error.ERR_WEBASSEMBLY_NOT_SUPPORTED') +class WebAssemblyNotSupportedError extends Error { + constructor (message) { + super(message || 'WebAssembly is not supported in this environment, but is required for HTTP/1 parsing') + this.code = 'ERR_WEBASSEMBLY_NOT_SUPPORTED' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kWebAssemblyNotSupportedError] === true + } + + get [kWebAssemblyNotSupportedError] () { + return true + } +} + +const kHTTPParserError = Symbol.for('undici.error.UND_ERR_HTTP_PARSER') +class HTTPParserError extends Error { + constructor (message, code, data) { + super(message) + this.name = 'HTTPParserError' + this.code = code ? `HPE_${code}` : undefined + this.data = data ? data.toString() : undefined + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kHTTPParserError] === true + } + + get [kHTTPParserError] () { + return true + } +} + +const kResponseExceededMaxSizeError = Symbol.for('undici.error.UND_ERR_RES_EXCEEDED_MAX_SIZE') +class ResponseExceededMaxSizeError extends UndiciError { + constructor (message) { + super(message) + this.name = 'ResponseExceededMaxSizeError' + this.message = message || 'Response content exceeded max size' + this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kResponseExceededMaxSizeError] === true + } + + get [kResponseExceededMaxSizeError] () { + return true + } +} + +const kRequestRetryError = Symbol.for('undici.error.UND_ERR_REQ_RETRY') +class RequestRetryError extends UndiciError { + constructor (message, code, { headers, data }) { + super(message) + this.name = 'RequestRetryError' + this.message = message || 'Request retry error' + this.code = 'UND_ERR_REQ_RETRY' + this.statusCode = code + this.data = data + this.headers = headers + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kRequestRetryError] === true + } + + get [kRequestRetryError] () { + return true + } +} + +const kResponseError = Symbol.for('undici.error.UND_ERR_RESPONSE') +class ResponseError extends UndiciError { + constructor (message, code, { headers, body, bodyTruncated = false }) { + super(message) + this.name = 'ResponseError' + this.message = message || 'Response error' + this.code = 'UND_ERR_RESPONSE' + this.statusCode = code + this.body = body + this.bodyTruncated = bodyTruncated + this.headers = headers + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kResponseError] === true + } + + get [kResponseError] () { + return true + } +} + +const kSecureProxyConnectionError = Symbol.for('undici.error.UND_ERR_PRX_TLS') +class SecureProxyConnectionError extends UndiciError { + constructor (cause, message, options = {}) { + super(message, { cause, ...options }) + this.name = 'SecureProxyConnectionError' + this.message = message || 'Secure Proxy Connection failed' + this.code = 'UND_ERR_PRX_TLS' + this.cause = cause + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kSecureProxyConnectionError] === true + } + + get [kSecureProxyConnectionError] () { + return true + } +} + +const kProxyConnectionError = Symbol.for('undici.error.UND_ERR_PRX_CONN') +class ProxyConnectionError extends UndiciError { + constructor (cause, message, options = {}) { + super(message, { cause, ...options }) + this.name = 'ProxyConnectionError' + this.message = message || 'Proxy Connection failed' + this.code = 'UND_ERR_PRX_CONN' + this.cause = cause + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kProxyConnectionError] === true + } + + get [kProxyConnectionError] () { + return true + } +} + +const kMaxRedirectsError = Symbol.for('undici.error.UND_ERR_REDIRECT_MAX') +class MaxRedirectsError extends UndiciError { + constructor (message) { + super(message) + this.name = 'MaxRedirectsError' + this.message = message || 'max redirects' + this.code = 'UND_ERR_REDIRECT_MAX' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kMaxRedirectsError] === true + } + + get [kMaxRedirectsError] () { + return true + } +} + +const kMaxOriginsReachedError = Symbol.for('undici.error.UND_ERR_MAX_ORIGINS_REACHED') +class MaxOriginsReachedError extends UndiciError { + constructor (message) { + super(message) + this.name = 'MaxOriginsReachedError' + this.message = message || 'Maximum allowed origins reached' + this.code = 'UND_ERR_MAX_ORIGINS_REACHED' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kMaxOriginsReachedError] === true + } + + get [kMaxOriginsReachedError] () { + return true + } +} + +class Socks5ProxyError extends UndiciError { + constructor (message, code) { + super(message) + this.name = 'Socks5ProxyError' + this.message = message || 'SOCKS5 proxy error' + this.code = code || 'UND_ERR_SOCKS5' + } +} + +const kMessageSizeExceededError = Symbol.for('undici.error.UND_ERR_WS_MESSAGE_SIZE_EXCEEDED') +class MessageSizeExceededError extends UndiciError { + constructor (message) { + super(message) + this.name = 'MessageSizeExceededError' + this.message = message || 'Max decompressed message size exceeded' + this.code = 'UND_ERR_WS_MESSAGE_SIZE_EXCEEDED' + } + + static [Symbol.hasInstance] (instance) { + return instance && instance[kMessageSizeExceededError] === true + } + + get [kMessageSizeExceededError] () { + return true + } +} + +module.exports = { + AbortError, + WebAssemblyNotSupportedError, + HTTPParserError, + UndiciError, + HeadersTimeoutError, + HeadersOverflowError, + BodyTimeoutError, + RequestContentLengthMismatchError, + ConnectTimeoutError, + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + ClientDestroyedError, + ClientClosedError, + InformationalError, + SocketError, + NotSupportedError, + ResponseContentLengthMismatchError, + BalancedPoolMissingUpstreamError, + ResponseExceededMaxSizeError, + RequestRetryError, + ResponseError, + SecureProxyConnectionError, + ProxyConnectionError, + MaxOriginsReachedError, + MaxRedirectsError, + Socks5ProxyError, + MessageSizeExceededError +} + + +/***/ }), + +/***/ 4655: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + InvalidArgumentError, + NotSupportedError +} = __nccwpck_require__(8707) +const assert = __nccwpck_require__(4589) +const { + isValidHTTPToken, + isValidHeaderValue, + isStream, + destroy, + isBuffer, + isFormDataLike, + isIterable, + hasSafeIterator, + isBlobLike, + serializePathWithQuery, + parseHeaders, + assertRequestHandler, + getServerName, + normalizedMethodRecords, + getProtocolFromUrlString +} = __nccwpck_require__(3440) +const { channels } = __nccwpck_require__(2414) +const { headerNameLowerCasedRecord } = __nccwpck_require__(735) + +// Verifies that a given path is valid does not contain control chars \x00 to \x20 +const invalidPathRegex = /[^\u0021-\u00ff]/ + +function isValidContentLengthHeaderValue (val) { + if (typeof val !== 'string' || val.length === 0) { + return false + } + + for (let i = 0; i < val.length; i++) { + const charCode = val.charCodeAt(i) + if (charCode < 48 || charCode > 57) { + return false + } + } + + return true +} + +const kHandler = Symbol('handler') +const kController = Symbol('controller') +const kResume = Symbol('resume') + +class RequestController { + #paused = false + #reason = null + #aborted = false + #abort + + [kResume] = null + + rawHeaders = null + rawTrailers = null + + constructor (abort) { + this.#abort = abort + } + + pause () { + this.#paused = true + } + + resume () { + if (this.#paused) { + this.#paused = false + this[kResume]?.() + } + } + + abort (reason) { + if (!this.#aborted) { + this.#aborted = true + this.#reason = reason + this.#abort(reason) + } + } + + get aborted () { + return this.#aborted + } + + get reason () { + return this.#reason + } + + get paused () { + return this.#paused + } +} + +class Request { + constructor (origin, { + path, + method, + body, + headers, + query, + idempotent, + blocking, + upgrade, + headersTimeout, + bodyTimeout, + reset, + expectContinue, + servername, + throwOnError, + maxRedirections, + typeOfService + }, handler) { + if (typeof path !== 'string') { + throw new InvalidArgumentError('path must be a string') + } else if ( + path[0] !== '/' && + !(path.startsWith('http://') || path.startsWith('https://')) && + method !== 'CONNECT' + ) { + throw new InvalidArgumentError('path must be an absolute URL or start with a slash') + } else if (invalidPathRegex.test(path)) { + throw new InvalidArgumentError('invalid request path') + } + + if (typeof method !== 'string') { + throw new InvalidArgumentError('method must be a string') + } else if (normalizedMethodRecords[method] === undefined && !isValidHTTPToken(method)) { + throw new InvalidArgumentError('invalid request method') + } + + if (upgrade && typeof upgrade !== 'string') { + throw new InvalidArgumentError('upgrade must be a string') + } + + if (upgrade && !isValidHeaderValue(upgrade)) { + throw new InvalidArgumentError('invalid upgrade header') + } + + if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('invalid headersTimeout') + } + + if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('invalid bodyTimeout') + } + + if (reset != null && typeof reset !== 'boolean') { + throw new InvalidArgumentError('invalid reset') + } + + if (expectContinue != null && typeof expectContinue !== 'boolean') { + throw new InvalidArgumentError('invalid expectContinue') + } + + if (throwOnError != null) { + throw new InvalidArgumentError('invalid throwOnError') + } + + if (maxRedirections != null && maxRedirections !== 0) { + throw new InvalidArgumentError('maxRedirections is not supported, use the redirect interceptor') + } + + if (typeOfService != null && (!Number.isInteger(typeOfService) || typeOfService < 0 || typeOfService > 255)) { + throw new InvalidArgumentError('typeOfService must be an integer between 0 and 255') + } + + this.headersTimeout = headersTimeout + + this.bodyTimeout = bodyTimeout + + this.method = method + + this.typeOfService = typeOfService + + this.abort = null + + if (body == null) { + this.body = null + } else if (isStream(body)) { + this.body = body + + const rState = this.body._readableState + if (!rState || !rState.autoDestroy) { + this.endHandler = function autoDestroy () { + destroy(this) + } + this.body.on('end', this.endHandler) + } + + this.errorHandler = err => { + if (this.abort) { + this.abort(err) + } else { + this.error = err + } + } + this.body.on('error', this.errorHandler) + } else if (isBuffer(body)) { + this.body = body.byteLength ? body : null + } else if (ArrayBuffer.isView(body)) { + this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null + } else if (body instanceof ArrayBuffer) { + this.body = body.byteLength ? Buffer.from(body) : null + } else if (typeof body === 'string') { + this.body = body.length ? Buffer.from(body) : null + } else if (isFormDataLike(body)) { + if (!isUndiciFormData(body)) { + throw new InvalidArgumentError('body must be a FormData created by this undici package instance; FormData from other sources, such as the built-in FormData provided by Node.js, is not supported') + } + this.body = body + } else if (isIterable(body) || isBlobLike(body)) { + this.body = body + } else { + throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') + } + + this.completed = false + this.aborted = false + + this.upgrade = upgrade || null + + this.path = query ? serializePathWithQuery(path, query) : path + + // TODO: shall we maybe standardize it to an URL object? + this.origin = origin + + this.protocol = getProtocolFromUrlString(origin) + + this.idempotent = idempotent == null + ? method === 'HEAD' || method === 'GET' || method === 'QUERY' + : idempotent + + this.blocking = blocking ?? this.method !== 'HEAD' + + this.reset = reset == null ? null : reset + + this.host = null + + this.contentLength = null + + this.contentType = null + + this.headers = [] + + // Only for H2 + this.expectContinue = expectContinue != null ? expectContinue : false + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(this, headers[i], headers[i + 1]) + } + } else if (headers && typeof headers === 'object') { + if (hasSafeIterator(headers)) { + for (const header of headers) { + if (!Array.isArray(header) || header.length !== 2) { + throw new InvalidArgumentError('headers must be in key-value pair format') + } + processHeader(this, header[0], header[1]) + } + } else { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; ++i) { + processHeader(this, keys[i], headers[keys[i]]) + } + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') + } + + assertRequestHandler(handler, method, upgrade) + + this.servername = servername || getServerName(this.host) || null + + this[kHandler] = handler + + if (channels.create.hasSubscribers) { + channels.create.publish({ request: this }) + } + } + + onBodySent (chunk) { + if (channels.bodyChunkSent.hasSubscribers) { + channels.bodyChunkSent.publish({ request: this, chunk }) + } + if (this[kHandler].onBodySent) { + try { + return this[kHandler].onBodySent(chunk) + } catch (err) { + this.abort(err) + } + } + } + + onRequestSent () { + if (channels.bodySent.hasSubscribers) { + channels.bodySent.publish({ request: this }) + } + + if (this[kHandler].onRequestSent) { + try { + return this[kHandler].onRequestSent() + } catch (err) { + this.abort(err) + } + } + } + + onRequestStart (abort, context) { + assert(!this.aborted) + assert(!this.completed) + + this[kController] = new RequestController(abort) + + if (this.error) { + this[kController].abort(this.error) + return + } + + this.abort = abort + return this[kHandler].onRequestStart(this[kController], context) + } + + onResponseStarted () { + return this[kHandler].onResponseStarted?.() + } + + onResponseStart (statusCode, headers, resume, statusText) { + assert(!this.aborted) + assert(!this.completed) + + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + } + + const controller = this[kController] + if (controller) { + controller[kResume] = resume + controller.rawHeaders = headers + } + + const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers + + try { + this[kHandler].onResponseStart?.(controller, statusCode, parsedHeaders, statusText) + return !controller?.paused + } catch (err) { + this.abort(err) + return false + } + } + + onResponseData (chunk) { + assert(!this.aborted) + assert(!this.completed) + + if (channels.bodyChunkReceived.hasSubscribers) { + channels.bodyChunkReceived.publish({ request: this, chunk }) + } + + const controller = this[kController] + try { + this[kHandler].onResponseData?.(controller, chunk) + return !controller?.paused + } catch (err) { + this.abort(err) + return false + } + } + + /** + * @param {number} statusCode + * @param {Buffer[]|string[]|import('../../types/header.d.ts').IncomingHttpHeaders} headers + * @param {import('node:stream').Duplex} socket + * @param {string} [statusText] + */ + onRequestUpgrade (statusCode, headers, socket, statusText = '') { + this.onFinally() + + assert(!this.aborted) + assert(!this.completed) + + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + } + + const controller = this[kController] + if (controller) { + controller.rawHeaders = headers + } + + const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers + + const result = this[kHandler].onRequestUpgrade?.(controller, statusCode, parsedHeaders, socket) + + if (!this.aborted) { + this.completed = true + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers: [] }) + } + } + + return result + } + + onResponseEnd (trailers) { + this.onFinally() + + assert(!this.aborted) + assert(!this.completed) + + this.completed = true + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers }) + } + + const controller = this[kController] + if (controller) { + controller.rawTrailers = trailers + } + + const parsedTrailers = Array.isArray(trailers) ? parseHeaders(trailers) : trailers + + try { + return this[kHandler].onResponseEnd?.(controller, parsedTrailers) + } catch (err) { + // TODO (fix): This might be a bad idea? + this.onResponseError(err) + } + } + + onResponseError (error) { + this.onFinally() + + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error }) + } + + if (this.aborted) { + return + } + this.aborted = true + + const controller = this[kController] + + return this[kHandler].onResponseError?.(controller, error) + } + + onFinally () { + if (this.errorHandler) { + this.body.off('error', this.errorHandler) + this.errorHandler = null + } + + if (this.endHandler) { + this.body.off('end', this.endHandler) + this.endHandler = null + } + } + + addHeader (key, value) { + processHeader(this, key, value) + return this + } +} + +function processHeader (request, key, val) { + if (val && (typeof val === 'object' && !Array.isArray(val))) { + throw new InvalidArgumentError(`invalid ${key} header`) + } else if (val === undefined) { + return + } + + let headerName = headerNameLowerCasedRecord[key] + + if (headerName === undefined) { + headerName = key.toLowerCase() + if (headerNameLowerCasedRecord[headerName] === undefined && !isValidHTTPToken(headerName)) { + throw new InvalidArgumentError('invalid header key') + } + } + + if (Array.isArray(val)) { + const arr = [] + for (let i = 0; i < val.length; i++) { + if (typeof val[i] === 'string') { + if (!isValidHeaderValue(val[i])) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + arr.push(val[i]) + } else if (val[i] === null) { + arr.push('') + } else if (typeof val[i] === 'object') { + throw new InvalidArgumentError(`invalid ${key} header`) + } else { + // Coerce primitives (and reject unsafe coercions such as functions + // with a crafted toString/Symbol.toPrimitive). + const str = `${val[i]}` + if (!isValidHeaderValue(str)) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + arr.push(str) + } + } + val = arr + } else if (typeof val === 'string') { + if (!isValidHeaderValue(val)) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + } else if (val === null) { + val = '' + } else { + // Coerce primitives (and reject unsafe coercions such as functions + // with a crafted toString/Symbol.toPrimitive). + val = `${val}` + if (!isValidHeaderValue(val)) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + } + + if (headerName === 'host') { + if (request.host !== null) { + throw new InvalidArgumentError('duplicate host header') + } + if (typeof val !== 'string') { + throw new InvalidArgumentError('invalid host header') + } + // Consumed by Client + request.host = val + } else if (headerName === 'content-length') { + if (request.contentLength !== null) { + throw new InvalidArgumentError('duplicate content-length header') + } + if (!isValidContentLengthHeaderValue(val)) { + throw new InvalidArgumentError('invalid content-length header') + } + request.contentLength = parseInt(val, 10) + } else if (request.contentType === null && headerName === 'content-type') { + request.contentType = val + request.headers.push(key, val) + } else if (headerName === 'transfer-encoding' || headerName === 'keep-alive' || headerName === 'upgrade') { + throw new InvalidArgumentError(`invalid ${headerName} header`) + } else if (headerName === 'connection') { + // Per RFC 7230 Section 6.1, Connection header can contain + // a comma-separated list of connection option tokens (header names) + const value = typeof val === 'string' ? val : null + if (value === null) { + throw new InvalidArgumentError('invalid connection header') + } + + for (const token of value.toLowerCase().split(',')) { + const trimmed = token.trim() + if (!isValidHTTPToken(trimmed)) { + throw new InvalidArgumentError('invalid connection header') + } + if (trimmed === 'close') { + request.reset = true + } + } + } else if (headerName === 'expect') { + throw new NotSupportedError('expect header not supported') + } else { + request.headers.push(key, val) + } +} + +let isFormData + +function isUndiciFormData (body) { + if (isFormData === undefined) { + __nccwpck_require__(5910) + isFormData = (__nccwpck_require__(7879).webidl).is.FormData + } + return isFormData(body) +} + +module.exports = Request + + +/***/ }), + +/***/ 8082: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { EventEmitter } = __nccwpck_require__(8474) +const { Buffer } = __nccwpck_require__(4573) +const { InvalidArgumentError, Socks5ProxyError } = __nccwpck_require__(8707) +const { debuglog } = __nccwpck_require__(7975) +const { parseAddress } = __nccwpck_require__(1732) + +const debug = debuglog('undici:socks5') +const EMPTY_BUFFER = Buffer.alloc(0) + +// SOCKS5 constants +const SOCKS_VERSION = 0x05 + +// Authentication methods +const AUTH_METHODS = { + NO_AUTH: 0x00, + GSSAPI: 0x01, + USERNAME_PASSWORD: 0x02, + NO_ACCEPTABLE: 0xFF +} + +// SOCKS5 commands +const COMMANDS = { + CONNECT: 0x01, + BIND: 0x02, + UDP_ASSOCIATE: 0x03 +} + +// Address types +const ADDRESS_TYPES = { + IPV4: 0x01, + DOMAIN: 0x03, + IPV6: 0x04 +} + +// Reply codes +const REPLY_CODES = { + SUCCEEDED: 0x00, + GENERAL_FAILURE: 0x01, + CONNECTION_NOT_ALLOWED: 0x02, + NETWORK_UNREACHABLE: 0x03, + HOST_UNREACHABLE: 0x04, + CONNECTION_REFUSED: 0x05, + TTL_EXPIRED: 0x06, + COMMAND_NOT_SUPPORTED: 0x07, + ADDRESS_TYPE_NOT_SUPPORTED: 0x08 +} + +// State machine states +const STATES = { + INITIAL: 'initial', + HANDSHAKING: 'handshaking', + AUTHENTICATING: 'authenticating', + AUTHENTICATED: 'authenticated', + CONNECTING: 'connecting', + CONNECTED: 'connected', + ERROR: 'error', + CLOSED: 'closed' +} + +/** + * SOCKS5 client implementation + * Handles SOCKS5 protocol negotiation and connection establishment + */ +class Socks5Client extends EventEmitter { + constructor (socket, options = {}) { + super() + + if (!socket) { + throw new InvalidArgumentError('socket is required') + } + + this.socket = socket + this.options = options + this.state = STATES.INITIAL + this.buffer = EMPTY_BUFFER + this.onSocketData = this.onData.bind(this) + this.onSocketError = this.onError.bind(this) + this.onSocketClose = this.onClose.bind(this) + + // Authentication settings + this.authMethods = [] + if (options.username && options.password) { + this.authMethods.push(AUTH_METHODS.USERNAME_PASSWORD) + } + this.authMethods.push(AUTH_METHODS.NO_AUTH) + + // Socket event handlers + this.socket.on('data', this.onSocketData) + this.socket.on('error', this.onSocketError) + this.socket.on('close', this.onSocketClose) + } + + /** + * Handle incoming data from the socket + */ + onData (data) { + debug('received data', data.length, 'bytes in state', this.state) + this.buffer = Buffer.concat([this.buffer, data]) + + try { + switch (this.state) { + case STATES.HANDSHAKING: + this.handleHandshakeResponse() + break + case STATES.AUTHENTICATING: + this.handleAuthResponse() + break + case STATES.CONNECTING: + this.handleConnectResponse() + break + } + } catch (err) { + this.onError(err) + } + } + + /** + * Handle socket errors + */ + onError (err) { + debug('socket error', err) + this.state = STATES.ERROR + this.emit('error', err) + this.destroy() + } + + /** + * Handle socket close + */ + onClose () { + debug('socket closed') + this.state = STATES.CLOSED + this.emit('close') + } + + /** + * Destroy the client and underlying socket + */ + destroy () { + if (this.socket && !this.socket.destroyed) { + this.socket.destroy() + } + } + + markAuthenticated () { + this.state = STATES.AUTHENTICATED + this.emit('authenticated') + } + + /** + * Start the SOCKS5 handshake + */ + handshake () { + if (this.state !== STATES.INITIAL) { + throw new InvalidArgumentError('Handshake already started') + } + + debug('starting handshake with', this.authMethods.length, 'auth methods') + this.state = STATES.HANDSHAKING + + // Build handshake request + // +----+----------+----------+ + // |VER | NMETHODS | METHODS | + // +----+----------+----------+ + // | 1 | 1 | 1 to 255 | + // +----+----------+----------+ + const request = Buffer.alloc(2 + this.authMethods.length) + request[0] = SOCKS_VERSION + request[1] = this.authMethods.length + this.authMethods.forEach((method, i) => { + request[2 + i] = method + }) + + this.socket.write(request) + } + + /** + * Handle handshake response from server + */ + handleHandshakeResponse () { + if (this.buffer.length < 2) { + return // Not enough data yet + } + + const version = this.buffer[0] + const method = this.buffer[1] + + if (version !== SOCKS_VERSION) { + throw new Socks5ProxyError(`Invalid SOCKS version: ${version}`, 'UND_ERR_SOCKS5_VERSION') + } + + if (method === AUTH_METHODS.NO_ACCEPTABLE) { + throw new Socks5ProxyError('No acceptable authentication method', 'UND_ERR_SOCKS5_AUTH_REJECTED') + } + + this.buffer = this.buffer.subarray(2) + debug('server selected auth method', method) + + if (method === AUTH_METHODS.NO_AUTH) { + this.markAuthenticated() + } else if (method === AUTH_METHODS.USERNAME_PASSWORD) { + this.state = STATES.AUTHENTICATING + this.sendAuthRequest() + } else { + throw new Socks5ProxyError(`Unsupported authentication method: ${method}`, 'UND_ERR_SOCKS5_AUTH_METHOD') + } + } + + /** + * Send username/password authentication request + */ + sendAuthRequest () { + const { username, password } = this.options + + if (!username || !password) { + throw new InvalidArgumentError('Username and password required for authentication') + } + + debug('sending username/password auth') + + // Username/Password authentication request (RFC 1929) + // +----+------+----------+------+----------+ + // |VER | ULEN | UNAME | PLEN | PASSWD | + // +----+------+----------+------+----------+ + // | 1 | 1 | 1 to 255 | 1 | 1 to 255 | + // +----+------+----------+------+----------+ + const usernameBuffer = Buffer.from(username) + const passwordBuffer = Buffer.from(password) + + if (usernameBuffer.length > 255 || passwordBuffer.length > 255) { + throw new InvalidArgumentError('Username or password too long') + } + + const request = Buffer.alloc(3 + usernameBuffer.length + passwordBuffer.length) + request[0] = 0x01 // Sub-negotiation version + request[1] = usernameBuffer.length + usernameBuffer.copy(request, 2) + request[2 + usernameBuffer.length] = passwordBuffer.length + passwordBuffer.copy(request, 3 + usernameBuffer.length) + + this.socket.write(request) + } + + /** + * Handle authentication response + */ + handleAuthResponse () { + if (this.buffer.length < 2) { + return // Not enough data yet + } + + const version = this.buffer[0] + const status = this.buffer[1] + + if (version !== 0x01) { + throw new Socks5ProxyError(`Invalid auth sub-negotiation version: ${version}`, 'UND_ERR_SOCKS5_AUTH_VERSION') + } + + if (status !== 0x00) { + throw new Socks5ProxyError('Authentication failed', 'UND_ERR_SOCKS5_AUTH_FAILED') + } + + this.buffer = this.buffer.subarray(2) + debug('authentication successful') + this.markAuthenticated() + } + + /** + * Send CONNECT command + * @param {string} address - Target address (IP or domain) + * @param {number} port - Target port + */ + connect (address, port) { + if (this.state === STATES.CONNECTING || this.state === STATES.CONNECTED) { + throw new InvalidArgumentError('Connection already in progress') + } + + if (this.state !== STATES.AUTHENTICATED) { + throw new InvalidArgumentError('Client must be authenticated before CONNECT') + } + + debug('connecting to', address, port) + this.state = STATES.CONNECTING + + const request = this.buildConnectRequest(COMMANDS.CONNECT, address, port) + this.socket.write(request) + } + + /** + * Build a SOCKS5 request + */ + buildConnectRequest (command, address, port) { + // Parse address to determine type and buffer + const { type: addressType, buffer: addressBuffer } = parseAddress(address) + + // Build request + // +----+-----+-------+------+----------+----------+ + // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | + // +----+-----+-------+------+----------+----------+ + // | 1 | 1 | X'00' | 1 | Variable | 2 | + // +----+-----+-------+------+----------+----------+ + const request = Buffer.alloc(4 + addressBuffer.length + 2) + request[0] = SOCKS_VERSION + request[1] = command + request[2] = 0x00 // Reserved + request[3] = addressType + addressBuffer.copy(request, 4) + request.writeUInt16BE(port, 4 + addressBuffer.length) + + return request + } + + /** + * Handle CONNECT response + */ + handleConnectResponse () { + if (this.buffer.length < 4) { + return // Not enough data for header + } + + const version = this.buffer[0] + const reply = this.buffer[1] + const addressType = this.buffer[3] + + if (version !== SOCKS_VERSION) { + throw new Socks5ProxyError(`Invalid SOCKS version in reply: ${version}`, 'UND_ERR_SOCKS5_REPLY_VERSION') + } + + // Calculate the expected response length + let responseLength = 4 // VER + REP + RSV + ATYP + if (addressType === ADDRESS_TYPES.IPV4) { + responseLength += 4 + 2 // IPv4 + port + } else if (addressType === ADDRESS_TYPES.DOMAIN) { + if (this.buffer.length < 5) { + return // Need domain length byte + } + responseLength += 1 + this.buffer[4] + 2 // length byte + domain + port + } else if (addressType === ADDRESS_TYPES.IPV6) { + responseLength += 16 + 2 // IPv6 + port + } else { + throw new Socks5ProxyError(`Invalid address type in reply: ${addressType}`, 'UND_ERR_SOCKS5_ADDR_TYPE') + } + + if (this.buffer.length < responseLength) { + return // Not enough data for full response + } + + if (reply !== REPLY_CODES.SUCCEEDED) { + const errorMessage = this.getReplyErrorMessage(reply) + throw new Socks5ProxyError(`SOCKS5 connection failed: ${errorMessage}`, `UND_ERR_SOCKS5_REPLY_${reply}`) + } + + // Parse bound address and port + let boundAddress + let offset = 4 + + if (addressType === ADDRESS_TYPES.IPV4) { + boundAddress = Array.from(this.buffer.subarray(offset, offset + 4)).join('.') + offset += 4 + } else if (addressType === ADDRESS_TYPES.DOMAIN) { + const domainLength = this.buffer[offset] + offset += 1 + boundAddress = this.buffer.subarray(offset, offset + domainLength).toString() + offset += domainLength + } else if (addressType === ADDRESS_TYPES.IPV6) { + // Parse IPv6 address from 16-byte buffer + const parts = [] + for (let i = 0; i < 8; i++) { + const value = this.buffer.readUInt16BE(offset + i * 2) + parts.push(value.toString(16)) + } + boundAddress = parts.join(':') + offset += 16 + } + + const boundPort = this.buffer.readUInt16BE(offset) + + this.buffer = EMPTY_BUFFER + this.state = STATES.CONNECTED + this.socket.removeListener('data', this.onSocketData) + + debug('connected, bound address:', boundAddress, 'port:', boundPort) + this.emit('connected', { address: boundAddress, port: boundPort }) + } + + /** + * Get human-readable error message for reply code + */ + getReplyErrorMessage (reply) { + switch (reply) { + case REPLY_CODES.GENERAL_FAILURE: + return 'General SOCKS server failure' + case REPLY_CODES.CONNECTION_NOT_ALLOWED: + return 'Connection not allowed by ruleset' + case REPLY_CODES.NETWORK_UNREACHABLE: + return 'Network unreachable' + case REPLY_CODES.HOST_UNREACHABLE: + return 'Host unreachable' + case REPLY_CODES.CONNECTION_REFUSED: + return 'Connection refused' + case REPLY_CODES.TTL_EXPIRED: + return 'TTL expired' + case REPLY_CODES.COMMAND_NOT_SUPPORTED: + return 'Command not supported' + case REPLY_CODES.ADDRESS_TYPE_NOT_SUPPORTED: + return 'Address type not supported' + default: + return `Unknown error code: ${reply}` + } + } +} + +module.exports = { + Socks5Client, + AUTH_METHODS, + COMMANDS, + ADDRESS_TYPES, + REPLY_CODES, + STATES +} + + +/***/ }), + +/***/ 1732: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { Buffer } = __nccwpck_require__(4573) +const net = __nccwpck_require__(7030) +const { InvalidArgumentError } = __nccwpck_require__(8707) + +/** + * Parse an address and determine its type + * @param {string} address - The address to parse + * @returns {{type: number, buffer: Buffer}} Address type and buffer + */ +function parseAddress (address) { + // Check if it's an IPv4 address + if (net.isIPv4(address)) { + const parts = address.split('.').map(Number) + return { + type: 0x01, // IPv4 + buffer: Buffer.from(parts) + } + } + + // Check if it's an IPv6 address + if (net.isIPv6(address)) { + return { + type: 0x04, // IPv6 + buffer: parseIPv6(address) + } + } + + // Otherwise, treat as domain name + const domainBuffer = Buffer.from(address, 'utf8') + if (domainBuffer.length > 255) { + throw new InvalidArgumentError('Domain name too long (max 255 bytes)') + } + + return { + type: 0x03, // Domain + buffer: Buffer.concat([Buffer.from([domainBuffer.length]), domainBuffer]) + } +} + +/** + * Parse IPv6 address to buffer + * @param {string} address - IPv6 address string + * @returns {Buffer} 16-byte buffer + */ +function parseIPv6 (address) { + const buffer = Buffer.alloc(16) + let normalizedAddress = address + + // Expand an embedded IPv4 tail into the last two IPv6 groups. + if (address.includes('.')) { + const lastColonIndex = address.lastIndexOf(':') + const ipv4Part = address.slice(lastColonIndex + 1) + + if (net.isIPv4(ipv4Part)) { + const octets = ipv4Part.split('.').map(Number) + const high = ((octets[0] << 8) | octets[1]).toString(16) + const low = ((octets[2] << 8) | octets[3]).toString(16) + normalizedAddress = `${address.slice(0, lastColonIndex)}:${high}:${low}` + } + } + + // Handle compressed notation (::) + const doubleColonIndex = normalizedAddress.indexOf('::') + if (doubleColonIndex !== -1) { + const before = normalizedAddress.slice(0, doubleColonIndex) + const after = normalizedAddress.slice(doubleColonIndex + 2) + const beforeParts = before === '' ? [] : before.split(':') + const afterParts = after === '' ? [] : after.split(':') + + let bufferIndex = 0 + for (const part of beforeParts) { + buffer.writeUInt16BE(parseInt(part, 16), bufferIndex) + bufferIndex += 2 + } + bufferIndex = 16 - afterParts.length * 2 + for (const part of afterParts) { + buffer.writeUInt16BE(parseInt(part, 16), bufferIndex) + bufferIndex += 2 + } + } else { + const parts = normalizedAddress.split(':') + for (let i = 0; i < parts.length; i++) { + buffer.writeUInt16BE(parseInt(parts[i], 16), i * 2) + } + } + + return buffer +} + +/** + * Build a SOCKS5 address buffer + * @param {number} type - Address type (1=IPv4, 3=Domain, 4=IPv6) + * @param {Buffer} addressBuffer - The address data + * @param {number} port - Port number + * @returns {Buffer} Complete address buffer including type, address, and port + */ +function buildAddressBuffer (type, addressBuffer, port) { + const portBuffer = Buffer.allocUnsafe(2) + portBuffer.writeUInt16BE(port, 0) + + return Buffer.concat([ + Buffer.from([type]), + addressBuffer, + portBuffer + ]) +} + +/** + * Parse address from SOCKS5 response + * @param {Buffer} buffer - Buffer containing the address + * @param {number} offset - Starting offset in buffer + * @returns {{address: string, port: number, bytesRead: number}} + */ +function parseResponseAddress (buffer, offset = 0) { + if (buffer.length < offset + 1) { + throw new InvalidArgumentError('Buffer too small to contain address type') + } + + const addressType = buffer[offset] + let address + let currentOffset = offset + 1 + + switch (addressType) { + case 0x01: { // IPv4 + if (buffer.length < currentOffset + 6) { + throw new InvalidArgumentError('Buffer too small for IPv4 address') + } + address = Array.from(buffer.subarray(currentOffset, currentOffset + 4)).join('.') + currentOffset += 4 + break + } + + case 0x03: { // Domain + if (buffer.length < currentOffset + 1) { + throw new InvalidArgumentError('Buffer too small for domain length') + } + const domainLength = buffer[currentOffset] + currentOffset += 1 + + if (buffer.length < currentOffset + domainLength + 2) { + throw new InvalidArgumentError('Buffer too small for domain address') + } + address = buffer.subarray(currentOffset, currentOffset + domainLength).toString('utf8') + currentOffset += domainLength + break + } + + case 0x04: { // IPv6 + if (buffer.length < currentOffset + 18) { + throw new InvalidArgumentError('Buffer too small for IPv6 address') + } + // Convert buffer to IPv6 string + const parts = [] + for (let i = 0; i < 8; i++) { + const value = buffer.readUInt16BE(currentOffset + i * 2) + parts.push(value.toString(16)) + } + address = parts.join(':') + currentOffset += 16 + break + } + + default: + throw new InvalidArgumentError(`Invalid address type: ${addressType}`) + } + + // Parse port + if (buffer.length < currentOffset + 2) { + throw new InvalidArgumentError('Buffer too small for port') + } + const port = buffer.readUInt16BE(currentOffset) + currentOffset += 2 + + return { + address, + port, + bytesRead: currentOffset - offset + } +} + +/** + * Create error for SOCKS5 reply code + * @param {number} replyCode - SOCKS5 reply code + * @returns {Error} Appropriate error object + */ +function createReplyError (replyCode) { + const messages = { + 0x01: 'General SOCKS server failure', + 0x02: 'Connection not allowed by ruleset', + 0x03: 'Network unreachable', + 0x04: 'Host unreachable', + 0x05: 'Connection refused', + 0x06: 'TTL expired', + 0x07: 'Command not supported', + 0x08: 'Address type not supported' + } + + const message = messages[replyCode] || `Unknown SOCKS5 error code: ${replyCode}` + const error = new Error(message) + error.code = `SOCKS5_${replyCode}` + return error +} + +module.exports = { + parseAddress, + parseIPv6, + buildAddressBuffer, + parseResponseAddress, + createReplyError +} + + +/***/ }), + +/***/ 6443: +/***/ ((module) => { + +"use strict"; + + +module.exports = { + kClose: Symbol('close'), + kDestroy: Symbol('destroy'), + kDispatch: Symbol('dispatch'), + kUrl: Symbol('url'), + kRequestOrigin: Symbol('request origin'), + kRedirectCacheControl: Symbol('redirect cache control'), + kOriginless: Symbol('originless'), + kWriting: Symbol('writing'), + kResuming: Symbol('resuming'), + kQueue: Symbol('queue'), + kConnect: Symbol('connect'), + kConnecting: Symbol('connecting'), + kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), + kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), + kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), + kKeepAliveTimeoutValue: Symbol('keep alive timeout'), + kKeepAlive: Symbol('keep alive'), + kHeadersTimeout: Symbol('headers timeout'), + kBodyTimeout: Symbol('body timeout'), + kServerName: Symbol('server name'), + kLocalAddress: Symbol('local address'), + kHost: Symbol('host'), + kNoRef: Symbol('no ref'), + kBodyUsed: Symbol('used'), + kBody: Symbol('abstracted request body'), + kRunning: Symbol('running'), + kBlocking: Symbol('blocking'), + kPending: Symbol('pending'), + kSize: Symbol('size'), + kBusy: Symbol('busy'), + kQueued: Symbol('queued'), + kFree: Symbol('free'), + kConnected: Symbol('connected'), + kClosed: Symbol('closed'), + kNeedDrain: Symbol('need drain'), + kReset: Symbol('reset'), + kDestroyed: Symbol.for('nodejs.stream.destroyed'), + kResume: Symbol('resume'), + kOnError: Symbol('on error'), + kMaxHeadersSize: Symbol('max headers size'), + kRunningIdx: Symbol('running index'), + kPendingIdx: Symbol('pending index'), + kError: Symbol('error'), + kClients: Symbol('clients'), + kClient: Symbol('client'), + kParser: Symbol('parser'), + kOnDestroyed: Symbol('destroy callbacks'), + kPipelining: Symbol('pipelining'), + kSocket: Symbol('socket'), + kHostHeader: Symbol('host header'), + kConnector: Symbol('connector'), + kStrictContentLength: Symbol('strict content length'), + kMaxRedirections: Symbol('maxRedirections'), + kMaxRequests: Symbol('maxRequestsPerClient'), + kProxy: Symbol('proxy agent options'), + kCounter: Symbol('socket request counter'), + kMaxResponseSize: Symbol('max response size'), + kHTTP2Session: Symbol('http2Session'), + kHTTP2Options: Symbol('http2 options'), + kHTTP2SessionState: Symbol('http2Session state'), + kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), + kConstruct: Symbol('constructable'), + kListeners: Symbol('listeners'), + kHTTPContext: Symbol('http context'), + kMaxConcurrentStreams: Symbol('max concurrent streams'), + kHostAuthority: Symbol('host authority'), + kHTTP2InitialWindowSize: Symbol('http2 initial window size'), + kHTTP2ConnectionWindowSize: Symbol('http2 connection window size'), + kEnableConnectProtocol: Symbol('http2session connect protocol'), + kRemoteSettings: Symbol('http2session remote settings'), + kHTTP2Stream: Symbol('http2session client stream'), + kPingInterval: Symbol('ping interval'), + kUseMilo: Symbol('use milo'), + kNoProxyAgent: Symbol('no proxy agent'), + kHttpProxyAgent: Symbol('http proxy agent'), + kHttpsProxyAgent: Symbol('https proxy agent'), + kSocks5ProxyAgent: Symbol('socks5 proxy agent') +} + + +/***/ }), + +/***/ 7752: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + wellknownHeaderNames, + headerNameLowerCasedRecord +} = __nccwpck_require__(735) + +class TstNode { + /** @type {any} */ + value = null + /** @type {null | TstNode} */ + left = null + /** @type {null | TstNode} */ + middle = null + /** @type {null | TstNode} */ + right = null + /** @type {number} */ + code + /** + * @param {string} key + * @param {any} value + * @param {number} index + */ + constructor (key, value, index) { + if (index === undefined || index >= key.length) { + throw new TypeError('Unreachable') + } + const code = this.code = key.charCodeAt(index) + // check code is ascii string + if (code > 0x7F) { + throw new TypeError('key must be ascii string') + } + if (key.length !== ++index) { + this.middle = new TstNode(key, value, index) + } else { + this.value = value + } + } + + /** + * @param {string} key + * @param {any} value + * @returns {void} + */ + add (key, value) { + const length = key.length + if (length === 0) { + throw new TypeError('Unreachable') + } + let index = 0 + /** + * @type {TstNode} + */ + let node = this + while (true) { + const code = key.charCodeAt(index) + // check code is ascii string + if (code > 0x7F) { + throw new TypeError('key must be ascii string') + } + if (node.code === code) { + if (length === ++index) { + node.value = value + break + } else if (node.middle !== null) { + node = node.middle + } else { + node.middle = new TstNode(key, value, index) + break + } + } else if (node.code < code) { + if (node.left !== null) { + node = node.left + } else { + node.left = new TstNode(key, value, index) + break + } + } else if (node.right !== null) { + node = node.right + } else { + node.right = new TstNode(key, value, index) + break + } + } + } + + /** + * @param {Uint8Array} key + * @returns {TstNode | null} + */ + search (key) { + const keylength = key.length + let index = 0 + /** + * @type {TstNode|null} + */ + let node = this + while (node !== null && index < keylength) { + let code = key[index] + // A-Z + // First check if it is bigger than 0x5a. + // Lowercase letters have higher char codes than uppercase ones. + // Also we assume that headers will mostly contain lowercase characters. + if (code <= 0x5a && code >= 0x41) { + // Lowercase for uppercase. + code |= 32 + } + while (node !== null) { + if (code === node.code) { + if (keylength === ++index) { + // Returns Node since it is the last key. + return node + } + node = node.middle + break + } + node = node.code < code ? node.left : node.right + } + } + return null + } +} + +class TernarySearchTree { + /** @type {TstNode | null} */ + node = null + + /** + * @param {string} key + * @param {any} value + * @returns {void} + * */ + insert (key, value) { + if (this.node === null) { + this.node = new TstNode(key, value, 0) + } else { + this.node.add(key, value) + } + } + + /** + * @param {Uint8Array} key + * @returns {any} + */ + lookup (key) { + return this.node?.search(key)?.value ?? null + } +} + +const tree = new TernarySearchTree() + +for (let i = 0; i < wellknownHeaderNames.length; ++i) { + const key = headerNameLowerCasedRecord[wellknownHeaderNames[i]] + tree.insert(key, key) +} + +module.exports = { + TernarySearchTree, + tree +} + + +/***/ }), + +/***/ 3440: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(4589) +const { kDestroyed, kBodyUsed, kListeners, kBody } = __nccwpck_require__(6443) +const { IncomingMessage } = __nccwpck_require__(7067) +const stream = __nccwpck_require__(7075) +const net = __nccwpck_require__(7030) +const { stringify } = __nccwpck_require__(1792) +const { EventEmitter: EE, addAbortListener: addAbortListenerNative } = __nccwpck_require__(8474) +const timers = __nccwpck_require__(6603) +const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8707) +const { headerNameLowerCasedRecord } = __nccwpck_require__(735) +const { tree } = __nccwpck_require__(7752) + +class BodyAsyncIterable { + constructor (body) { + this[kBody] = body + this[kBodyUsed] = false + } + + async * [Symbol.asyncIterator] () { + assert(!this[kBodyUsed], 'disturbed') + this[kBodyUsed] = true + yield * this[kBody] + } +} + +function noop () {} + +/** + * @param {*} body + * @returns {*} + */ +function wrapRequestBody (body) { + if (isStream(body)) { + // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp + // so that it can be dispatched again? + // TODO (fix): Do we need 100-expect support to provide a way to do this properly? + if (bodyLength(body) === 0) { + body + .on('data', function () { + assert(false) + }) + } + + if (typeof body.readableDidRead !== 'boolean') { + body[kBodyUsed] = false + EE.prototype.on.call(body, 'data', function () { + this[kBodyUsed] = true + }) + } + + return body + } else if (body && typeof body.pipeTo === 'function') { + // TODO (fix): We can't access ReadableStream internal state + // to determine whether or not it has been disturbed. This is just + // a workaround. + return new BodyAsyncIterable(body) + } else if (body && isFormDataLike(body)) { + return body + } else if ( + body && + typeof body !== 'string' && + !ArrayBuffer.isView(body) && + isIterable(body) + ) { + // TODO: Should we allow re-using iterable if !this.opts.idempotent + // or through some other flag? + return new BodyAsyncIterable(body) + } else { + return body + } +} + +/** + * @param {*} obj + * @returns {obj is import('node:stream').Stream} + */ +function isStream (obj) { + return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' +} + +/** + * @param {*} object + * @returns {object is Blob} + */ +function isBlobLike (object) { + return object instanceof Blob +} + +/** + * @param {string} url The path to check for query strings or fragments. + * @returns {boolean} Returns true if the path contains a query string or fragment. + */ +function pathHasQueryOrFragment (url) { + return ( + url.includes('?') || + url.includes('#') + ) +} + +/** + * @param {string} url The URL to add the query params to + * @param {import('node:querystring').ParsedUrlQueryInput} queryParams The object to serialize into a URL query string + * @returns {string} The URL with the query params added + */ +function serializePathWithQuery (url, queryParams) { + if (pathHasQueryOrFragment(url)) { + throw new Error('Query params cannot be passed when url already contains "?" or "#".') + } + + const stringified = stringify(queryParams) + + if (stringified) { + url += '?' + stringified + } + + return url +} + +/** + * @param {number|string|undefined} port + * @returns {boolean} + */ +function isValidPort (port) { + const value = parseInt(port, 10) + return ( + value === Number(port) && + value >= 0 && + value <= 65535 + ) +} + +/** + * Check if the value is a valid http or https prefixed string. + * + * @param {string} value + * @returns {boolean} + */ +function isHttpOrHttpsPrefixed (value) { + return ( + value != null && + value[0] === 'h' && + value[1] === 't' && + value[2] === 't' && + value[3] === 'p' && + ( + value[4] === ':' || + ( + value[4] === 's' && + value[5] === ':' + ) + ) + ) +} + +/** + * @param {string|URL|Record} url + * @returns {URL} + */ +function parseURL (url) { + if (typeof url === 'string') { + /** + * @type {URL} + */ + url = new URL(url) + + if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + return url + } + + if (!url || typeof url !== 'object') { + throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') + } + + if (!(url instanceof URL)) { + if (url.port != null && url.port !== '' && isValidPort(url.port) === false) { + throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') + } + + if (url.path != null && typeof url.path !== 'string') { + throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') + } + + if (url.pathname != null && typeof url.pathname !== 'string') { + throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') + } + + if (url.hostname != null && typeof url.hostname !== 'string') { + throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') + } + + if (url.origin != null && typeof url.origin !== 'string') { + throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') + } + + if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + const port = url.port != null + ? url.port + : (url.protocol === 'https:' ? 443 : 80) + let origin = url.origin != null + ? url.origin + : `${url.protocol || ''}//${url.hostname || ''}:${port}` + let path = url.path != null + ? url.path + : `${url.pathname || ''}${url.search || ''}` + + if (origin[origin.length - 1] === '/') { + origin = origin.slice(0, origin.length - 1) + } + + if (path && path[0] !== '/') { + path = `/${path}` + } + // new URL(path, origin) is unsafe when `path` contains an absolute URL + // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: + // If first parameter is a relative URL, second param is required, and will be used as the base URL. + // If first parameter is an absolute URL, a given second param will be ignored. + return new URL(`${origin}${path}`) + } + + if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + return url +} + +/** + * @param {string|URL|Record} url + * @returns {URL} + */ +function parseOrigin (url) { + url = parseURL(url) + + if (url.pathname !== '/' || url.search || url.hash) { + throw new InvalidArgumentError('invalid url') + } + + return url +} + +/** + * @param {string} host + * @returns {string} + */ +function getHostname (host) { + if (host[0] === '[') { + const idx = host.indexOf(']') + + assert(idx !== -1) + return host.substring(1, idx) + } + + const idx = host.indexOf(':') + if (idx === -1) return host + + return host.substring(0, idx) +} + +/** + * IP addresses are not valid server names per RFC6066 + * Currently, the only server names supported are DNS hostnames + * @param {string|null} host + * @returns {string|null} + */ +function getServerName (host) { + if (!host) { + return null + } + + assert(typeof host === 'string') + + const servername = getHostname(host) + if (net.isIP(servername)) { + return '' + } + + return servername +} + +/** + * @function + * @template T + * @param {T} obj + * @returns {T} + */ +function deepClone (obj) { + return JSON.parse(JSON.stringify(obj)) +} + +/** + * @param {*} obj + * @returns {obj is AsyncIterable} + */ +function isAsyncIterable (obj) { + return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') +} + +/** + * @param {*} obj + * @returns {obj is Iterable} + */ +function isIterable (obj) { + return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) +} + +/** + * Checks whether an object has a safe Symbol.iterator — i.e. one that is + * either own or inherited from a non-Object.prototype chain. This prevents + * prototype-pollution attacks from injecting a fake iterator on + * Object.prototype. + * @param {object} obj + * @returns {boolean} + */ +function hasSafeIterator (obj) { + const prototype = Object.getPrototypeOf(obj) + const ownIterator = Object.hasOwn(obj, Symbol.iterator) + return ownIterator || (prototype != null && prototype !== Object.prototype && typeof obj[Symbol.iterator] === 'function') +} + +/** + * @param {Blob|Buffer|import ('stream').Stream} body + * @returns {number|null} + */ +function bodyLength (body) { + if (body == null) { + return 0 + } else if (isStream(body)) { + const state = body._readableState + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) + ? state.length + : null + } else if (isBlobLike(body)) { + return body.size != null ? body.size : null + } else if (isBuffer(body)) { + return body.byteLength + } + + return null +} + +/** + * @param {import ('stream').Stream} body + * @returns {boolean} + */ +function isDestroyed (body) { + return body && !!(body.destroyed || body[kDestroyed] || (stream.isDestroyed?.(body))) +} + +/** + * @param {import ('stream').Stream} stream + * @param {Error} [err] + * @returns {void} + */ +function destroy (stream, err) { + if (stream == null || !isStream(stream) || isDestroyed(stream)) { + return + } + + if (typeof stream.destroy === 'function') { + if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { + // See: https://github.com/nodejs/node/pull/38505/files + stream.socket = null + } + + try { + stream.destroy(err) + } catch { + // stream.destroy may throw on managed sockets (e.g., http2). + // Silently ignore — the socket lifecycle is handled by the subsystem. + } + } else if (err) { + queueMicrotask(() => { + stream.emit('error', err) + }) + } + + if (stream.destroyed !== true) { + stream[kDestroyed] = true + } +} + +const KEEPALIVE_TIMEOUT_EXPR = /(?:^|,)[\t ]*timeout=(\d+)/i +/** + * @param {string} val + * @returns {number | null} + */ +function parseKeepAliveTimeout (val) { + const m = val.match(KEEPALIVE_TIMEOUT_EXPR) + return m ? parseInt(m[1], 10) * 1000 : null +} + +/** + * Retrieves a header name and returns its lowercase value. + * @param {string | Buffer} value Header name + * @returns {string} + */ +function headerNameToString (value) { + return typeof value === 'string' + ? headerNameLowerCasedRecord[value] ?? value.toLowerCase() + : tree.lookup(value) ?? value.toString('latin1').toLowerCase() +} + +/** + * Receive the buffer as a string and return its lowercase value. + * @param {Buffer} value Header name + * @returns {string} + */ +function bufferToLowerCasedHeaderName (value) { + return tree.lookup(value) ?? value.toString('latin1').toLowerCase() +} + +/** + * Writes a header onto a plain object without going through the + * `Object.prototype` `__proto__` setter. Plain assignment there drops a string + * value and, when the value is an array, replaces the object's prototype + * instead of storing anything. Every other name is a normal assignment. + * + * @param {Record} obj Accumulator to write onto + * @param {string} key Header name + * @param {string | string[]} value Header value + * @returns {void} + */ +function setHeader (obj, key, value) { + if (key === '__proto__') { + Object.defineProperty(obj, key, { + value, + enumerable: true, + configurable: true, + writable: true + }) + } else { + obj[key] = value + } +} + +/** + * @param {(Buffer | string)[]} headers + * @param {Record} [obj] + * @returns {Record} + */ +function parseHeaders (headers, obj) { + if (obj === undefined) obj = {} + + for (let i = 0; i < headers.length; i += 2) { + const key = headerNameToString(headers[i]) + let val = obj[key] + + if (val !== undefined) { + if (!Object.hasOwn(obj, key)) { + const headersValue = typeof headers[i + 1] === 'string' + ? headers[i + 1] + : Array.isArray(headers[i + 1]) + ? headers[i + 1].map(x => x.toString('latin1')) + : headers[i + 1].toString('latin1') + + if (key === '__proto__') { + Object.defineProperty(obj, key, { + value: headersValue, + enumerable: true, + configurable: true, + writable: true + }) + } else { + obj[key] = headersValue + } + } else { + if (typeof val === 'string') { + val = [val] + obj[key] = val + } + val.push(headers[i + 1].toString('latin1')) + } + } else { + const headersValue = typeof headers[i + 1] === 'string' + ? headers[i + 1] + : Array.isArray(headers[i + 1]) + ? headers[i + 1].map(x => x.toString('latin1')) + : headers[i + 1].toString('latin1') + + obj[key] = headersValue + } + } + + return obj +} + +/** + * @param {Buffer[] | string[] | Record | null | undefined} headers + * @returns {string[]} + */ +function parseRawHeaders (headers) { + if (headers == null) { + return [] + } + + if (!Array.isArray(headers)) { + const rawHeaders = [] + + for (const [name, value] of Object.entries(headers)) { + if (Array.isArray(value)) { + for (const entry of value) { + rawHeaders.push(name, `${entry}`) + } + } else { + rawHeaders.push(name, `${value}`) + } + } + + return rawHeaders + } + + const headersLength = headers.length + /** + * @type {string[]} + */ + const ret = new Array(headersLength) + + let key + let val + + for (let n = 0; n < headersLength; n += 2) { + key = headers[n] + val = headers[n + 1] + + typeof key !== 'string' && (key = key.toString()) + typeof val !== 'string' && (val = val.toString('latin1')) + + ret[n] = key + ret[n + 1] = val + } + + return ret +} + +/** + * @param {Record} headers + * @returns {Buffer[]} + */ +function toRawHeaders (headers) { + const rawHeaders = [] + + for (const [name, value] of Object.entries(headers)) { + if (Array.isArray(value)) { + for (const entry of value) { + rawHeaders.push(Buffer.from(name, 'latin1'), Buffer.from(`${entry}`, 'latin1')) + } + } else { + rawHeaders.push(Buffer.from(name, 'latin1'), Buffer.from(`${value}`, 'latin1')) + } + } + + return rawHeaders +} + +/** + * @param {string[]} headers + * @param {Buffer[]} headers + */ +function encodeRawHeaders (headers) { + if (!Array.isArray(headers)) { + throw new TypeError('expected headers to be an array') + } + return headers.map(x => Buffer.from(x)) +} + +/** + * @param {*} buffer + * @returns {buffer is Buffer} + */ +function isBuffer (buffer) { + // See, https://github.com/mcollina/undici/pull/319 + return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) +} + +/** + * Asserts that the handler object is a request handler. + * + * @param {object} handler + * @param {string} method + * @param {string} [upgrade] + * @returns {asserts handler is import('../api/api-request').RequestHandler} + */ +function assertRequestHandler (handler, method, upgrade) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + if (typeof handler.onRequestStart !== 'function') { + throw new InvalidArgumentError('invalid onRequestStart method') + } + + if (typeof handler.onResponseError !== 'function') { + throw new InvalidArgumentError('invalid onResponseError method') + } + + if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { + throw new InvalidArgumentError('invalid onBodySent method') + } + + if (typeof handler.onRequestSent !== 'function' && handler.onRequestSent !== undefined) { + throw new InvalidArgumentError('invalid onRequestSent method') + } + + if (upgrade || method === 'CONNECT') { + if (typeof handler.onRequestUpgrade !== 'function') { + throw new InvalidArgumentError('invalid onRequestUpgrade method') + } + } else { + if (typeof handler.onResponseStart !== 'function') { + throw new InvalidArgumentError('invalid onResponseStart method') + } + + if (typeof handler.onResponseData !== 'function') { + throw new InvalidArgumentError('invalid onResponseData method') + } + + if (typeof handler.onResponseEnd !== 'function') { + throw new InvalidArgumentError('invalid onResponseEnd method') + } + } +} + +/** + * A body is disturbed if it has been read from and it cannot be re-used without + * losing state or data. + * @param {import('node:stream').Readable} body + * @returns {boolean} + */ +function isDisturbed (body) { + // TODO (fix): Why is body[kBodyUsed] needed? + return !!(body && (stream.isDisturbed(body) || body[kBodyUsed])) +} + +/** + * @typedef {object} SocketInfo + * @property {string} [localAddress] + * @property {number} [localPort] + * @property {string} [remoteAddress] + * @property {number} [remotePort] + * @property {string} [remoteFamily] + * @property {number} [timeout] + * @property {number} bytesWritten + * @property {number} bytesRead + */ + +/** + * @param {import('net').Socket} socket + * @returns {SocketInfo} + */ +function getSocketInfo (socket) { + return { + localAddress: socket.localAddress, + localPort: socket.localPort, + remoteAddress: socket.remoteAddress, + remotePort: socket.remotePort, + remoteFamily: socket.remoteFamily, + timeout: socket.timeout, + bytesWritten: socket.bytesWritten, + bytesRead: socket.bytesRead + } +} + +/** + * The object should be a FormData instance and contains all the required + * methods. + * @param {*} object + * @returns {object is FormData} + */ +function isFormDataLike (object) { + return ( + object && + typeof object === 'object' && + typeof object.append === 'function' && + typeof object.delete === 'function' && + typeof object.get === 'function' && + typeof object.getAll === 'function' && + typeof object.has === 'function' && + typeof object.set === 'function' && + object[Symbol.toStringTag] === 'FormData' + ) +} + +function addAbortListener (signal, listener) { + if (!signal || 'aborted' in signal) { + return addAbortListenerNative(signal, listener)[Symbol.dispose] + } + + if (typeof signal.addEventListener === 'function') { + signal.addEventListener('abort', listener, { once: true }) + return () => signal.removeEventListener('abort', listener) + } + signal.once('abort', listener) + return () => signal.removeListener('abort', listener) +} + +const validTokenChars = new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32-47 (!"#$%&'()*+,-./) + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48-63 (0-9:;<=>?) + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64-79 (@A-O) + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80-95 (P-Z[\]^_) + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96-111 (`a-o) + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 112-127 (p-z{|}~) + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128-143 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 144-159 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-175 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 176-191 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 192-207 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 208-223 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 224-239 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 240-255 +]) + +/** + * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 + * @param {number} c + * @returns {boolean} + */ +function isTokenCharCode (c) { + return (validTokenChars[c] === 1) +} + +const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ + +/** + * @param {string} characters + * @returns {boolean} + */ +function isValidHTTPToken (characters) { + if (characters.length >= 12) return tokenRegExp.test(characters) + if (characters.length === 0) return false + + for (let i = 0; i < characters.length; i++) { + if (validTokenChars[characters.charCodeAt(i)] !== 1) { + return false + } + } + return true +} + +// headerCharRegex have been lifted from +// https://github.com/nodejs/node/blob/main/lib/_http_common.js + +/** + * Matches if val contains an invalid field-vchar + * field-value = *( field-content / obs-fold ) + * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + * field-vchar = VCHAR / obs-text + */ +const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ + +/** + * @param {string} characters + * @returns {boolean} + */ +function isValidHeaderValue (characters) { + return !headerCharRegex.test(characters) +} + +const rangeHeaderRegex = /^bytes (\d+)-(\d+)\/(\d+|\*)?$/ + +/** + * @typedef {object} RangeHeader + * @property {number} start + * @property {number | null} end + * @property {number | null} size + */ + +/** + * Parse accordingly to RFC 9110 + * @see https://www.rfc-editor.org/rfc/rfc9110#field.content-range + * @param {string} [range] + * @returns {RangeHeader|null} + */ +function parseRangeHeader (range) { + if (range == null || range === '') return { start: 0, end: null, size: null } + if (!range) return null + + const m = rangeHeaderRegex.exec(range) + return m + ? { + start: parseInt(m[1]), + end: m[2] ? parseInt(m[2]) : null, + size: m[3] && m[3] !== '*' ? parseInt(m[3]) : null + } + : null +} + +/** + * @template {import("events").EventEmitter} T + * @param {T} obj + * @param {string} name + * @param {(...args: any[]) => void} listener + * @returns {T} + */ +function addListener (obj, name, listener) { + const listeners = (obj[kListeners] ??= []) + listeners.push([name, listener]) + obj.on(name, listener) + return obj +} + +/** + * @template {import("events").EventEmitter} T + * @param {T} obj + * @returns {T} + */ +function removeAllListeners (obj) { + if (obj[kListeners] != null) { + for (const [name, listener] of obj[kListeners]) { + obj.removeListener(name, listener) + } + obj[kListeners] = null + } + return obj +} + +/** + * @param {import ('../dispatcher/client')} client + * @param {import ('../core/request')} request + * @param {Error} err + */ +function errorRequest (client, request, err) { + try { + request.onResponseError(err) + assert(request.aborted) + } catch (err) { + client.emit('error', err) + } +} + +/** + * @param {WeakRef} socketWeakRef + * @param {object} opts + * @param {number} opts.timeout + * @param {string} opts.hostname + * @param {number} opts.port + * @returns {() => void} + */ +const setupConnectTimeout = process.platform === 'win32' + ? (socketWeakRef, opts) => { + if (!opts.timeout) { + return noop + } + + let s1 = null + let s2 = null + const fastTimer = timers.setFastTimeout(() => { + // setImmediate is added to make sure that we prioritize socket error events over timeouts + s1 = setImmediate(() => { + // Windows needs an extra setImmediate probably due to implementation differences in the socket logic + s2 = setImmediate(() => onConnectTimeout(socketWeakRef.deref(), opts)) + }) + }, opts.timeout) + return () => { + timers.clearFastTimeout(fastTimer) + clearImmediate(s1) + clearImmediate(s2) + } + } + : (socketWeakRef, opts) => { + if (!opts.timeout) { + return noop + } + + let s1 = null + const fastTimer = timers.setFastTimeout(() => { + // setImmediate is added to make sure that we prioritize socket error events over timeouts + s1 = setImmediate(() => { + onConnectTimeout(socketWeakRef.deref(), opts) + }) + }, opts.timeout) + return () => { + timers.clearFastTimeout(fastTimer) + clearImmediate(s1) + } + } + +/** + * @param {net.Socket} socket + * @param {object} opts + * @param {number} opts.timeout + * @param {string} opts.hostname + * @param {number} opts.port + */ +function onConnectTimeout (socket, opts) { + // The socket could be already garbage collected + if (socket == null) { + return + } + + let message = 'Connect Timeout Error' + if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { + message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')},` + } else { + message += ` (attempted address: ${opts.hostname}:${opts.port},` + } + + message += ` timeout: ${opts.timeout}ms)` + + destroy(socket, new ConnectTimeoutError(message)) +} + +let lastUrlString = null +let lastProtocol = null + +/** + * @param {string} urlString + * @returns {string} + */ +function getProtocolFromUrlString (urlString) { + // Requests are typically dispatched against the same origin over and over, + // so cache the last (urlString, protocol) pair to skip re-parsing. + if (urlString === lastUrlString) { + return lastProtocol + } + + const protocol = getProtocolFromUrlStringSlow(urlString) + lastUrlString = urlString + lastProtocol = protocol + + return protocol +} + +/** + * @param {string} urlString + * @returns {string} + */ +function getProtocolFromUrlStringSlow (urlString) { + if ( + urlString[0] === 'h' && + urlString[1] === 't' && + urlString[2] === 't' && + urlString[3] === 'p' + ) { + switch (urlString[4]) { + case ':': + return 'http:' + case 's': + if (urlString[5] === ':') { + return 'https:' + } + } + } + // fallback if none of the usual suspects + return urlString.slice(0, urlString.indexOf(':') + 1) +} + +const kEnumerableProperty = { + __proto__: null, + enumerable: true +} + +const normalizedMethodRecordsBase = { + delete: 'DELETE', + DELETE: 'DELETE', + get: 'GET', + GET: 'GET', + head: 'HEAD', + HEAD: 'HEAD', + options: 'OPTIONS', + OPTIONS: 'OPTIONS', + post: 'POST', + POST: 'POST', + put: 'PUT', + PUT: 'PUT', + query: 'QUERY', + QUERY: 'QUERY' +} + +const normalizedMethodRecords = { + ...normalizedMethodRecordsBase, + patch: 'patch', + PATCH: 'PATCH' +} + +// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. +Object.setPrototypeOf(normalizedMethodRecordsBase, null) +Object.setPrototypeOf(normalizedMethodRecords, null) + +module.exports = { + kEnumerableProperty, + isDisturbed, + isBlobLike, + parseOrigin, + parseURL, + getServerName, + isStream, + isIterable, + hasSafeIterator, + isAsyncIterable, + isDestroyed, + headerNameToString, + bufferToLowerCasedHeaderName, + addListener, + removeAllListeners, + errorRequest, + parseRawHeaders, + toRawHeaders, + encodeRawHeaders, + parseHeaders, + setHeader, + parseKeepAliveTimeout, + destroy, + bodyLength, + deepClone, + isBuffer, + assertRequestHandler, + getSocketInfo, + isFormDataLike, + pathHasQueryOrFragment, + serializePathWithQuery, + addAbortListener, + isValidHTTPToken, + isValidHeaderValue, + isTokenCharCode, + parseRangeHeader, + normalizedMethodRecordsBase, + normalizedMethodRecords, + isValidPort, + isHttpOrHttpsPrefixed, + safeHTTPMethods: Object.freeze(['GET', 'HEAD', 'OPTIONS', 'TRACE']), + wrapRequestBody, + setupConnectTimeout, + getProtocolFromUrlString +} + + +/***/ }), + +/***/ 7405: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { InvalidArgumentError, MaxOriginsReachedError } = __nccwpck_require__(8707) +const { kBusy, kClients, kConnected, kRunning, kPending, kClose, kDestroy, kDispatch, kUrl } = __nccwpck_require__(6443) +const DispatcherBase = __nccwpck_require__(1841) +const Pool = __nccwpck_require__(628) +const Client = __nccwpck_require__(3701) +const util = __nccwpck_require__(3440) + +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kOnDrain = Symbol('onDrain') +const kFactory = Symbol('factory') +const kOptions = Symbol('options') +const kOrigins = Symbol('origins') + +function defaultFactory (origin, opts) { + return opts && opts.connections === 1 + ? new Client(origin, opts) + : new Pool(origin, opts) +} + +class Agent extends DispatcherBase { + constructor ({ factory = defaultFactory, maxOrigins = Infinity, connect, tls, ...options } = {}) { + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } + + if (typeof maxOrigins !== 'number' || Number.isNaN(maxOrigins) || maxOrigins <= 0) { + throw new InvalidArgumentError('maxOrigins must be a number greater than 0') + } + + super(options) + + if (connect && typeof connect !== 'function') { + connect = { ...connect } + } + + if (tls && typeof tls !== 'function') { + tls = { ...tls } + } + + this[kOptions] = { ...util.deepClone(options), maxOrigins, connect, tls } + this[kFactory] = factory + this[kClients] = new Map() + this[kOrigins] = new Set() + + this[kOnDrain] = (origin, targets) => { + this.emit('drain', origin, [this, ...targets]) + } + + this[kOnConnect] = (origin, targets) => { + this.emit('connect', origin, [this, ...targets]) + } + + this[kOnDisconnect] = (origin, targets, err) => { + this.emit('disconnect', origin, [this, ...targets], err) + } + + this[kOnConnectionError] = (origin, targets, err) => { + this.emit('connectionError', origin, [this, ...targets], err) + } + } + + get [kRunning] () { + let ret = 0 + for (const dispatcher of this[kClients].values()) { + ret += dispatcher[kRunning] + } + return ret + } + + [kDispatch] (opts, handler) { + let origin + if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { + origin = String(opts.origin) + } else { + throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') + } + + const allowH2 = opts.allowH2 ?? this[kOptions].allowH2 + const key = allowH2 === false ? `${origin}#http1-only` : origin + + if (this[kOrigins].size >= this[kOptions].maxOrigins && !this[kOrigins].has(origin)) { + throw new MaxOriginsReachedError() + } + + let dispatcher = this[kClients].get(key) + if (!dispatcher) { + dispatcher = this[kFactory](opts.origin, allowH2 === false + ? { ...this[kOptions], allowH2: false } + : this[kOptions]) + + const closeClientIfUnused = () => { + if (this[kClients].get(key) !== dispatcher) { + return + } + + // A GOAWAY detaches the HTTP/2 session before requeued requests are + // dispatched on a replacement connection. At that point the pool has + // no connected clients and is not busy, but it still has pending work. + // Closing it here lets the replacement Client finish those requests + // and then destroys that new connection with ClientDestroyedError. + if (dispatcher[kConnected] > 0 || dispatcher[kBusy] || dispatcher[kPending] > 0) { + return + } + + this[kClients].delete(key) + if (!dispatcher.destroyed) { + dispatcher.close() + } + + let hasOrigin = false + for (const k of this[kClients].keys()) { + if (k === origin || k === `${origin}#http1-only`) { + hasOrigin = true + break + } + } + + if (!hasOrigin) { + this[kOrigins].delete(origin) + } + } + + dispatcher + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', (origin, targets, err) => { + closeClientIfUnused() + this[kOnDisconnect](origin, targets, err) + }) + .on('connectionError', (origin, targets, err) => { + closeClientIfUnused() + this[kOnConnectionError](origin, targets, err) + }) + + this[kClients].set(key, dispatcher) + this[kOrigins].add(origin) + } + + return dispatcher.dispatch(opts, handler) + } + + [kClose] () { + const closePromises = [] + for (const dispatcher of this[kClients].values()) { + closePromises.push(dispatcher.close()) + } + this[kClients].clear() + + return Promise.all(closePromises) + } + + [kDestroy] (err) { + const destroyPromises = [] + for (const dispatcher of this[kClients].values()) { + destroyPromises.push(dispatcher.destroy(err)) + } + this[kClients].clear() + + return Promise.all(destroyPromises) + } + + get stats () { + const allClientStats = {} + for (const dispatcher of this[kClients].values()) { + if (dispatcher.stats) { + allClientStats[dispatcher[kUrl].origin] = dispatcher.stats + } + } + return allClientStats + } +} + +module.exports = Agent + + +/***/ }), + +/***/ 837: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + BalancedPoolMissingUpstreamError, + InvalidArgumentError +} = __nccwpck_require__(8707) +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher +} = __nccwpck_require__(2128) +const Pool = __nccwpck_require__(628) +const { kOriginless, kUrl } = __nccwpck_require__(6443) +const util = __nccwpck_require__(3440) +const kFactory = Symbol('factory') + +const kOptions = Symbol('options') +const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') +const kCurrentWeight = Symbol('kCurrentWeight') +const kIndex = Symbol('kIndex') +const kWeight = Symbol('kWeight') +const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') +const kErrorPenalty = Symbol('kErrorPenalty') + +/** + * Calculate the greatest common divisor of two numbers by + * using the Euclidean algorithm. + * + * @param {number} a + * @param {number} b + * @returns {number} + */ +function getGreatestCommonDivisor (a, b) { + if (a === 0) return b + + while (b !== 0) { + const t = b + b = a % b + a = t + } + return a +} + +function defaultFactory (origin, opts) { + return new Pool(origin, opts) +} + +class BalancedPool extends PoolBase { + constructor (upstreams = [], { factory = defaultFactory, connect, tls, ...opts } = {}) { + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + super(opts) + + this[kOriginless] = true + if (connect && typeof connect !== 'function') connect = { ...connect } + if (tls && typeof tls !== 'function') tls = { ...tls } + this[kOptions] = { ...util.deepClone(opts), connect, tls } + this[kIndex] = -1 + this[kCurrentWeight] = 0 + + this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 + this[kErrorPenalty] = this[kOptions].errorPenalty || 15 + + if (!Array.isArray(upstreams)) { + upstreams = [upstreams] + } + + this[kFactory] = factory + + for (const upstream of upstreams) { + this.addUpstream(upstream) + } + this._updateBalancedPoolStats() + } + + addUpstream (upstream) { + const upstreamOrigin = util.parseOrigin(upstream).origin + + if (this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + ))) { + return this + } + const pool = this[kFactory](upstreamOrigin, this[kOptions]) + + this[kAddClient](pool) + pool.on('connect', () => { + pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]) + }) + + pool.on('connectionError', () => { + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + }) + + pool.on('disconnect', (...args) => { + const err = args[2] + if (err && err.code === 'UND_ERR_SOCKET') { + // decrease the weight of the pool. + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + } + }) + + for (const client of this[kClients]) { + client[kWeight] = this[kMaxWeightPerServer] + } + + this._updateBalancedPoolStats() + + return this + } + + _updateBalancedPoolStats () { + let result = 0 + for (let i = 0; i < this[kClients].length; i++) { + result = getGreatestCommonDivisor(this[kClients][i][kWeight], result) + } + + this[kGreatestCommonDivisor] = result + } + + removeUpstream (upstream) { + const upstreamOrigin = util.parseOrigin(upstream).origin + + const pool = this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + )) + + if (pool) { + this[kRemoveClient](pool) + } + + return this + } + + getUpstream (upstream) { + const upstreamOrigin = util.parseOrigin(upstream).origin + + return this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + )) + } + + get upstreams () { + return this[kClients] + .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) + .map((p) => p[kUrl].origin) + } + + [kGetDispatcher] () { + // We validate that pools is greater than 0, + // otherwise we would have to wait until an upstream + // is added, which might never happen. + if (this[kClients].length === 0) { + throw new BalancedPoolMissingUpstreamError() + } + + let counter = 0 + + let maxWeightIndex = -1 + + while (counter++ < this[kClients].length) { + this[kIndex] = (this[kIndex] + 1) % this[kClients].length + const pool = this[kClients][this[kIndex]] + + // decrease the current weight every `this[kClients].length`. + if (this[kIndex] === 0) { + // Set the current weight to the next lower weight. + this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor] + + if (this[kCurrentWeight] <= 0) { + this[kCurrentWeight] = this[kMaxWeightPerServer] + } + } + + // Skip unavailable pools after updating the current weight for this cycle. + if ( + pool[kNeedDrain] || + pool.closed === true || + pool.destroyed === true + ) { + continue + } + + // Track the best fallback if no pool matches the current weight. + if (maxWeightIndex === -1 || pool[kWeight] > this[kClients][maxWeightIndex][kWeight]) { + maxWeightIndex = this[kIndex] + } + + if (pool[kWeight] >= this[kCurrentWeight]) { + return pool + } + } + + if (maxWeightIndex === -1) { + return + } + + this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] + this[kIndex] = maxWeightIndex + return this[kClients][maxWeightIndex] + } +} + +module.exports = BalancedPool + + +/***/ }), + +/***/ 637: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +/* global WebAssembly */ + +const assert = __nccwpck_require__(4589) +const util = __nccwpck_require__(3440) +const { channels } = __nccwpck_require__(2414) +const timers = __nccwpck_require__(6603) +const { + RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, + RequestAbortedError, + InvalidArgumentError, + HeadersTimeoutError, + HeadersOverflowError, + SocketError, + InformationalError, + BodyTimeoutError, + HTTPParserError, + WebAssemblyNotSupportedError, + ResponseExceededMaxSizeError +} = __nccwpck_require__(8707) +const { + kUrl, + kReset, + kClient, + kParser, + kBlocking, + kRunning, + kPending, + kSize, + kWriting, + kQueue, + kNoRef, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kSocket, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kMaxRequests, + kCounter, + kMaxResponseSize, + kOnError, + kResume, + kHTTPContext, + kClosed, + kUseMilo +} = __nccwpck_require__(6443) + +const constants = __nccwpck_require__(2824) +// Node.js core bundles only llhttp; experimental Milo remains available in npm builds. +const { H1Parser, getMiloEnabled } = typeof esbuildDetection === 'undefined' + ? __nccwpck_require__(1969) + : {} +const EMPTY_BUF = Buffer.alloc(0) +const FastBuffer = Buffer[Symbol.species] +const removeAllListeners = util.removeAllListeners +const kIdleSocketValidation = Symbol('kIdleSocketValidation') +const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout') +const kSocketUsed = Symbol('kSocketUsed') +const kTypeOfService = Symbol('kTypeOfService') + +let extractBody + +function lazyllhttp () { + // Check only when HTTP/1 needs the parser, so other APIs remain usable without WASM. + if (typeof WebAssembly === 'undefined') { + throw new WebAssemblyNotSupportedError() + } + + const llhttpWasmData = process.env.JEST_WORKER_ID ? __nccwpck_require__(3870) : undefined + + let mod + + // We disable wasm SIMD on older versions of Node.js on ppc64 that are broken on Power >=9 architectures. + let useWasmSIMD = true + if (process.arch === 'ppc64') { + const [major, minor] = process.versions.node.split('.').map(n => parseInt(n, 10)) + if (major < 24 || (major === 24 && minor < 12)) { + useWasmSIMD = false + } + } + // The Env Variable UNDICI_NO_WASM_SIMD allows explicitly overriding the default behavior + if (process.env.UNDICI_NO_WASM_SIMD === '1') { + useWasmSIMD = false + } else if (process.env.UNDICI_NO_WASM_SIMD === '0') { + useWasmSIMD = true + } + + if (useWasmSIMD) { + try { + mod = new WebAssembly.Module(__nccwpck_require__(3434)) + } catch {} + } + + if (!mod) { + // We could check if the error was caused by the simd option not + // being enabled, but the occurring of this other error + // * https://github.com/emscripten-core/emscripten/issues/11495 + // got me to remove that check to avoid breaking Node 12. + mod = new WebAssembly.Module(llhttpWasmData || __nccwpck_require__(3870)) + } + + return new WebAssembly.Instance(mod, { + env: { + /** + * @param {number} p + * @param {number} at + * @param {number} len + * @returns {number} + */ + wasm_on_url: (p, at, len) => { + return 0 + }, + /** + * @param {number} p + * @param {number} at + * @param {number} len + * @returns {number} + */ + wasm_on_status: (p, at, len) => { + assert(currentParser.ptr === p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) + }, + /** + * @param {number} p + * @returns {number} + */ + wasm_on_message_begin: p => { + assert(currentParser.ptr === p) + return currentParser.onMessageBegin() + }, + /** + * @param {number} p + * @param {number} at + * @param {number} len + * @returns {number} + */ + wasm_on_header_field: (p, at, len) => { + assert(currentParser.ptr === p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) + }, + /** + * @param {number} p + * @param {number} at + * @param {number} len + * @returns {number} + */ + wasm_on_header_value: (p, at, len) => { + assert(currentParser.ptr === p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) + }, + /** + * @param {number} p + * @param {number} statusCode + * @param {0|1} upgrade + * @param {0|1} shouldKeepAlive + * @returns {number} + */ + wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { + assert(currentParser.ptr === p) + return currentParser.onHeadersComplete(statusCode, upgrade === 1, shouldKeepAlive === 1) + }, + /** + * @param {number} p + * @param {number} at + * @param {number} len + * @returns {number} + */ + wasm_on_body: (p, at, len) => { + assert(currentParser.ptr === p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) + }, + /** + * @param {number} p + * @returns {number} + */ + wasm_on_message_complete: p => { + assert(currentParser.ptr === p) + return currentParser.onMessageComplete() + } + } + }) +} + +let llhttpInstance = null + +/** + * @type {Parser|null} + */ +let currentParser = null +let currentBufferRef = null +/** + * @type {number} + */ +let currentBufferSize = 0 +let currentBufferPtr = null +let currentBuffer = null + +const USE_NATIVE_TIMER = 0 +const USE_FAST_TIMER = 1 + +// Use fast timers for headers and body to take eventual event loop +// latency into account. +const TIMEOUT_HEADERS = 2 | USE_FAST_TIMER +const TIMEOUT_BODY = 4 | USE_FAST_TIMER + +// Use native timers to ignore event loop latency for keep-alive +// handling. +const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER + +class Parser { + /** + * @param {import('./client.js')} client + * @param {import('net').Socket} socket + * @param {*} llhttp + */ + constructor (client, socket, { exports }) { + this.llhttp = exports + this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) + this.client = client + /** + * @type {import('net').Socket} + */ + this.socket = socket + this.timeout = null + this.timeoutWeakRef = new WeakRef(this) + this.timeoutValue = null + this.timeoutType = null + this.statusCode = 0 + this.statusText = '' + this.upgrade = false + this.headers = [] + this.headersSize = 0 + this.headersMaxSize = client[kMaxHeadersSize] + this.shouldKeepAlive = false + this.paused = false + this.resume = this.resume.bind(this) + + this.bytesRead = 0 + + this.keepAlive = '' + this.contentLength = -1 + this.hasTransferEncoding = false + this.connection = '' + this.maxResponseSize = client[kMaxResponseSize] + } + + setTimeout (delay, type) { + // If the existing timer and the new timer are of different timer type + // (fast or native) or have different delay, we need to clear the existing + // timer and set a new one. + if (delay !== this.timeoutValue || (type & USE_FAST_TIMER) ^ (this.timeoutType & USE_FAST_TIMER)) { + // If a timeout is already set, clear it with clearTimeout of the fast + // timer implementation, as it can clear fast and native timers. + if (this.timeout) { + timers.clearTimeout(this.timeout) + this.timeout = null + } + + if (delay) { + if (type & USE_FAST_TIMER) { + this.timeout = timers.setFastTimeout(onParserTimeout, delay, this.timeoutWeakRef) + } else { + this.timeout = setTimeout(onParserTimeout, delay, this.timeoutWeakRef) + this.timeout?.unref() + } + } + + this.timeoutValue = delay + } else if (this.timeout) { + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + this.timeoutType = type + } + + resume () { + if (this.socket.destroyed || !this.paused) { + return + } + + assert(this.ptr != null) + assert(currentParser === null) + + this.llhttp.llhttp_resume(this.ptr) + + assert(this.timeoutType === TIMEOUT_BODY) + if (this.timeout) { + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + this.paused = false + this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. + this.readMore() + } + + readMore () { + while (!this.paused && this.ptr) { + const chunk = this.socket.read() + if (chunk === null) { + break + } + this.execute(chunk) + } + } + + /** + * @param {Buffer} chunk + */ + execute (chunk) { + assert(currentParser === null) + assert(this.ptr != null) + assert(!this.paused) + + const { socket, llhttp } = this + + // Allocate a new buffer if the current buffer is too small. + if (chunk.length > currentBufferSize) { + if (currentBufferPtr) { + llhttp.free(currentBufferPtr) + } + // Allocate a buffer that is a multiple of 4096 bytes. + currentBufferSize = Math.ceil(chunk.length / 4096) * 4096 + currentBufferPtr = llhttp.malloc(currentBufferSize) + } + + if ( + currentBuffer === null || + currentBuffer.buffer !== llhttp.memory.buffer || + currentBuffer.byteOffset !== currentBufferPtr || + currentBuffer.byteLength !== currentBufferSize + ) { + currentBuffer = new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize) + } + + currentBuffer.set(chunk) + + // Call `execute` on the wasm parser. + // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, + // and finally the length of bytes to parse. + // The return value is an error code or `constants.ERROR.OK`. + try { + let ret + + try { + currentBufferRef = chunk + currentParser = this + ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, chunk.length) + } finally { + currentParser = null + currentBufferRef = null + } + + if (ret !== constants.ERROR.OK) { + const data = chunk.subarray(llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr) + + if (ret === constants.ERROR.PAUSED_UPGRADE) { + this.onUpgrade(data) + } else if (ret === constants.ERROR.PAUSED) { + this.paused = true + socket.unshift(data) + } else { + throw this.createError(ret, data) } - // otherwise apply quoting rules specific to the cmd.exe command line parser. - // the libuv rules are generic and are not designed specifically for cmd.exe - // command line parser. - // - // for a detailed description of the cmd.exe command line parser, refer to - // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912 - // need quotes for empty arg - if (!arg) { - return '""'; + } + } catch (err) { + util.destroy(socket, err) + } + } + + finish () { + assert(currentParser === null) + assert(this.ptr != null) + + const { llhttp } = this + + // The peer closed the connection. If the body parser was paused by + // backpressure we must finish parsing before signalling EOF, otherwise + // llhttp_finish() would crash (it used to assert !paused) or report a + // half-parsed message. Backpressure is advisory here: onData keeps buffering + // delivered bytes into the response stream, so resume across pauses and + // drain whatever is still buffered on the socket. A Content-Length/chunked + // body reaches on_message_complete during execute(); an EOF-delimited body + // stays paused (its length is unknown) and is completed by llhttp_finish(). + if (this.paused) { + let data + do { + llhttp.llhttp_resume(this.ptr) + this.paused = false + data = this.socket.read() || EMPTY_BUF + this.execute(data) + } while (this.paused && data.length > 0) + + if (this.paused) { + llhttp.llhttp_resume(this.ptr) + this.paused = false + } + } + + let ret + + try { + currentParser = this + ret = llhttp.llhttp_finish(this.ptr) + } finally { + currentParser = null + } + + if (ret === constants.ERROR.OK) { + return null + } + + if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) { + this.paused = true + return null + } + + return this.createError(ret, EMPTY_BUF) + } + + createError (ret, data) { + const { llhttp, contentLength, bytesRead } = this + + if (contentLength !== -1 && bytesRead !== contentLength) { + return new ResponseContentLengthMismatchError() + } + + const ptr = llhttp.llhttp_get_error_reason(this.ptr) + let message = '' + if (ptr) { + const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) + message = + 'Response does not match the HTTP/1.1 protocol (' + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ')' + } + + return new HTTPParserError(message, constants.ERROR[ret], data) + } + + destroy () { + assert(currentParser === null) + assert(this.ptr != null) + + this.llhttp.llhttp_free(this.ptr) + this.ptr = null + + this.timeout && timers.clearTimeout(this.timeout) + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + + this.paused = false + } + + /** + * @param {Buffer} buf + * @returns {0} + */ + onStatus (buf) { + this.statusText = buf.toString() + return 0 + } + + /** + * @returns {0|-1} + */ + onMessageBegin () { + const { socket, client } = this + + if (socket.destroyed) { + return -1 + } + + if (client[kRunning] === 0) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 + } + + const request = client[kQueue][client[kRunningIdx]] + if (!request) { + return -1 + } + request.onResponseStarted() + + return 0 + } + + /** + * @param {Buffer} buf + * @returns {number} + */ + onHeaderField (buf) { + const len = this.headers.length + + if ((len & 1) === 0) { + this.headers.push(buf) + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } + + this.trackHeader(buf.length) + + return 0 + } + + /** + * @param {Buffer} buf + * @returns {number} + */ + onHeaderValue (buf) { + let len = this.headers.length + const isContinuation = (len & 1) === 0 + + if ((len & 1) === 1) { + this.headers.push(buf) + len += 1 + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } + + const key = this.headers[len - 2] + if (key.length === 10) { + const headerName = util.bufferToLowerCasedHeaderName(key) + if (headerName === 'keep-alive') { + this.keepAlive += (isContinuation || this.keepAlive.length === 0 ? '' : ',') + buf.toString() + } else if (headerName === 'connection') { + this.connection += (isContinuation || this.connection.length === 0 ? '' : ',') + buf.toString() + } + } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') { + if (this.contentLength === -1) { + this.contentLength = 0 + } + for (let i = 0; i < buf.length; i++) { + this.contentLength = this.contentLength * 10 + (buf[i] - 0x30) + } + } else if (key.length === 17 && util.bufferToLowerCasedHeaderName(key) === 'transfer-encoding') { + this.hasTransferEncoding = true + } + + this.trackHeader(buf.length) + + return 0 + } + + /** + * @param {number} len + */ + trackHeader (len) { + this.headersSize += len + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + } + } + + /** + * @param {Buffer} head + */ + onUpgrade (head) { + const { upgrade, client, socket, headers, statusCode, statusText } = this + + assert(upgrade) + assert(client[kSocket] === socket) + assert(!socket.destroyed) + assert(!this.paused) + assert((headers.length & 1) === 0) + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + assert(request.upgrade || request.method === 'CONNECT') + + this.statusCode = 0 + this.statusText = '' + this.shouldKeepAlive = false + + this.headers = [] + this.headersSize = 0 + + socket.unshift(head) + + socket[kParser].destroy() + socket[kParser] = null + + socket[kClient] = null + socket[kError] = null + + removeAllListeners(socket) + + client[kSocket] = null + client[kHTTPContext] = null // TODO (fix): This is hacky... + client[kQueue][client[kRunningIdx]++] = null + client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) + + try { + request.onRequestUpgrade(statusCode, headers, socket, statusText) + } catch (err) { + util.errorRequest(client, request, err) + util.destroy(socket, err) + } + + client[kResume]() + } + + /** + * @param {number} statusCode + * @param {boolean} upgrade + * @param {boolean} shouldKeepAlive + * @returns {number} + */ + onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { + const { client, socket, headers, statusText } = this + + if (socket.destroyed) { + return -1 + } + + if (client[kRunning] === 0) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 + } + + const request = client[kQueue][client[kRunningIdx]] + + if (!request) { + return -1 + } + + assert(!this.upgrade) + assert(this.statusCode < 200) + + if (statusCode === 100) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 + } + + /* this can only happen if server is misbehaving */ + if (upgrade && !request.upgrade) { + util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))) + return -1 + } + + assert(this.timeoutType === TIMEOUT_HEADERS) + + this.statusCode = statusCode + this.shouldKeepAlive = + shouldKeepAlive || + // Override llhttp value which does not allow keepAlive for HEAD. + (request.method === 'HEAD' && !socket[kReset] && + /(?:^|,)[\t ]*keep-alive[\t ]*(?:,|$)/i.test(this.connection) && + !/(?:^|,)[\t ]*close[\t ]*(?:,|$)/i.test(this.connection)) + + // Responses to HEAD and 204/304 responses never carry content + if (request.method === 'HEAD' || statusCode === 204 || statusCode === 304) { + // A non-zero Content-Length or Transfer-Encoding on a 204/304 means the + // server may also have sent content inappropriately, which would then be + // parsed as the next response on this connection. Accept it, but do not + // reuse the connection. HEAD requests are fine tho. + if (request.method !== 'HEAD' && (this.contentLength > 0 || this.hasTransferEncoding)) { + this.shouldKeepAlive = false + } + this.contentLength = -1 + } + + if (this.statusCode >= 200) { + const bodyTimeout = request.bodyTimeout != null ? request.bodyTimeout : client[kBodyTimeout] + this.setTimeout(bodyTimeout, TIMEOUT_BODY) + } else if (this.timeout) { + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + if (request.method === 'CONNECT') { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } + + if (upgrade) { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } + + assert((this.headers.length & 1) === 0) + this.headers = [] + this.headersSize = 0 + + if (this.shouldKeepAlive && client[kPipelining]) { + const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null + + if (keepAliveTimeout != null) { + const timeout = Math.min(keepAliveTimeout - client[kKeepAliveTimeoutThreshold], client[kKeepAliveMaxTimeout]) + if (timeout <= 0) { + socket[kReset] = true + } else { + client[kKeepAliveTimeoutValue] = timeout } - // determine whether the arg needs to be quoted - const cmdSpecialChars = [ - ' ', - '\t', - '&', - '(', - ')', - '[', - ']', - '{', - '}', - '^', - '=', - ';', - '!', - "'", - '+', - ',', - '`', - '~', - '|', - '<', - '>', - '"' - ]; - let needsQuotes = false; - for (const char of arg) { - if (cmdSpecialChars.some(x => x === char)) { - needsQuotes = true; - break; - } + } else { + client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] + } + } else { + // Stop more requests from being dispatched. + socket[kReset] = true + } + + const pause = request.onResponseStart(statusCode, headers, this.resume, statusText) === false + + if (request.aborted) { + return -1 + } + + if (request.method === 'HEAD') { + return 1 + } + + if (statusCode < 200) { + return 1 + } + + if (socket[kBlocking]) { + socket[kBlocking] = false + client[kResume]() + } + + return pause ? constants.ERROR.PAUSED : 0 + } + + /** + * @param {Buffer} buf + * @returns {number} + */ + onBody (buf) { + const { client, socket, statusCode, maxResponseSize } = this + + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + assert(this.timeoutType === TIMEOUT_BODY) + if (this.timeout) { + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + assert(statusCode >= 200) + + if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { + util.destroy(socket, new ResponseExceededMaxSizeError()) + return -1 + } + + this.bytesRead += buf.length + + if (request.onResponseData(buf) === false) { + return constants.ERROR.PAUSED + } + + return 0 + } + + /** + * @returns {number} + */ + onMessageComplete () { + const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this + + if (socket.destroyed && (!statusCode || shouldKeepAlive)) { + return -1 + } + + if (upgrade) { + return 0 + } + + assert(statusCode >= 100) + assert((this.headers.length & 1) === 0) + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + this.statusCode = 0 + this.statusText = '' + this.bytesRead = 0 + this.contentLength = -1 + this.hasTransferEncoding = false + this.keepAlive = '' + this.connection = '' + + this.headers = [] + this.headersSize = 0 + + if (statusCode < 200) { + return 0 + } + + if (contentLength !== -1 && bytesRead !== contentLength) { + util.destroy(socket, new ResponseContentLengthMismatchError()) + return -1 + } + + request.onResponseEnd(headers) + + client[kQueue][client[kRunningIdx]++] = null + socket[kSocketUsed] = client[kPending] === 0 + + if (socket[kWriting]) { + assert(client[kRunning] === 0) + // Response completed before request. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (!shouldKeepAlive) { + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (socket[kReset] && client[kRunning] === 0) { + // Destroy socket once all requests have completed. + // The request at the tail of the pipeline is the one + // that requested reset and no further requests should + // have been queued since then. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (client[kPipelining] == null || client[kPipelining] === 1) { + // We must wait a full event loop cycle to reuse this socket to make sure + // that non-spec compliant servers are not closing the connection even if they + // said they won't. + setImmediate(client[kResume]) + } else { + client[kResume]() + } + + return 0 + } +} + +function onParserTimeout (parserWeakRef) { + const parser = parserWeakRef.deref() + if (!parser) { + return + } + + const { socket, timeoutType, client, paused } = parser + + if (timeoutType === TIMEOUT_HEADERS) { + if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { + assert(!paused, 'cannot be paused while waiting for headers') + util.destroy(socket, new HeadersTimeoutError()) + } + } else if (timeoutType === TIMEOUT_BODY) { + if (!paused) { + util.destroy(socket, new BodyTimeoutError()) + } + } else if (timeoutType === TIMEOUT_KEEP_ALIVE) { + assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) + util.destroy(socket, new InformationalError('socket idle timeout')) + } +} + +/** + * @param {import ('./client.js')} client + * @param {import('net').Socket} socket + * @returns + */ +function connectH1 (client, socket) { + client[kSocket] = socket + + if (!llhttpInstance) { + llhttpInstance = lazyllhttp() + } + + if (socket.errored) { + throw socket.errored + } + + if (socket.destroyed) { + throw new SocketError('destroyed') + } + + socket[kNoRef] = false + socket[kWriting] = false + socket[kReset] = false + socket[kBlocking] = false + socket[kIdleSocketValidation] = 0 + socket[kIdleSocketValidationTimeout] = null + socket[kSocketUsed] = false + socket[kParser] = typeof esbuildDetection === 'undefined' && (client[kUseMilo] ?? getMiloEnabled()) + ? new H1Parser(client, socket) + : new Parser(client, socket, llhttpInstance) + + util.addListener(socket, 'error', onHttpSocketError) + util.addListener(socket, 'readable', onHttpSocketReadable) + util.addListener(socket, 'end', onHttpSocketEnd) + util.addListener(socket, 'close', onHttpSocketClose) + + socket[kClosed] = false + socket.on('close', onSocketClose) + + return { + version: 'h1', + defaultPipelining: 1, + write (request) { + return writeH1(client, request) + }, + resume () { + resumeH1(client) + }, + /** + * @param {Error|undefined} err + * @param {() => void} callback + */ + destroy (err, callback) { + if (socket[kClosed]) { + queueMicrotask(callback) + } else { + socket.on('close', callback) + socket.destroy(err) + } + }, + /** + * @returns {boolean} + */ + get destroyed () { + return socket.destroyed + }, + /** + * @param {import('../core/request.js')} request + * @returns {boolean} + */ + busy (request) { + if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) { + return true + } + + if (request) { + if (client[kRunning] > 0 && !request.idempotent) { + // Non-idempotent request cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return true } - // short-circuit if quotes not needed - if (!needsQuotes) { - return arg; + + if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { + // Don't dispatch an upgrade until all preceding requests have completed. + // A misbehaving server might upgrade the connection before all pipelined + // request has completed. + return true } - // the following quoting rules are very similar to the rules that by libuv applies. - // - // 1) wrap the string in quotes - // - // 2) double-up quotes - i.e. " => "" - // - // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately - // doesn't work well with a cmd.exe command line. - // - // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app. - // for example, the command line: - // foo.exe "myarg:""my val""" - // is parsed by a .NET console app into an arg array: - // [ "myarg:\"my val\"" ] - // which is the same end result when applying libuv quoting rules. although the actual - // command line from libuv quoting rules would look like: - // foo.exe "myarg:\"my val\"" - // - // 3) double-up slashes that precede a quote, - // e.g. hello \world => "hello \world" - // hello\"world => "hello\\""world" - // hello\\"world => "hello\\\\""world" - // hello world\ => "hello world\\" - // - // technically this is not required for a cmd.exe command line, or the batch argument parser. - // the reasons for including this as a .cmd quoting rule are: - // - // a) this is optimized for the scenario where the argument is passed from the .cmd file to an - // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule. - // - // b) it's what we've been doing previously (by deferring to node default behavior) and we - // haven't heard any complaints about that aspect. - // - // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be - // escaped when used on the command line directly - even though within a .cmd file % can be escaped - // by using %%. - // - // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts - // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing. - // - // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would - // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the - // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args - // to an external program. - // - // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file. - // % can be escaped within a .cmd file. - let reverse = '"'; - let quoteHit = true; - for (let i = arg.length; i > 0; i--) { - // walk the string in reverse - reverse += arg[i - 1]; - if (quoteHit && arg[i - 1] === '\\') { - reverse += '\\'; // double the slash - } - else if (arg[i - 1] === '"') { - quoteHit = true; - reverse += '"'; // double the quote - } - else { - quoteHit = false; - } + + if ( + client[kRunning] > 0 && + util.bodyLength(request.body) !== 0 && + (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body)) + ) { + // Request with stream or iterator body can error while other requests + // are inflight and indirectly error those as well. + // Ensure this doesn't happen by waiting for inflight + // to complete before dispatching. + + // Request with stream or iterator body cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return true + } + } + + return false + } + } +} + +function onHttpSocketError (err) { + const parser = this[kParser] + + // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded + // to the user. + if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { + const parserErr = parser.finish() + if (parserErr) { + this[kError] = parserErr + this[kClient][kOnError](parserErr) + } + return + } + + this[kError] = err + + this[kClient][kOnError](err) +} + +function onHttpSocketReadable () { + this[kParser]?.readMore() +} + +function onHttpSocketEnd () { + const parser = this[kParser] + + if (parser.statusCode && !parser.shouldKeepAlive) { + const parserErr = parser.finish() + if (parserErr) { + util.destroy(this, parserErr) + } + return + } + + util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) +} + +function onHttpSocketClose () { + const parser = this[kParser] + + clearIdleSocketValidation(this) + + if (parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + this[kError] = parser.finish() || this[kError] + } + + this[kParser].destroy() + this[kParser] = null + } + + const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) + + const client = this[kClient] + + client[kSocket] = null + client[kHTTPContext] = null // TODO (fix): This is hacky... + + if (client.destroyed) { + assert(client[kPending] === 0) + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + util.errorRequest(client, request, err) + } + } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null + + util.errorRequest(client, request, err) + } + + client[kPendingIdx] = client[kRunningIdx] + + assert(client[kRunning] === 0) + + client.emit('disconnect', client[kUrl], [client], err) + + client[kResume]() +} + +function onSocketClose () { + this[kClosed] = true +} + +function clearIdleSocketValidation (socket) { + if (socket[kIdleSocketValidationTimeout]) { + clearImmediate(socket[kIdleSocketValidationTimeout]) + socket[kIdleSocketValidationTimeout] = null + } + + socket[kIdleSocketValidation] = 0 +} + +function scheduleIdleSocketValidation (client, socket) { + socket[kIdleSocketValidation] = 1 + // Yield to the check phase (after poll) so unsolicited bytes / FIN / RST + // already pending on this idle keep-alive socket are processed before the + // next request is written (GHSA-35p6-xmwp-9g52). + // + // setTimeout(0) pays Node's ~1ms timer floor on every sequential reuse + // (#5493). setImmediate avoids that, but an *unref'd* Immediate lets poll + // block for ~500ms when the event loop is otherwise idle (#5600 / #5606). + // A ref'd Immediate both keeps the pending request alive and makes poll + // return immediately — the hybrid those issues asked for. + socket[kIdleSocketValidationTimeout] = setImmediate(() => { + socket[kIdleSocketValidationTimeout] = null + socket[kIdleSocketValidation] = 2 + + if (client[kSocket] === socket && !socket.destroyed) { + client[kResume]() + } + }) +} + +/** + * @param {import('./client.js')} client + */ +function resumeH1 (client) { + const socket = client[kSocket] + + if (socket && !socket.destroyed) { + if (client[kSize] === 0) { + if (!socket[kNoRef] && socket.unref) { + socket.unref() + socket[kNoRef] = true + } + } else if (socket[kNoRef] && socket.ref) { + socket.ref() + socket[kNoRef] = false + } + + if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) { + if (socket[kIdleSocketValidation] === 0) { + scheduleIdleSocketValidation(client, socket) + socket[kParser].readMore() + if (socket.destroyed) { + return + } + return + } + + if (socket[kIdleSocketValidation] === 1) { + socket[kParser].readMore() + if (socket.destroyed) { + return + } + return + } + } + + if (client[kRunning] === 0) { + socket[kParser].readMore() + if (socket.destroyed) { + return + } + } + + if (client[kSize] === 0) { + if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) { + socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE) + } + } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { + if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { + const request = client[kQueue][client[kRunningIdx]] + const headersTimeout = request.headersTimeout != null ? request.headersTimeout : client[kHeadersTimeout] + socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) + } + } + } +} + +// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 +function shouldSendContentLength (method) { + return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' +} + +function setTypeOfService (socket, request) { + if (typeof socket.setTypeOfService !== 'function') { + return + } + + const typeOfService = request.typeOfService + + if (typeOfService === undefined) { + return + } + + const currentTypeOfService = socket[kTypeOfService] + + if (currentTypeOfService === typeOfService) { + return + } + + try { + socket.setTypeOfService(typeOfService) + socket[kTypeOfService] = typeOfService + } catch { + // QoS marking is best-effort. setTypeOfService() can throw synchronously on + // some platforms depending on socket state, but that must not abort the request. + } +} + +/** + * @param {import('./client.js')} client + * @param {import('../core/request.js')} request + * @returns + */ +function writeH1 (client, request) { + const { method, path, host, upgrade, blocking, reset } = request + + let { body, headers, contentLength } = request + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = + method === 'PUT' || + method === 'POST' || + method === 'PATCH' || + method === 'QUERY' || + method === 'PROPFIND' || + method === 'PROPPATCH' + + if (util.isFormDataLike(body)) { + if (!extractBody) { + extractBody = (__nccwpck_require__(4492).extractBody) + } + + const [bodyStream, contentType] = extractBody(body) + if (request.contentType == null) { + headers.push('content-type', contentType) + } + body = bodyStream.stream + contentLength = bodyStream.length + } else if (util.isBlobLike(body) && request.contentType == null) { + const contentType = body.type + if (contentType) { + const contentTypeValue = `${contentType}` + if (!util.isValidHeaderValue(contentTypeValue)) { + util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header')) + return false + } + headers.push('content-type', contentTypeValue) + } + } + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } + + const bodyLength = util.bodyLength(body) + + contentLength = bodyLength ?? contentLength + + if (contentLength === null) { + contentLength = request.contentLength + } + + if (contentLength === 0 && !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // 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. + + contentLength = null + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if ( + shouldSendContentLength(method) && + contentLength > 0 && + request.contentLength !== null && + request.contentLength !== contentLength + ) { + if (client[kStrictContentLength]) { + util.errorRequest(client, request, new RequestContentLengthMismatchError()) + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + const socket = client[kSocket] + clearIdleSocketValidation(socket) + + /** + * @param {Error} [err] + * @returns {void} + */ + const abort = err => { + if (request.aborted || request.completed) { + return + } + + util.errorRequest(client, request, err || new RequestAbortedError()) + + util.destroy(body) + util.destroy(socket, new InformationalError('aborted')) + } + + try { + request.onRequestStart(abort, null) + } catch (err) { + util.errorRequest(client, request, err) + } + + if (request.aborted) { + return false + } + + if (method === 'HEAD') { + // https://github.com/mcollina/undici/issues/258 + // Close after a HEAD request to interop with misbehaving servers + // that may send a body in the response. + + socket[kReset] = true + } + + if (upgrade || method === 'CONNECT') { + // On CONNECT or upgrade, block pipeline from dispatching further + // requests on this connection. + + socket[kReset] = true + } + + if (reset != null) { + socket[kReset] = reset + } + + if (client[kMaxRequests] && ++socket[kCounter] >= client[kMaxRequests]) { + socket[kReset] = true + } + + if (blocking) { + socket[kBlocking] = true + } + + setTypeOfService(socket, request) + + let header = `${method} ${path} HTTP/1.1\r\n` + + if (typeof host === 'string') { + header += `host: ${host}\r\n` + } else { + header += client[kHostHeader] + } + + if (upgrade) { + header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` + } else if (client[kPipelining] && !socket[kReset]) { + header += 'connection: keep-alive\r\n' + } else { + header += 'connection: close\r\n' + } + + if (Array.isArray(headers)) { + for (let n = 0; n < headers.length; n += 2) { + const key = headers[n + 0] + const val = headers[n + 1] + + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + header += `${key}: ${val[i]}\r\n` } - reverse += '"'; - return reverse - .split('') - .reverse() - .join(''); + } else { + header += `${key}: ${val}\r\n` + } + } + } + + if (channels.sendHeaders.hasSubscribers) { + channels.sendHeaders.publish({ request, headers: header, socket }) + } + + if (!body || bodyLength === 0) { + writeBuffer(abort, null, client, request, socket, contentLength, header, expectsPayload) + } else if (util.isBuffer(body)) { + writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload) + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable(abort, body.stream(), client, request, socket, contentLength, header, expectsPayload) + } else { + writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload) + } + } else if (util.isStream(body)) { + writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload) + } else if (util.isIterable(body)) { + writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload) + } else { + assert(false) + } + + return true +} + +/** + * @param {AbortCallback} abort + * @param {import('stream').Stream} body + * @param {import('./client.js')} client + * @param {import('../core/request.js')} request + * @param {import('net').Socket} socket + * @param {number} contentLength + * @param {string} header + * @param {boolean} expectsPayload + */ +function writeStream (abort, body, client, request, socket, contentLength, header, expectsPayload) { + assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') + + let finished = false + + const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }) + + /** + * @param {Buffer} chunk + * @returns {void} + */ + const onData = function (chunk) { + if (finished) { + return + } + + try { + if (!writer.write(chunk) && this.pause) { + this.pause() + } + } catch (err) { + util.destroy(this, err) + } + } + + /** + * @returns {void} + */ + const onDrain = function () { + if (finished) { + return + } + + if (body.resume) { + body.resume() + } + } + + /** + * @returns {void} + */ + const onClose = function () { + // 'close' might be emitted *before* 'error' for + // broken streams. Wait a tick to avoid this case. + queueMicrotask(() => { + // It's only safe to remove 'error' listener after + // 'close'. + body.removeListener('error', onFinished) + }) + + if (!finished) { + const err = new RequestAbortedError() + queueMicrotask(() => onFinished(err)) + } + } + + /** + * @param {Error} [err] + * @returns + */ + const onFinished = function (err) { + if (finished) { + return + } + + finished = true + + assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)) + + socket.off('drain', onDrain).off('error', onFinished) + + body.removeListener('data', onData).removeListener('end', onFinished).removeListener('close', onClose) + + if (!err) { + try { + writer.end() + } catch (er) { + err = er + } + } + + writer.destroy(err) + + if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { + util.destroy(body, err) + } else { + util.destroy(body) + } + } + + body.on('data', onData).on('end', onFinished).on('error', onFinished).on('close', onClose) + + if (body.resume) { + body.resume() + } + + socket.on('drain', onDrain).on('error', onFinished) + + if (body.errorEmitted ?? body.errored) { + setImmediate(onFinished, body.errored) + } else if (body.endEmitted ?? body.readableEnded) { + setImmediate(onFinished, null) + } + + if (body.closeEmitted ?? body.closed) { + setImmediate(onClose) + } +} + +/** + * @typedef AbortCallback + * @type {Function} + * @param {Error} [err] + * @returns {void} + */ + +/** + * @param {AbortCallback} abort + * @param {Uint8Array|null} body + * @param {import('./client.js')} client + * @param {import('../core/request.js')} request + * @param {import('net').Socket} socket + * @param {number} contentLength + * @param {string} header + * @param {boolean} expectsPayload + * @returns {void} + */ +function writeBuffer (abort, body, client, request, socket, contentLength, header, expectsPayload) { + try { + if (!body) { + if (contentLength === 0) { + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + assert(contentLength === null, 'no body must not have content length') + socket.write(`${header}\r\n`, 'latin1') + } + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') + + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(body) + socket.uncork() + request.onBodySent(body) + + if (!expectsPayload && request.reset !== false) { + socket[kReset] = true + } } - _uvQuoteCmdArg(arg) { - // Tool runner wraps child_process.spawn() and needs to apply the same quoting as - // Node in certain cases where the undocumented spawn option windowsVerbatimArguments - // is used. - // - // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV, - // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details), - // pasting copyright notice from Node within this function: - // - // Copyright Joyent, Inc. and other Node contributors. All rights reserved. - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to - // deal in the Software without restriction, including without limitation the - // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - // sell copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - // IN THE SOFTWARE. - if (!arg) { - // Need double quotation for empty argument - return '""'; - } - if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { - // No quotation needed - return arg; - } - if (!arg.includes('"') && !arg.includes('\\')) { - // No embedded double quotes or backslashes, so I can just wrap - // quote marks around the whole thing. - return `"${arg}"`; - } - // Expected input/output: - // input : hello"world - // output: "hello\"world" - // input : hello""world - // output: "hello\"\"world" - // input : hello\world - // output: hello\world - // input : hello\\world - // output: hello\\world - // input : hello\"world - // output: "hello\\\"world" - // input : hello\\"world - // output: "hello\\\\\"world" - // input : hello world\ - // output: "hello world\\" - note the comment in libuv actually reads "hello world\" - // but it appears the comment is wrong, it should be "hello world\\" - let reverse = '"'; - let quoteHit = true; - for (let i = arg.length; i > 0; i--) { - // walk the string in reverse - reverse += arg[i - 1]; - if (quoteHit && arg[i - 1] === '\\') { - reverse += '\\'; - } - else if (arg[i - 1] === '"') { - quoteHit = true; - reverse += '\\'; - } - else { - quoteHit = false; - } + request.onRequestSent() + + client[kResume]() + } catch (err) { + abort(err) + } +} + +/** + * @param {AbortCallback} abort + * @param {Blob} body + * @param {import('./client.js')} client + * @param {import('../core/request.js')} request + * @param {import('net').Socket} socket + * @param {number} contentLength + * @param {string} header + * @param {boolean} expectsPayload + * @returns {Promise} + */ +async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) { + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() + } + + const buffer = Buffer.from(await body.arrayBuffer()) + + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(buffer) + socket.uncork() + + request.onBodySent(buffer) + request.onRequestSent() + + if (!expectsPayload && request.reset !== false) { + socket[kReset] = true + } + + client[kResume]() + } catch (err) { + abort(err) + } +} + +/** + * @param {AbortCallback} abort + * @param {Iterable} body + * @param {import('./client.js')} client + * @param {import('../core/request.js')} request + * @param {import('net').Socket} socket + * @param {number} contentLength + * @param {string} header + * @param {boolean} expectsPayload + * @returns {Promise} + */ +async function writeIterable (abort, body, client, request, socket, contentLength, header, expectsPayload) { + assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') + + let callback = null + function onDrain () { + if (callback) { + const cb = callback + callback = null + cb() + } + } + + const waitForDrain = () => + new Promise((resolve, reject) => { + assert(callback === null) + + if (socket[kError]) { + reject(socket[kError]) + } else { + callback = resolve + } + }) + + socket.on('close', onDrain).on('drain', onDrain) + + const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }) + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + if (!writer.write(chunk)) { + await waitForDrain() + } + } + + writer.end() + } catch (err) { + writer.destroy(err) + } finally { + socket.off('close', onDrain).off('drain', onDrain) + } +} + +class AsyncWriter { + /** + * + * @param {object} arg + * @param {AbortCallback} arg.abort + * @param {import('net').Socket} arg.socket + * @param {import('../core/request.js')} arg.request + * @param {number} arg.contentLength + * @param {import('./client.js')} arg.client + * @param {boolean} arg.expectsPayload + * @param {string} arg.header + */ + constructor ({ abort, socket, request, contentLength, client, expectsPayload, header }) { + this.socket = socket + this.request = request + this.contentLength = contentLength + this.client = client + this.bytesWritten = 0 + this.expectsPayload = expectsPayload + this.header = header + this.abort = abort + this.lengthMismatch = false + + socket[kWriting] = true + } + + /** + * The body doesn't match the declared content-length and strictContentLength + * is off. Warn once, and mark the socket so it isn't reused: on the wire this + * request's body no longer ends where the server expects, so anything sent + * after it on the same connection would be misread. + * @returns {void} + */ + onLengthMismatch () { + this.socket[kReset] = true + + if (!this.lengthMismatch) { + this.lengthMismatch = true + process.emitWarning(new RequestContentLengthMismatchError()) + } + } + + /** + * @param {string|Uint8Array} chunk + * @returns + */ + write (chunk) { + const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this + + if (socket[kError]) { + throw socket[kError] + } + + if (socket.destroyed) { + return false + } + + let len = chunk instanceof Uint8Array ? chunk.byteLength : Buffer.byteLength(chunk) + if (!len) { + return true + } + + // We should defer writing chunks. + if (contentLength !== null && bytesWritten + len > contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } + + this.onLengthMismatch() + + // Never write past the declared content-length. The server treats any + // extra bytes as the start of the next request, so a body could inject + // a request of its own (request smuggling). + const remaining = contentLength - bytesWritten + if (remaining === 0) { + return true + } + chunk = (typeof chunk === 'string' ? Buffer.from(chunk) : chunk).subarray(0, remaining) + len = remaining + } + + socket.cork() + + if (bytesWritten === 0) { + if (!expectsPayload && request.reset !== false) { + socket[kReset] = true + } + + if (contentLength === null) { + socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') + } else { + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + } + } + + if (contentLength === null) { + socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') + } + + this.bytesWritten += len + + const ret = socket.write(chunk) + + socket.uncork() + + request.onBodySent(chunk) + + if (!ret) { + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() } - reverse += '"'; - return reverse - .split('') - .reverse() - .join(''); + } } - _cloneExecOptions(options) { - options = options || {}; - const result = { - cwd: options.cwd || process.cwd(), - env: options.env || process.env, - silent: options.silent || false, - windowsVerbatimArguments: options.windowsVerbatimArguments || false, - failOnStdErr: options.failOnStdErr || false, - ignoreReturnCode: options.ignoreReturnCode || false, - delay: options.delay || 10000 - }; - result.outStream = options.outStream || process.stdout; - result.errStream = options.errStream || process.stderr; - return result; + + return ret + } + + /** + * @returns {void} + */ + end () { + const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this + request.onRequestSent() + + socket[kWriting] = false + + if (socket[kError]) { + throw socket[kError] } - _getSpawnOptions(options, toolPath) { - options = options || {}; - const result = {}; - result.cwd = options.cwd; - result.env = options.env; - result['windowsVerbatimArguments'] = - options.windowsVerbatimArguments || this._isCmdFile(); - if (options.windowsVerbatimArguments) { - result.argv0 = `"${toolPath}"`; - } - return result; + + if (socket.destroyed) { + return } - /** - * Exec a tool. - * Output will be streamed to the live console. - * Returns promise with return code - * - * @param tool path to tool to exec - * @param options optional exec options. See ExecOptions - * @returns number - */ - exec() { - return __awaiter(this, void 0, void 0, function* () { - // root the tool path if it is unrooted and contains relative pathing - if (!ioUtil.isRooted(this.toolPath) && - (this.toolPath.includes('/') || - (IS_WINDOWS && this.toolPath.includes('\\')))) { - // prefer options.cwd if it is specified, however options.cwd may also need to be rooted - this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); - } - // if the tool is only a file name, then resolve it from the PATH - // otherwise verify it exists (add extension on Windows if necessary) - this.toolPath = yield io.which(this.toolPath, true); - return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { - this._debug(`exec tool: ${this.toolPath}`); - this._debug('arguments:'); - for (const arg of this.args) { - this._debug(` ${arg}`); - } - const optionsNonNull = this._cloneExecOptions(this.options); - if (!optionsNonNull.silent && optionsNonNull.outStream) { - optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); - } - const state = new ExecState(optionsNonNull, this.toolPath); - state.on('debug', (message) => { - this._debug(message); - }); - if (this.options.cwd && !(yield ioUtil.exists(this.options.cwd))) { - return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`)); - } - const fileName = this._getSpawnFileName(); - const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); - let stdbuffer = ''; - if (cp.stdout) { - cp.stdout.on('data', (data) => { - if (this.options.listeners && this.options.listeners.stdout) { - this.options.listeners.stdout(data); - } - if (!optionsNonNull.silent && optionsNonNull.outStream) { - optionsNonNull.outStream.write(data); - } - stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => { - if (this.options.listeners && this.options.listeners.stdline) { - this.options.listeners.stdline(line); - } - }); - }); - } - let errbuffer = ''; - if (cp.stderr) { - cp.stderr.on('data', (data) => { - state.processStderr = true; - if (this.options.listeners && this.options.listeners.stderr) { - this.options.listeners.stderr(data); - } - if (!optionsNonNull.silent && - optionsNonNull.errStream && - optionsNonNull.outStream) { - const s = optionsNonNull.failOnStdErr - ? optionsNonNull.errStream - : optionsNonNull.outStream; - s.write(data); - } - errbuffer = this._processLineBuffer(data, errbuffer, (line) => { - if (this.options.listeners && this.options.listeners.errline) { - this.options.listeners.errline(line); - } - }); - }); - } - cp.on('error', (err) => { - state.processError = err.message; - state.processExited = true; - state.processClosed = true; - state.CheckComplete(); - }); - cp.on('exit', (code) => { - state.processExitCode = code; - state.processExited = true; - this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); - state.CheckComplete(); - }); - cp.on('close', (code) => { - state.processExitCode = code; - state.processExited = true; - state.processClosed = true; - this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); - state.CheckComplete(); - }); - state.on('done', (error, exitCode) => { - if (stdbuffer.length > 0) { - this.emit('stdline', stdbuffer); - } - if (errbuffer.length > 0) { - this.emit('errline', errbuffer); - } - cp.removeAllListeners(); - if (error) { - reject(error); - } - else { - resolve(exitCode); - } - }); - if (this.options.input) { - if (!cp.stdin) { - throw new Error('child process missing stdin'); - } - cp.stdin.end(this.options.input); - } - })); - }); + + if (bytesWritten === 0) { + if (expectsPayload) { + // 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. + + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + socket.write(`${header}\r\n`, 'latin1') + } + } else if (contentLength === null) { + socket.write('\r\n0\r\n\r\n', 'latin1') + } + + if (contentLength !== null && bytesWritten !== contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } + + // The body is shorter than declared, so the server is still waiting for + // the rest. Don't let the next request's bytes on this connection be + // read as the missing part of this body. + this.onLengthMismatch() + } + + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } + } + + client[kResume]() + } + + /** + * @param {Error} [err] + * @returns {void} + */ + destroy (err) { + const { socket, client, abort } = this + + socket[kWriting] = false + + if (err) { + assert(client[kRunning] <= 1, 'pipeline should only contain this request') + abort(err) } + } +} + +module.exports = connectH1 + + +/***/ }), + +/***/ 8788: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(4589) +const { pipeline } = __nccwpck_require__(7075) +const util = __nccwpck_require__(3440) +const { + RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, + RequestAbortedError, + SocketError, + InformationalError, + InvalidArgumentError, + HeadersTimeoutError, + BodyTimeoutError, + ResponseExceededMaxSizeError +} = __nccwpck_require__(8707) +const { + kUrl, + kReset, + kClient, + kRunning, + kPending, + kQueue, + kPendingIdx, + kRunningIdx, + kError, + kSocket, + kStrictContentLength, + kOnError, + kMaxConcurrentStreams, + kHTTP2Session, + kHostAuthority, + kResume, + kSize, + kHTTPContext, + kClosed, + kKeepAliveDefaultTimeout, + kHeadersTimeout, + kBodyTimeout, + kEnableConnectProtocol, + kRemoteSettings, + kHTTP2Stream, + kHTTP2SessionState, + kHTTP2Options, + kMaxResponseSize +} = __nccwpck_require__(6443) +const { channels } = __nccwpck_require__(2414) + +const kOpenStreams = Symbol('open streams') +const kRequestStreamId = Symbol('request stream id') +const kRequestStream = Symbol('request stream') +const kRequestStreamCleanup = Symbol('request stream cleanup') +const kRequestStreamState = Symbol('request stream state') +const kReceivedGoAway = Symbol('received goaway') +const kGoAwayReplayAttempts = Symbol('goaway replay attempts') +const kRefusedStreamRetry = Symbol('refused stream retry') + +// RFC 9113 section 8.7: a client SHOULD NOT automatically retry a request more +// than once. Without a budget a peer that keeps refusing turns one request into +// an unbounded connect/refuse/reconnect loop that never settles and starves the +// event loop. +const MAX_GOAWAY_REPLAY_ATTEMPTS = 1 + +let extractBody + +/** @type {import('http2')} */ +let http2 +try { + http2 = __nccwpck_require__(2467) +} catch { + // @ts-ignore + http2 = { constants: {} } } -exports.ToolRunner = ToolRunner; -/** - * Convert an arg string to an array of args. Handles escaping - * - * @param argString string of arguments - * @returns string[] array of arguments - */ -function argStringToArray(argString) { - const args = []; - let inQuotes = false; - let escaped = false; - let arg = ''; - function append(c) { - // we only escape double quotes. - if (escaped && c !== '"') { - arg += '\\'; - } - arg += c; - escaped = false; - } - for (let i = 0; i < argString.length; i++) { - const c = argString.charAt(i); - if (c === '"') { - if (!escaped) { - inQuotes = !inQuotes; - } - else { - append(c); - } - continue; - } - if (c === '\\' && escaped) { - append(c); - continue; - } - if (c === '\\' && inQuotes) { - escaped = true; - continue; - } - if (c === ' ' && !inQuotes) { - if (arg.length > 0) { - args.push(arg); - arg = ''; - } - continue; - } - append(c); - } - if (arg.length > 0) { - args.push(arg.trim()); - } - return args; + +const { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS, + HTTP2_HEADER_PROTOCOL, + NGHTTP2_NO_ERROR, + NGHTTP2_REFUSED_STREAM + } +} = http2 + +function getGoAwayError (session, errorCode) { + return session[kError] || + (errorCode === NGHTTP2_NO_ERROR + ? new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${errorCode}`) + : new SocketError(`HTTP/2: "GOAWAY" frame received with code ${errorCode}`, util.getSocketInfo(session[kSocket]))) } -exports.argStringToArray = argStringToArray; -class ExecState extends events.EventEmitter { - constructor(options, toolPath) { - super(); - this.processClosed = false; // tracks whether the process has exited and stdio is closed - this.processError = ''; - this.processExitCode = 0; - this.processExited = false; // tracks whether the process has exited - this.processStderr = false; // tracks whether stderr was written to - this.delay = 10000; // 10 seconds - this.done = false; - this.timeout = null; - if (!toolPath) { - throw new Error('toolPath must not be empty'); - } - this.options = options; - this.toolPath = toolPath; - if (options.delay) { - this.delay = options.delay; - } - } - CheckComplete() { - if (this.done) { - return; - } - if (this.processClosed) { - this._setResult(); - } - else if (this.processExited) { - this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this); - } + +function resetHttp2Session (session, err) { + const client = session[kClient] + const socket = session[kSocket] + + if (client[kHTTP2Session] === session) { + client[kSocket] = null + client[kHTTPContext] = null + client[kHTTP2Session] = null + } + + if (socket != null && socket[kError] == null) { + socket[kError] = err + } + + if (!session.closed && !session.destroyed) { + try { + session.destroy(err) + } catch {} + } + + util.destroy(socket, err) +} + +function getGoAwayPendingIdx (client, lastStreamID) { + const maxAcceptedStreamID = Number.isInteger(lastStreamID) ? lastStreamID : Number.MAX_SAFE_INTEGER + + for (let i = client[kRunningIdx]; i < client[kPendingIdx]; i++) { + const request = client[kQueue][i] + + if (request == null) { + continue } - _debug(message) { - this.emit('debug', message); + + if (typeof request[kRequestStreamId] !== 'number' || request[kRequestStreamId] > maxAcceptedStreamID) { + return i } - _setResult() { - // determine whether there is an error - let error; - if (this.processExited) { - if (this.processError) { - error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); - } - else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { - error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); - } - else if (this.processStderr && this.options.failOnStdErr) { - error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); - } - } - // clear the timeout - if (this.timeout) { - clearTimeout(this.timeout); - this.timeout = null; - } - this.done = true; - this.emit('done', error, this.processExitCode); + } + + return client[kPendingIdx] +} + +function detachRequestFromStream (request) { + request[kRequestStreamId] = null + request[kRequestStream] = null + request[kRequestStreamCleanup] = null +} + +function bindRequestToStream (request, stream, cleanup) { + const previousCleanup = request[kRequestStreamCleanup] + const previousStream = request[kRequestStream] + detachRequestFromStream(request) + previousCleanup?.(previousStream) + request[kRequestStreamId] = stream.id + request[kRequestStream] = stream + request[kRequestStreamCleanup] = cleanup +} + +function clearRequestStream (request) { + const cleanup = request[kRequestStreamCleanup] + const stream = request[kRequestStream] + detachRequestFromStream(request) + cleanup?.(stream) +} + +function requeueUnsentRequest (client, request) { + client[kQueue].splice(client[kPendingIdx] + 1, 0, request) +} + +function completeRequest (client, request, resetPendingIdx = false) { + const queue = client[kQueue] + const runningIdx = client[kRunningIdx] + + // In-order completion: clear the request and advance without splicing. + // The client's resume loop compacts cleared slots once the index grows. + if (runningIdx < client[kPendingIdx] && queue[runningIdx] === request) { + queue[runningIdx] = null + client[kRunningIdx] = runningIdx + 1 + return + } + + const index = queue.indexOf(request, runningIdx) + + if (index === -1 || index >= client[kPendingIdx]) { + return + } + + queue.splice(index, 1) + client[kPendingIdx]-- + + if (resetPendingIdx && client[kPendingIdx] < client[kRunningIdx]) { + client[kPendingIdx] = client[kRunningIdx] + } +} + +function canReplayRequest (request) { + const { body } = request + + return body == null || util.isBuffer(body) || util.isBlobLike(body) +} + +function hasResponseStarted (request) { + const state = request[kRequestStream]?.[kRequestStreamState] + return state?.responseReceived === true +} + +// Count a GOAWAY refusal against the request's replay budget. A peer that +// refuses every connection must eventually surface an error to the caller +// rather than being retried forever. Kept separate from canReplayRequest so +// that the REFUSED_STREAM retry, which has its own single-attempt limit, does +// not consume this budget just by asking whether the body can be replayed. +function registerGoAwayRefusal (request) { + const attempts = (request[kGoAwayReplayAttempts] ?? 0) + 1 + request[kGoAwayReplayAttempts] = attempts + + return attempts <= MAX_GOAWAY_REPLAY_ATTEMPTS +} + +function closeStream (stream, code = NGHTTP2_REFUSED_STREAM) { + if (stream != null && !stream.destroyed && !stream.closed) { + try { + stream.close(code) + } catch {} + } +} + +function detachRequestStreamForClose (request) { + const stream = request[kRequestStream] + + clearRequestStream(request) + severRequestStream(stream) + + return stream +} + +// Unbind a stream from its request for good. releaseRequestStream() alone +// leaves the 'close' listener attached and kRequestStreamState populated, so a +// stream abandoned here would still run completeRequestStream() later — and +// splice out the request that has since been requeued onto another session. +function severRequestStream (stream) { + if (stream == null || stream[kRequestStreamState] == null) { + return + } + + stream[kRequestStreamState] = null + stream.off('close', completeRequestStream) + // Upgrade streams use their own close cleanup, which would otherwise release + // the session a second time after the stream has been severed for GOAWAY. + stream.off('close', onUpgradeStreamClose) + + if (stream[kHTTP2Session] != null) { + closeStreamSession(stream) + } + + if (!stream.destroyed && !stream.closed) { + stream.once('error', noop) + } +} + +function connectH2 (client, socket) { + client[kSocket] = socket + + const http2InitialWindowSize = client[kHTTP2Options].sessionOptions?.initialWindowSize + const http2ConnectionWindowSize = client[kHTTP2Options].connectionWindowSize + + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: client[kHTTP2Options].maxConcurrentStreams, + settings: { + // TODO(metcoder95): add support for PUSH + enablePush: false, + ...(http2InitialWindowSize != null ? { initialWindowSize: http2InitialWindowSize } : null) } - static HandleTimeout(state) { - if (state.done) { - return; - } - if (!state.processClosed && state.processExited) { - const message = `The STDIO streams did not close within ${state.delay / - 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`; - state._debug(message); + }) + + client[kSocket] = socket + session[kOpenStreams] = 0 + session[kClient] = client + session[kSocket] = socket + session[kHTTP2SessionState] = { + idleTimeout: null, + // Armed while the peer advertises MAX_CONCURRENT_STREAMS = 0 and we have + // work that cannot start. See setNoStreamsTimeout. + noStreamsTimeout: null, + // Sockets start out ref'd. Session ref/unref proxies to the socket, so a + // single cached flag lets us skip redundant uv ref/unref calls, provided + // every ref/unref of the session or its socket goes through + // refH2Session/unrefH2Session. + refed: true, + ping: { + interval: client[kHTTP2Options].pingInterval === 0 ? null : setInterval(onHttp2SendPing, client[kHTTP2Options].pingInterval, session).unref() + } + } + session[kReceivedGoAway] = false + // We set it to true by default in a best-effort; however once connected to an H2 server + // we will check if extended CONNECT protocol is supported or not + // and set this value accordingly. + session[kEnableConnectProtocol] = false + // States whether or not we have received the remote settings from the server + session[kRemoteSettings] = false + + // Apply connection-level flow control once connected (if supported). + if (http2ConnectionWindowSize) { + util.addListener(session, 'connect', applyConnectionWindowSize.bind(session, http2ConnectionWindowSize)) + } + + util.addListener(session, 'error', onHttp2SessionError) + util.addListener(session, 'frameError', onHttp2FrameError) + util.addListener(session, 'goaway', onHttp2SessionGoAway) + util.addListener(session, 'close', onHttp2SessionClose) + util.addListener(session, 'remoteSettings', onHttp2RemoteSettings) + // TODO (@metcoder95): implement SETTINGS support + // util.addListener(session, 'localSettings', onHttp2RemoteSettings) + + unrefH2Session(session) + + client[kHTTP2Session] = session + socket[kHTTP2Session] = session + + util.addListener(socket, 'error', onHttp2SocketError) + util.addListener(socket, 'end', onHttp2SocketEnd) + util.addListener(socket, 'close', onHttp2SocketClose) + + socket[kClosed] = false + socket.on('close', onSocketClose) + + return { + version: 'h2', + defaultPipelining: Infinity, + /** + * @param {import('../core/request.js')} request + * @returns {boolean} + */ + write (request) { + return writeH2(client, request) + }, + /** + * @returns {void} + */ + resume () { + resumeH2(client) + }, + /** + * @param {Error | null} err + * @param {() => void} callback + */ + destroy (err, callback) { + if (socket[kClosed]) { + queueMicrotask(callback) + } else { + socket.destroy(err).on('close', callback) + } + }, + /** + * @type {boolean} + */ + get destroyed () { + return socket.destroyed + }, + /** + * @param {import('../core/request.js')} request + * @returns {boolean} + */ + busy (request) { + if (session[kRemoteSettings] === false && client[kRunning] > 0) { + return true + } + + if (client[kRunning] >= client[kMaxConcurrentStreams]) { + return true + } + + if (request != null) { + if (client[kRunning] > 0) { + // We are already processing requests + + // Unlike HTTP/1.1 pipelining, HTTP/2 multiplexes requests on + // independent streams, so non-idempotent requests can be dispatched + // concurrently. Retry eligibility is handled by stream/session error + // handling instead of by serializing all non-idempotent requests. + // Don't dispatch an upgrade until all preceding requests have completed. + // Possibly, we do not have remote settings confirmed yet. + if ((request.upgrade === 'websocket' || request.method === 'CONNECT') && session[kRemoteSettings] === false) return true + } else { + return (request.upgrade === 'websocket' || request.method === 'CONNECT') && session[kRemoteSettings] === false } - state._setResult(); + } + + return false } + } } -//# sourceMappingURL=toolrunner.js.map -/***/ }), +// Session ref/unref proxies to the underlying socket, so refH2Session and +// unrefH2Session cover both and can skip the call when the cached ref state +// already matches. +function refH2Session (session) { + const state = session[kHTTP2SessionState] -/***/ 4552: -/***/ (function(__unused_webpack_module, exports) { + if (state.refed === false) { + state.refed = true + session.ref() + } +} -"use strict"; +function unrefH2Session (session) { + const state = session[kHTTP2SessionState] -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; -class BasicCredentialHandler { - constructor(username, password) { - this.username = username; - this.password = password; - } - prepareRequest(options) { - if (!options.headers) { - throw Error('The request has no headers'); - } - options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; + if (state.refed === true) { + state.refed = false + session.unref() + } +} + +function resumeH2 (client) { + const socket = client[kSocket] + const session = client[kHTTP2Session] + + if (socket?.destroyed === false) { + // After an upgrade the queue is empty but its stream is still in use, so never unref while a stream is open. + if (session[kOpenStreams] === 0 && client[kSize] === 0) { + unrefH2Session(session) + } else { + refH2Session(session) } - // This handler cannot handle 401 - canHandleAuthentication() { - return false; + + if (client[kSize] === 0 && session[kOpenStreams] === 0) { + setHttp2IdleTimeout(session) + } else { + clearHttp2IdleTimeout(session) } - handleAuthentication() { - return __awaiter(this, void 0, void 0, function* () { - throw new Error('not implemented'); - }); + + if (client[kMaxConcurrentStreams] === 0 && client[kRunning] === 0 && client[kPending] > 0) { + setNoStreamsTimeout(session) + } else { + clearNoStreamsTimeout(session) } + } } -exports.BasicCredentialHandler = BasicCredentialHandler; -class BearerCredentialHandler { - constructor(token) { - this.token = token; - } - // currently implements pre-authorization - // TODO: support preAuth = false where it hooks on 401 - prepareRequest(options) { - if (!options.headers) { - throw Error('The request has no headers'); - } - options.headers['Authorization'] = `Bearer ${this.token}`; + +function clearNoStreamsTimeout (session) { + const state = session[kHTTP2SessionState] + + if (state?.noStreamsTimeout != null) { + clearTimeout(state.noStreamsTimeout) + state.noStreamsTimeout = null + } +} + +// A peer is allowed to advertise SETTINGS_MAX_CONCURRENT_STREAMS = 0 to refuse +// new streams (RFC 9113 §6.5.2), and is expected to raise it again later. Until +// it does, busy() reports the client as permanently busy and queued requests +// cannot open a stream — which means no per-stream timeout covers them, and no +// reconnect can happen either, so the SETTINGS frame that would lift the limit +// can never arrive. Give the peer headersTimeout to start honouring requests +// before failing them; a request that cannot even be sent has missed the same +// deadline as one whose headers never arrive. +function setNoStreamsTimeout (session) { + const client = session[kClient] + const state = session[kHTTP2SessionState] + const timeout = client[kHeadersTimeout] + + if (!timeout || state.noStreamsTimeout != null) { + return + } + + state.noStreamsTimeout = setTimeout(onNoStreamsTimeout, timeout, session).unref() +} + +function onNoStreamsTimeout (session) { + const client = session[kClient] + const state = session[kHTTP2SessionState] + + state.noStreamsTimeout = null + + if ( + client[kHTTP2Session] !== session || + client[kMaxConcurrentStreams] !== 0 || + client[kRunning] !== 0 || + client[kPending] === 0 + ) { + return + } + + const err = new HeadersTimeoutError( + `HTTP/2: server did not accept a new stream within ${client[kHeadersTimeout]}` + ) + + const requests = client[kQueue].splice(client[kPendingIdx]) + for (let i = 0; i < requests.length; i++) { + if (requests[i] != null) { + util.errorRequest(client, requests[i], err) } - // This handler cannot handle 401 - canHandleAuthentication() { - return false; + } + + // Drop the unusable session so the next request gets a fresh connection, + // whose SETTINGS may well allow streams again. + session[kError] = err + resetHttp2Session(session, err) +} + +function clearHttp2IdleTimeout (session) { + const state = session[kHTTP2SessionState] + + if (state?.idleTimeout != null) { + clearTimeout(state.idleTimeout) + state.idleTimeout = null + } +} + +function setHttp2IdleTimeout (session) { + const client = session[kClient] + + if (client[kHTTP2Session] !== session || session.closed || session.destroyed) { + return + } + + if (session[kOpenStreams] !== 0 || client[kSize] !== 0) { + clearHttp2IdleTimeout(session) + return + } + + const state = session[kHTTP2SessionState] + if (state.idleTimeout == null) { + state.idleTimeout = setTimeout(onHttp2SessionIdleTimeout, client[kKeepAliveDefaultTimeout], session).unref() + } +} + +function onHttp2SessionIdleTimeout (session) { + const client = session[kClient] + const socket = session[kSocket] + const state = session[kHTTP2SessionState] + + state.idleTimeout = null + + if (client[kHTTP2Session] !== session || session[kOpenStreams] !== 0 || client[kSize] !== 0 || session.closed || session.destroyed) { + return + } + + const err = new InformationalError('socket idle timeout') + socket[kError] = err + util.destroy(socket, err) +} + +function applyConnectionWindowSize (connectionWindowSize) { + try { + if (typeof this.setLocalWindowSize === 'function') { + this.setLocalWindowSize(connectionWindowSize) } - handleAuthentication() { - return __awaiter(this, void 0, void 0, function* () { - throw new Error('not implemented'); - }); + } catch { + // Best-effort only. + } +} + +function onHttp2RemoteSettings (settings) { + const client = this[kClient] + + // The configured maxConcurrentStreams (default 100) is the client's own + // ceiling. The server's SETTINGS_MAX_CONCURRENT_STREAMS can lower it, but + // must not raise it: a default Node.js server advertises 2^32-1. + const localMaxConcurrentStreams = client[kHTTP2Options].maxConcurrentStreams + const remoteMaxConcurrentStreams = settings.maxConcurrentStreams ?? client[kMaxConcurrentStreams] ?? localMaxConcurrentStreams + client[kMaxConcurrentStreams] = Math.min(remoteMaxConcurrentStreams, localMaxConcurrentStreams) + /** + * From RFC-8441 + * A sender MUST NOT send a SETTINGS_ENABLE_CONNECT_PROTOCOL parameter + * with the value of 0 after previously sending a value of 1. + */ + // Note: Cannot be tested in Node, it does not supports disabling the extended CONNECT protocol once enabled + if (this[kRemoteSettings] === true && this[kEnableConnectProtocol] === true && settings.enableConnectProtocol === false) { + const err = new InformationalError('HTTP/2: Server disabled extended CONNECT protocol against RFC-8441') + this[kSocket][kError] = err + this[kClient][kOnError](err) + return + } + + this[kEnableConnectProtocol] = settings.enableConnectProtocol ?? this[kEnableConnectProtocol] + this[kRemoteSettings] = true + this[kClient][kResume]() +} + +function onHttp2SendPing (session) { + const state = session[kHTTP2SessionState] + if ((session.closed || session.destroyed) && state.ping.interval != null) { + clearInterval(state.ping.interval) + state.ping.interval = null + return + } + + // If no ping sent, do nothing + session.ping(onPing.bind(session)) + + function onPing (err, duration) { + const client = this[kClient] + const socket = this[kSocket] + + if (err != null) { + const error = new InformationalError(`HTTP/2: "PING" errored - type ${err.message}`) + socket[kError] = error + client[kOnError](error) + } else { + client.emit('ping', duration) } + } } -exports.BearerCredentialHandler = BearerCredentialHandler; -class PersonalAccessTokenCredentialHandler { - constructor(token) { - this.token = token; + +function onHttp2SessionError (err) { + this[kSocket][kError] = err + + if (this[kReceivedGoAway]) { + return + } + + this[kClient][kOnError](err) +} + +function onHttp2FrameError (type, code, id) { + if (id === 0) { + if (this[kReceivedGoAway]) { + return } - // currently implements pre-authorization - // TODO: support preAuth = false where it hooks on 401 - prepareRequest(options) { - if (!options.headers) { - throw Error('The request has no headers'); - } - options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; + + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) + this[kSocket][kError] = err + this[kClient][kOnError](err) + } +} + +/** + * This is the root cause of #3011 + * We need to handle GOAWAY frames properly, and trigger the session close + * along with the socket right away + * + * @this {import('http2').ClientHttp2Session} + * @param {number} errorCode + * @param {number} lastStreamID + */ +function onHttp2SessionGoAway (errorCode, lastStreamID) { + if (this[kReceivedGoAway]) { + return + } + + this[kReceivedGoAway] = true + + const err = getGoAwayError(this, errorCode) + const client = this[kClient] + const previousPendingIdx = client[kPendingIdx] + const pendingIdx = getGoAwayPendingIdx(client, lastStreamID) + const retriableRequests = [] + const streamsToClose = [] + + // Closing one stream after GOAWAY can synchronously emit frameError on + // sibling streams. Detach all affected requests first so those errors do + // not fail requests that are about to be requeued. + for (let i = pendingIdx; i < previousPendingIdx; i++) { + const request = client[kQueue][i] + + if (request != null) { + // Read before detaching, which drops the stream state. + const responseStarted = hasResponseStarted(request) + + streamsToClose.push(detachRequestStreamForClose(request)) + + if (!responseStarted && canReplayRequest(request) && registerGoAwayRefusal(request)) { + retriableRequests.push(request) + } else { + util.errorRequest(client, request, err) + } } - // This handler cannot handle 401 - canHandleAuthentication() { - return false; + } + + for (let i = 0; i < streamsToClose.length; i++) { + closeStream(streamsToClose[i]) + } + + if (pendingIdx !== previousPendingIdx) { + const remainingPendingRequests = client[kQueue].slice(previousPendingIdx) + client[kQueue].length = pendingIdx + client[kQueue].push(...retriableRequests, ...remainingPendingRequests) + } + + if (client[kHTTP2Session] === this) { + client[kSocket] = null + client[kHTTPContext] = null + client[kHTTP2Session] = null + } + + if (this[kOpenStreams] === 0) { + unrefH2Session(this) + } + + clearHttp2IdleTimeout(this) + clearNoStreamsTimeout(this) + + if (!this.closed && !this.destroyed) { + this.close() + } + + client[kPendingIdx] = pendingIdx + + client.emit('disconnect', client[kUrl], [client], err) + + client[kResume]() +} + +function onHttp2SessionClose () { + const { [kClient]: client, [kHTTP2SessionState]: state, [kSocket]: socket } = this + + const err = socket[kError] || this[kError] || new SocketError('closed', util.getSocketInfo(socket)) + + if (client[kHTTP2Session] === this) { + client[kSocket] = null + client[kHTTPContext] = null + client[kHTTP2Session] = null + } + + clearHttp2IdleTimeout(this) + clearNoStreamsTimeout(this) + + if (state.ping.interval != null) { + clearInterval(state.ping.interval) + state.ping.interval = null + } + + if (client.destroyed) { + assert(client[kPending] === 0) + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + if (request != null) { + util.errorRequest(client, request, err) + } } - handleAuthentication() { - return __awaiter(this, void 0, void 0, function* () { - throw new Error('not implemented'); - }); + } +} + +function onHttp2SocketClose () { + const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) + + const session = this[kHTTP2Session] + const client = session[kClient] + + if (client[kSocket] !== this) { + // Ignore stale socket closes from a detached GOAWAY session and from any + // session that has already been replaced. If the session was detached + // without a GOAWAY and there is no replacement yet, we still need the + // close event to flush the client state. + if (session[kReceivedGoAway] || (client[kHTTP2Session] != null && client[kHTTP2Session] !== session)) { + return } + } + + client[kSocket] = null + client[kHTTPContext] = null + if (client[kHTTP2Session] === session) { + client[kHTTP2Session] = null + } + + session.destroy(err) + + client[kPendingIdx] = client[kRunningIdx] + + assert(client[kRunning] === 0) + + client.emit('disconnect', client[kUrl], [client], err) + + client[kResume]() +} + +function onHttp2SocketError (err) { + this[kError] = err + + if (this[kHTTP2Session]?.[kReceivedGoAway]) { + return + } + + this[kHTTP2Session]?.[kClient]?.[kOnError](err) +} + +function onHttp2SocketEnd () { + util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) +} + +function onSocketClose () { + this[kClosed] = true } -exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; -//# sourceMappingURL=auth.js.map -/***/ }), +function noop () {} -/***/ 4844: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +function closeStreamSession (stream) { + const session = stream[kHTTP2Session] + const client = session[kClient] -"use strict"; + stream[kHTTP2Session] = null + session[kOpenStreams] -= 1 + // A session that received GOAWAY does not need to stay ref'd for queued requests. + if (session[kOpenStreams] === 0 && (client[kSize] === 0 || session[kReceivedGoAway])) { + unrefH2Session(session) + setHttp2IdleTimeout(session) + } +} -/* eslint-disable @typescript-eslint/no-explicit-any */ -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; -const http = __importStar(__nccwpck_require__(8611)); -const https = __importStar(__nccwpck_require__(5692)); -const pm = __importStar(__nccwpck_require__(4988)); -const tunnel = __importStar(__nccwpck_require__(770)); -const undici_1 = __nccwpck_require__(6752); -var HttpCodes; -(function (HttpCodes) { - HttpCodes[HttpCodes["OK"] = 200] = "OK"; - HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; - HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; - HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; - HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; - HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; - HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; - HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; - HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; - HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; - HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; - HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; - HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; - HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; - HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; - HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; - HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; - HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; - HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; - HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; - HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; - HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; - HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; - HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; - HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; - HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; - HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; -})(HttpCodes || (exports.HttpCodes = HttpCodes = {})); -var Headers; -(function (Headers) { - Headers["Accept"] = "accept"; - Headers["ContentType"] = "content-type"; -})(Headers || (exports.Headers = Headers = {})); -var MediaTypes; -(function (MediaTypes) { - MediaTypes["ApplicationJson"] = "application/json"; -})(MediaTypes || (exports.MediaTypes = MediaTypes = {})); -/** - * Returns the proxy URL, depending upon the supplied url and proxy environment variables. - * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com - */ -function getProxyUrl(serverUrl) { - const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); - return proxyUrl ? proxyUrl.href : ''; +function onUpgradeStreamClose () { + this.off('error', noop) + + const state = this[kRequestStreamState] + this[kRequestStreamState] = null + + failUpgradeStream(state, new InformationalError('HTTP/2: stream closed before response headers')) + closeStreamSession(this) } -exports.getProxyUrl = getProxyUrl; -const HttpRedirectCodes = [ - HttpCodes.MovedPermanently, - HttpCodes.ResourceMoved, - HttpCodes.SeeOther, - HttpCodes.TemporaryRedirect, - HttpCodes.PermanentRedirect -]; -const HttpResponseRetryCodes = [ - HttpCodes.BadGateway, - HttpCodes.ServiceUnavailable, - HttpCodes.GatewayTimeout -]; -const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; -const ExponentialBackoffCeiling = 10; -const ExponentialBackoffTimeSlice = 5; -class HttpClientError extends Error { - constructor(message, statusCode) { - super(message); - this.name = 'HttpClientError'; - this.statusCode = statusCode; - Object.setPrototypeOf(this, HttpClientError.prototype); - } + +// Idempotent terminal cleanup, called from both 'end' and 'close': the +// null-state guard no-ops the later call. +function completeRequestStream () { + const state = this[kRequestStreamState] + + if (state == null) { + return + } + + // Release the stream first so request references are cleared, + // then complete the response with trailers if available. + releaseRequestStream(this) + + if (state.pendingEnd && !state.request.aborted && !state.request.completed) { + state.request.onResponseEnd(state.trailers || {}) + } else if (!state.request.aborted && !state.request.completed) { + // The stream closed without a complete response and without reporting an + // error. finalizeRequest() below frees the queue slot either way, so + // without this the request would simply vanish and its caller would never + // hear back. + util.errorRequest( + state.client, + state.request, + new InformationalError('HTTP/2: stream closed before the response was complete') + ) + } + + finalizeRequest(state) + closeStreamSession(this) + this[kRequestStreamState] = null } -exports.HttpClientError = HttpClientError; -class HttpClientResponse { - constructor(message) { - this.message = message; + +// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 +function shouldSendContentLength (method) { + return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' +} + +function buildRequestHeaders (reqHeaders) { + const headers = {} + + for (let n = 0; n < reqHeaders.length; n += 2) { + const key = reqHeaders[n + 0] + const val = reqHeaders[n + 1] + // Reading headers[key] directly resolves `__proto__` through the prototype + // chain instead of reporting the header as absent. + const current = Object.hasOwn(headers, key) ? headers[key] : undefined + + if (key === 'cookie') { + if (current != null) { + util.setHeader(headers, key, Array.isArray(current) ? (current.push(val), current) : [current, val]) + } else { + util.setHeader(headers, key, val) + } + + continue } - readBody() { - return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { - let output = Buffer.alloc(0); - this.message.on('data', (chunk) => { - output = Buffer.concat([output, chunk]); - }); - this.message.on('end', () => { - resolve(output.toString()); - }); - })); - }); + + if (typeof val === 'string') { + util.setHeader(headers, key, current ? `${current}, ${val}` : val) + continue } - readBodyBuffer() { - return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { - const chunks = []; - this.message.on('data', (chunk) => { - chunks.push(chunk); - }); - this.message.on('end', () => { - resolve(Buffer.concat(chunks)); - }); - })); - }); + + for (let i = 0; i < val.length; i++) { + util.setHeader(headers, key, Object.hasOwn(headers, key) ? `${headers[key]}, ${val[i]}` : val[i]) } + } + + return headers } -exports.HttpClientResponse = HttpClientResponse; -function isHttps(requestUrl) { - const parsedUrl = new URL(requestUrl); - return parsedUrl.protocol === 'https:'; + +function removeUpgradeStreamListeners (stream) { + stream.off('response', onUpgradeResponse) + stream.off('error', onUpgradeStreamError) + stream.off('end', onUpgradeStreamEnd) + stream.off('timeout', onUpgradeStreamTimeout) + stream.off('error', noop) } -exports.isHttps = isHttps; -class HttpClient { - constructor(userAgent, handlers, requestOptions) { - this._ignoreSslError = false; - this._allowRedirects = true; - this._allowRedirectDowngrade = false; - this._maxRedirects = 50; - this._allowRetries = false; - this._maxRetries = 1; - this._keepAlive = false; - this._disposed = false; - this.userAgent = userAgent; - this.handlers = handlers || []; - this.requestOptions = requestOptions; - if (requestOptions) { - if (requestOptions.ignoreSslError != null) { - this._ignoreSslError = requestOptions.ignoreSslError; - } - this._socketTimeout = requestOptions.socketTimeout; - if (requestOptions.allowRedirects != null) { - this._allowRedirects = requestOptions.allowRedirects; - } - if (requestOptions.allowRedirectDowngrade != null) { - this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; - } - if (requestOptions.maxRedirects != null) { - this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); - } - if (requestOptions.keepAlive != null) { - this._keepAlive = requestOptions.keepAlive; - } - if (requestOptions.allowRetries != null) { - this._allowRetries = requestOptions.allowRetries; - } - if (requestOptions.maxRetries != null) { - this._maxRetries = requestOptions.maxRetries; - } - } - } - options(requestUrl, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); - }); - } - get(requestUrl, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request('GET', requestUrl, null, additionalHeaders || {}); - }); - } - del(requestUrl, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request('DELETE', requestUrl, null, additionalHeaders || {}); - }); - } - post(requestUrl, data, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request('POST', requestUrl, data, additionalHeaders || {}); - }); - } - patch(requestUrl, data, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request('PATCH', requestUrl, data, additionalHeaders || {}); - }); - } - put(requestUrl, data, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request('PUT', requestUrl, data, additionalHeaders || {}); - }); - } - head(requestUrl, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request('HEAD', requestUrl, null, additionalHeaders || {}); - }); - } - sendStream(verb, requestUrl, stream, additionalHeaders) { - return __awaiter(this, void 0, void 0, function* () { - return this.request(verb, requestUrl, stream, additionalHeaders); - }); - } - /** - * Gets a typed object from an endpoint - * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise - */ - getJson(requestUrl, additionalHeaders = {}) { - return __awaiter(this, void 0, void 0, function* () { - additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); - const res = yield this.get(requestUrl, additionalHeaders); - return this._processResponse(res, this.requestOptions); - }); + +function releaseUpgradeStream (stream) { + if (stream == null) { + return + } + + const state = stream[kRequestStreamState] + if (state == null) { + return + } + + const { request } = state + + if (request[kRequestStream] === stream) { + detachRequestFromStream(request) + } + + removeUpgradeStreamListeners(stream) + + if (!stream.destroyed && !stream.closed) { + stream.once('error', noop) + } +} + +function failUpgradeStream (state, err) { + if (state == null) { + return + } + + const { request } = state + if (state.responseReceived || request.aborted || request.completed) { + return + } + + releaseUpgradeStream(state.stream) + state.abort(err, true) +} + +function onUpgradeStreamError () { + const state = this[kRequestStreamState] + + if (typeof this.rstCode === 'number' && this.rstCode !== 0) { + failUpgradeStream(state, new InformationalError(`HTTP/2: "stream error" received - code ${this.rstCode}`)) + } else { + failUpgradeStream(state, new InformationalError('HTTP/2: stream errored before response headers')) + } +} + +function onUpgradeStreamEnd () { + failUpgradeStream(this[kRequestStreamState], new InformationalError('HTTP/2: stream half-closed (remote)')) +} + +function onUpgradeStreamTimeout () { + const state = this[kRequestStreamState] + failUpgradeStream(state, new InformationalError(`HTTP/2: "stream timeout after ${state.headersTimeout}"`)) +} + +function onUpgradeResponse (headers, _flags) { + const stream = this + const state = stream[kRequestStreamState] + const { request } = state + + state.responseReceived = true + + const statusCode = headers[HTTP2_HEADER_STATUS] + delete headers[HTTP2_HEADER_STATUS] + + try { + request.onRequestUpgrade(statusCode, headers, stream) + } catch (err) { + state.abort(err) + return + } + + if (request.aborted) { + return + } + + removeUpgradeStreamListeners(stream) + detachRequestFromStream(request) + finalizeRequest(state) +} + +function setupUpgradeStream (stream, state) { + const { request, headersTimeout, session } = state + + stream[kHTTP2Stream] = true + stream[kHTTP2Session] = session + stream[kRequestStreamState] = state + state.stream = stream + + bindRequestToStream(request, stream, releaseUpgradeStream) + stream.once('response', onUpgradeResponse) + stream.on('error', onUpgradeStreamError) + stream.once('end', onUpgradeStreamEnd) + stream.on('timeout', onUpgradeStreamTimeout) + stream.once('close', onUpgradeStreamClose) + + clearHttp2IdleTimeout(session) + ++session[kOpenStreams] + stream.setTimeout(headersTimeout) +} + +function finalizeRequest (state, resetPendingIdx = false) { + if (state.requestFinalized) { + return + } + + state.requestFinalized = true + completeRequest(state.client, state.request, resetPendingIdx) + + state.client[kResume]() +} + +function openStream (client, request, session, abort, headers, options) { + try { + return session.request(headers, options) + } catch (err) { + // A GOAWAY'd session rejects new streams, same as an invalid session: + // reset and requeue on a fresh connection rather than the destroy + abort + // below, whose destroy(socket, err) can crash via an unhandled 'error'. + if (err?.code === 'ERR_HTTP2_INVALID_SESSION' || err?.code === 'ERR_HTTP2_GOAWAY_SESSION') { + const wrappedErr = new SocketError(err.message, util.getSocketInfo(session[kSocket])) + wrappedErr.cause = err + session[kError] = wrappedErr + resetHttp2Session(session, wrappedErr) + requeueUnsentRequest(client, request) + + return null } - postJson(requestUrl, obj, additionalHeaders = {}) { - return __awaiter(this, void 0, void 0, function* () { - const data = JSON.stringify(obj, null, 2); - additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); - const res = yield this.post(requestUrl, data, additionalHeaders); - return this._processResponse(res, this.requestOptions); - }); + + const wrappedErr = new InformationalError(err.message, { cause: err }) + session[kError] = wrappedErr + session[kSocket][kError] = wrappedErr + + session.destroy(wrappedErr) + util.destroy(session[kSocket], wrappedErr) + abort(wrappedErr) + + return null + } +} + +function writeH2 (client, request) { + const headersTimeout = request.headersTimeout ?? client[kHeadersTimeout] + const bodyTimeout = request.bodyTimeout ?? client[kBodyTimeout] + const session = client[kHTTP2Session] + const { method, path, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request + + if (upgrade != null && upgrade !== 'websocket') { + util.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`)) + return false + } + + const headers = buildRequestHeaders(reqHeaders) + + headers[HTTP2_HEADER_AUTHORITY] = host || client[kHostAuthority] + headers[HTTP2_HEADER_METHOD] = method + + // Single pre-shaped state object shared by all stream event handlers. + // All fields are declared up-front so the object keeps a stable hidden + // class for the whole request lifetime. + const state = { + abort: null, + body: request.body, + bytesRead: 0, + client, + contentLength: null, + expectsPayload: false, + maxResponseSize: client[kMaxResponseSize], + request, + headersTimeout, + bodyTimeout, + requestFinalized: false, + responseContentLength: null, + responseReceived: false, + bodySent: false, + pendingEnd: false, + trailers: null, + session, + stream: null + } + + const abort = (err, resetPendingIdx = false) => { + if (request.aborted || request.completed) { + return } - putJson(requestUrl, obj, additionalHeaders = {}) { - return __awaiter(this, void 0, void 0, function* () { - const data = JSON.stringify(obj, null, 2); - additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); - const res = yield this.put(requestUrl, data, additionalHeaders); - return this._processResponse(res, this.requestOptions); - }); + + err = err || new RequestAbortedError() + + util.errorRequest(client, request, err) + + if (state.stream != null) { + clearRequestStream(request) + + // On Abort, we close the stream to send RST_STREAM frame. + const stream = state.stream + stream.close() + + // close() alone leaves cleanup waiting on the 'close' event; on a busy, + // long-lived multiplexed session that event can fail to fire, leaving the + // native Http2Stream (and the whole request graph it pins) alive for the + // session's life. Destroy the stream synchronously to release the handle + // deterministically. Deferring the destroy (e.g. via setImmediate) leaks + // the same way when the event loop is stalled and the callback never runs + // under abort churn (#5558); close() has already queued the RST_STREAM + // frame on the native session, so a synchronous destroy still sends it. + if (!stream.destroyed) { + util.destroy(stream) + } + + // We move the running index to the next request + client[kOnError](err) + finalizeRequest(state, resetPendingIdx) } - patchJson(requestUrl, obj, additionalHeaders = {}) { - return __awaiter(this, void 0, void 0, function* () { - const data = JSON.stringify(obj, null, 2); - additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); - const res = yield this.patch(requestUrl, data, additionalHeaders); - return this._processResponse(res, this.requestOptions); - }); + + // We do not destroy the socket as we can continue using the session + // the stream gets destroyed and the session remains to create new streams + util.destroy(state.body, err) + } + + state.abort = abort + + /** @type {import('node:http2').ClientHttp2Stream} */ + let stream = null + + try { + // We are already connected, streams are pending. + // We can call on connect, and wait for abort + request.onRequestStart(abort, null) + } catch (err) { + util.errorRequest(client, request, err) + } + + if (request.aborted) { + return false + } + + if (upgrade || method === 'CONNECT') { + refH2Session(session) + + if (upgrade === 'websocket') { + // We cannot upgrade to websocket if extended CONNECT protocol is not supported + if (session[kEnableConnectProtocol] === false) { + util.errorRequest(client, request, new InformationalError('HTTP/2: Extended CONNECT protocol not supported by server')) + unrefH2Session(session) + return false + } + + // We force the method to CONNECT + // as per RFC-8441 + // https://datatracker.ietf.org/doc/html/rfc8441#section-4 + headers[HTTP2_HEADER_METHOD] = 'CONNECT' + headers[HTTP2_HEADER_PROTOCOL] = 'websocket' + // :path and :scheme headers must be omitted when sending CONNECT but set if extended-CONNECT + headers[HTTP2_HEADER_PATH] = path + + if (protocol === 'ws:' || protocol === 'wss:') { + headers[HTTP2_HEADER_SCHEME] = protocol === 'ws:' ? 'http' : 'https' + } else { + headers[HTTP2_HEADER_SCHEME] = protocol === 'http:' ? 'http' : 'https' + } + + stream = openStream(client, request, session, abort, headers, { endStream: false, signal }) + if (stream == null) { + unrefH2Session(session) + return false + } + setupUpgradeStream(stream, state) + return true } - /** - * Makes a raw http request. - * All other methods such as get, post, patch, and request ultimately call this. - * Prefer get, del, post and patch - */ - request(verb, requestUrl, data, headers) { - return __awaiter(this, void 0, void 0, function* () { - if (this._disposed) { - throw new Error('Client has already been disposed.'); - } - const parsedUrl = new URL(requestUrl); - let info = this._prepareRequest(verb, parsedUrl, headers); - // Only perform retries on reads since writes may not be idempotent. - const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) - ? this._maxRetries + 1 - : 1; - let numTries = 0; - let response; - do { - response = yield this.requestRaw(info, data); - // Check if it's an authentication challenge - if (response && - response.message && - response.message.statusCode === HttpCodes.Unauthorized) { - let authenticationHandler; - for (const handler of this.handlers) { - if (handler.canHandleAuthentication(response)) { - authenticationHandler = handler; - break; - } - } - if (authenticationHandler) { - return authenticationHandler.handleAuthentication(this, info, data); - } - else { - // We have received an unauthorized response but have no handlers to handle it. - // Let the response return to the caller. - return response; - } - } - let redirectsRemaining = this._maxRedirects; - while (response.message.statusCode && - HttpRedirectCodes.includes(response.message.statusCode) && - this._allowRedirects && - redirectsRemaining > 0) { - const redirectUrl = response.message.headers['location']; - if (!redirectUrl) { - // if there's no location to redirect to, we won't - break; - } - const parsedRedirectUrl = new URL(redirectUrl); - if (parsedUrl.protocol === 'https:' && - parsedUrl.protocol !== parsedRedirectUrl.protocol && - !this._allowRedirectDowngrade) { - throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); - } - // we need to finish reading the response before reassigning response - // which will leak the open socket. - yield response.readBody(); - // strip authorization header if redirected to a different hostname - if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { - for (const header in headers) { - // header names are case insensitive - if (header.toLowerCase() === 'authorization') { - delete headers[header]; - } - } - } - // let's make the request with the new redirectUrl - info = this._prepareRequest(verb, parsedRedirectUrl, headers); - response = yield this.requestRaw(info, data); - redirectsRemaining--; - } - if (!response.message.statusCode || - !HttpResponseRetryCodes.includes(response.message.statusCode)) { - // If not a retry code, return immediately instead of retrying - return response; - } - numTries += 1; - if (numTries < maxTries) { - yield response.readBody(); - yield this._performExponentialBackoff(numTries); - } - } while (numTries < maxTries); - return response; - }); + + // TODO: consolidate once we support CONNECT properly + // NOTE: We are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered + // We disabled endStream to allow the user to write to the stream + stream = openStream(client, request, session, abort, headers, { endStream: false, signal }) + if (stream == null) { + unrefH2Session(session) + return false } - /** - * Needs to be called if keepAlive is set to true in request options. - */ - dispose() { - if (this._agent) { - this._agent.destroy(); - } - this._disposed = true; + setupUpgradeStream(stream, state) + + return true + } + + // https://tools.ietf.org/html/rfc7540#section-8.3 + // :path and :scheme headers must be omitted when sending CONNECT + headers[HTTP2_HEADER_PATH] = path + headers[HTTP2_HEADER_SCHEME] = protocol === 'http:' ? 'http' : 'https' + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' || + method === 'QUERY' || + method === 'PROPFIND' || + method === 'PROPPATCH' + ) + + let body = state.body + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } + + let contentLength = util.bodyLength(body) + + if (util.isFormDataLike(body)) { + extractBody ??= (__nccwpck_require__(4492).extractBody) + + const [bodyStream, contentType] = extractBody(body) + headers['content-type'] = contentType + + body = bodyStream.stream + contentLength = bodyStream.length + } + + if (contentLength == null) { + contentLength = request.contentLength + } + + if (contentLength === 0 && !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // 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. + // And for methods that don't expect a payload, omit Content-Length. + contentLength = null + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + util.errorRequest(client, request, new RequestContentLengthMismatchError()) + return false } - /** - * Raw request. - * @param info - * @param data - */ - requestRaw(info, data) { - return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => { - function callbackForResult(err, res) { - if (err) { - reject(err); - } - else if (!res) { - // If `err` is not passed, then `res` must be passed. - reject(new Error('Unknown error')); - } - else { - resolve(res); - } - } - this.requestRawWithCallback(info, data, callbackForResult); - }); - }); + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + if (contentLength != null) { + assert(body || contentLength === 0, 'no body must not have content length') + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` + } + + refH2Session(session) + + if (channels.sendHeaders.hasSubscribers) { + let header = '' + for (const key in headers) { + header += `${key}: ${headers[key]}\r\n` } - /** - * Raw request with callback. - * @param info - * @param data - * @param onResult - */ - requestRawWithCallback(info, data, onResult) { - if (typeof data === 'string') { - if (!info.options.headers) { - info.options.headers = {}; - } - info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); - } - let callbackCalled = false; - function handleResult(err, res) { - if (!callbackCalled) { - callbackCalled = true; - onResult(err, res); - } - } - const req = info.httpModule.request(info.options, (msg) => { - const res = new HttpClientResponse(msg); - handleResult(undefined, res); - }); - let socket; - req.on('socket', sock => { - socket = sock; - }); - // If we ever get disconnected, we want the socket to timeout eventually - req.setTimeout(this._socketTimeout || 3 * 60000, () => { - if (socket) { - socket.end(); - } - handleResult(new Error(`Request timeout: ${info.options.path}`)); - }); - req.on('error', function (err) { - // err has statusCode property - // res should have headers - handleResult(err); - }); - if (data && typeof data === 'string') { - req.write(data, 'utf8'); - } - if (data && typeof data !== 'string') { - data.on('close', function () { - req.end(); - }); - data.pipe(req); - } - else { - req.end(); - } + channels.sendHeaders.publish({ request, headers: header, socket: session[kSocket] }) + } + + // TODO(metcoder95): add support for sending trailers + const shouldEndStream = body === null || contentLength === 0 + + state.body = body + state.contentLength = contentLength + state.expectsPayload = expectsPayload + + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = '100-continue' + } + + stream = openStream(client, request, session, abort, headers, { endStream: shouldEndStream, signal }) + if (stream == null) { + return false + } + stream[kHTTP2Stream] = true + stream[kRequestStreamState] = state + state.stream = stream + + // Increment counter as we have new streams open + clearHttp2IdleTimeout(session) + ++session[kOpenStreams] + + if (headersTimeout) { + stream.setTimeout(headersTimeout) + } + + stream[kHTTP2Session] = session + stream.on('close', completeRequestStream) + + bindRequestToStream(request, stream, releaseRequestStream) + if (expectContinue) { + stream.once('continue', writeBodyH2) + } + // The handlers below either remove themselves on first invocation or + // become unreachable once the stream closes, so plain `on` avoids the + // per-listener `once` wrapper allocation. + stream.on('response', onResponse) + stream.on('headers', onInterimResponse) + stream.on('end', onEnd) + stream.on('error', onError) + stream.on('frameError', onFrameError) + stream.on('aborted', onAborted) + if (headersTimeout || bodyTimeout) { + stream.on('timeout', onTimeout) + } + stream.on('trailers', onTrailers) + + if (!expectContinue) { + writeBodyH2.call(stream) + } + + return true +} + +function removeRequestStreamListeners (stream) { + stream.off('error', noop) + stream.off('continue', writeBodyH2) + stream.off('response', onResponse) + stream.off('headers', onInterimResponse) + stream.off('end', onEnd) + stream.off('error', onError) + stream.off('frameError', onFrameError) + stream.off('aborted', onAborted) + stream.off('timeout', onTimeout) + stream.off('trailers', onTrailers) + stream.off('data', onData) +} + +function releaseRequestStream (stream) { + if (stream == null) { + return + } + + const state = stream[kRequestStreamState] + if (state == null) { + return + } + + const { request } = state + + if (request[kRequestStream] === stream) { + detachRequestFromStream(request) + } + + // A closed or destroyed stream cannot emit further events; leaving the + // listeners in place saves the removal scans (they are collected with + // the stream). All handlers bail out when the stream state is gone. + if (!stream.destroyed && !stream.closed) { + removeRequestStreamListeners(stream) + stream.once('error', noop) + } +} + +function onData (chunk) { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + const { request, maxResponseSize, responseContentLength } = state + + if (request.aborted || request.completed) { + return + } + + if (responseContentLength != null && state.bytesRead + chunk.length > responseContentLength) { + state.abort(new ResponseContentLengthMismatchError()) + return + } + + if (maxResponseSize > -1 && state.bytesRead + chunk.length > maxResponseSize) { + // Unlike HTTP/1.1, which destroys the socket because it cannot abandon one + // response without losing framing, resetting the offending stream leaves + // the session usable for its siblings. + state.abort(new ResponseExceededMaxSizeError()) + return + } + + state.bytesRead += chunk.length + + if (request.onResponseData(chunk) === false) { + pauseResponseStream(stream, state) + } +} + +// The body timeout measures how long the peer takes to send data. While the +// consumer applies backpressure the peer can't send (it's out of flow-control +// window), and Http2Stream's timer, which counts stream activity, would fire. +// Stop it while paused and start a fresh one on resume, like HTTP/1.1, which +// ignores the body timeout while its parser is paused. +function pauseResponseStream (stream, state) { + stream.pause() + if (state.bodyTimeout) { + stream.setTimeout(0) + } +} + +// Passed to the handler as its resume callback, bound to the stream. +function resumeResponseStream () { + const stream = this + const state = stream[kRequestStreamState] + + if (state != null && state.bodyTimeout && stream.isPaused()) { + stream.setTimeout(state.bodyTimeout) + } + + stream.resume() +} + +function onInterimResponse (headers) { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + const { request } = state + + if (request.aborted || request.completed) { + return + } + + // node http2 emits 'headers' for interim (1xx) informational responses, + // while the final response arrives via 'response'. Forward these to the + // handler so that onInfo is invoked, matching the HTTP/1 behaviour and the + // documented onInfo contract. + const statusCode = headers[HTTP2_HEADER_STATUS] + delete headers[HTTP2_HEADER_STATUS] + + request.onResponseStart(Number(statusCode), headers, noop, '') +} + +function onResponse (headers) { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + const { request } = state + + stream.off('response', onResponse) + + // Final response received while still awaiting 100 (Continue): the body won't + // be sent, so close our half or the stream stays open and never completes. + if (state.body != null && !state.bodySent && !stream.writableEnded) { + stream.removeListener('continue', writeBodyH2) + stream.end() + } + + const statusCode = Number(headers[HTTP2_HEADER_STATUS]) + delete headers[HTTP2_HEADER_STATUS] + request.onResponseStarted() + state.responseReceived = true + + // A Content-Length in HEAD and 304 responses describes the selected + // representation rather than DATA on this stream. Successful CONNECT uses + // the upgrade path above; all other final responses use Content-Length as + // their DATA payload length. + if (request.method !== 'HEAD' && statusCode !== 304) { + const contentLength = headers[HTTP2_HEADER_CONTENT_LENGTH] + state.responseContentLength = contentLength == null ? null : Number(contentLength) + } + + if (state.headersTimeout || state.bodyTimeout) { + stream.setTimeout(state.bodyTimeout) + } + + // Due to the stream nature, it is possible we face a race condition + // where the stream has been assigned, but the request has been aborted + // or already completed and headers hasn't been received yet. A late + // 'response' delivered after completion would call request.onResponseStart + // post-completion, tripping its `assert(!this.completed)` (an uncatchable + // throw on the http2 event tick). Guard `completed` here as onEnd/onTrailers + // already do; best effort is to release the stream immediately as there's + // no value to keep it open. + if (request.aborted || request.completed) { + releaseRequestStream(stream) + return + } + + if (request.onResponseStart(statusCode, headers, resumeResponseStream.bind(stream), '') === false) { + pauseResponseStream(stream, state) + } + + stream.on('data', onData) +} + +function onEnd () { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + const { request } = state + + stream.off('end', onEnd) + + // onTrailers (which may fire after 'end' on Windows) has already stored + // trailers on the state by now, so completing here still delivers them. + if (state.responseReceived) { + if (!request.aborted && !request.completed) { + if (state.responseContentLength != null && state.bytesRead !== state.responseContentLength) { + state.abort(new ResponseContentLengthMismatchError()) + return + } + + state.pendingEnd = true + + // Complete on 'end': a blocked event loop can keep the stream's 'close' + // from firing, stranding its buffers until OOM. Idempotent, so a later + // 'close' no-ops. + completeRequestStream.call(stream) } - /** - * Gets an http agent. This function is useful when you need an http agent that handles - * routing through a proxy server - depending upon the url and proxy environment variables. - * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com - */ - getAgent(serverUrl) { - const parsedUrl = new URL(serverUrl); - return this._getAgent(parsedUrl); + } else { + // Stream ended without receiving a response - this is an error + // (e.g., server destroyed the stream before sending headers) + state.abort(new InformationalError('HTTP/2: stream half-closed (remote)'), true) + } +} + +function retryRefusedStream (stream, state) { + const { client, request } = state + + if ( + state.responseReceived || + request.aborted || + request.completed || + request[kRefusedStreamRetry] || + !canReplayRequest(request) + ) { + return false + } + + // RFC 9113 section 8.7 permits retrying REFUSED_STREAM, but says clients + // SHOULD NOT automatically retry the same request more than once. + request[kRefusedStreamRetry] = true + + // Detach the failed attempt before moving the request back to the pending + // queue. The peer only reset this stream, so the HTTP/2 session remains + // usable for the retry. Severing also drops the 'close' listener, so the + // abandoned stream cannot later complete the retried request. + detachRequestStreamForClose(request) + state.stream = null + state.requestFinalized = true + + completeRequest(client, request) + client[kQueue].splice(client[kPendingIdx], 0, request) + client[kResume]() + + return true +} + +function onError (err) { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + stream.off('error', onError) + + // Node's HTTP/2 implementation can turn an incomplete Content-Length body + // into a protocol stream error instead of emitting 'end'. Prefer the + // content-length mismatch error when the received byte count proves it. + if (state.responseContentLength != null && state.bytesRead !== state.responseContentLength) { + err = new ResponseContentLengthMismatchError() + } + + if (typeof stream.rstCode === 'number' && stream.rstCode !== NGHTTP2_NO_ERROR) { + err.http2ErrorCode = stream.rstCode + } + + if ( + stream.rstCode === NGHTTP2_REFUSED_STREAM && + retryRefusedStream(stream, state) + ) { + return + } + + state.abort(err) +} + +function onFrameError (type, code) { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + stream.off('frameError', onFrameError) + state.abort(new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)) +} + +function onAborted () { + this.off('data', onData) +} + +function onTimeout () { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + // Remove self so timeout doesn't fire again after we handle it + stream.off('timeout', onTimeout) + + const err = state.responseReceived + ? new BodyTimeoutError(`HTTP/2: "stream timeout after ${state.bodyTimeout}"`) + : new HeadersTimeoutError(`HTTP/2: "headers timeout after ${state.headersTimeout}"`) + state.abort(err) +} + +function onTrailers (trailers) { + const stream = this + const state = stream[kRequestStreamState] + + if (state == null) { + return + } + + const { request } = state + + stream.off('trailers', onTrailers) + stream.off('data', onData) + + if (request.aborted || request.completed) { + return + } + + // Store trailers for completeRequestStream to use when completing + state.trailers = trailers +} + +function writeBodyH2 () { + const stream = this + const state = stream[kRequestStreamState] + state.bodySent = true + const { abort, body, client, contentLength, expectsPayload, request } = state + + if (!body || contentLength === 0) { + writeBuffer( + abort, + stream, + null, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ) + } else if (util.isBuffer(body)) { + writeBuffer( + abort, + stream, + body, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ) + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable( + abort, + stream, + body.stream(), + client, + request, + client[kSocket], + contentLength, + expectsPayload + ) + } else { + writeBlob( + abort, + stream, + body, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ) } - getAgentDispatcher(serverUrl) { - const parsedUrl = new URL(serverUrl); - const proxyUrl = pm.getProxyUrl(parsedUrl); - const useProxy = proxyUrl && proxyUrl.hostname; - if (!useProxy) { - return; - } - return this._getProxyAgentDispatcher(parsedUrl, proxyUrl); + } else if (util.isStream(body)) { + writeStream( + abort, + client[kSocket], + expectsPayload, + stream, + body, + client, + request, + contentLength + ) + } else if (util.isIterable(body)) { + writeIterable( + abort, + stream, + body, + client, + request, + client[kSocket], + contentLength, + expectsPayload + ) + } else { + assert(false) + } +} + +function writeBuffer (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { + try { + if (body != null && util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') + h2stream.cork() + h2stream.write(body) + h2stream.uncork() + h2stream.end() + + request.onBodySent(body) } - _prepareRequest(method, requestUrl, headers) { - const info = {}; - info.parsedUrl = requestUrl; - const usingSsl = info.parsedUrl.protocol === 'https:'; - info.httpModule = usingSsl ? https : http; - const defaultPort = usingSsl ? 443 : 80; - info.options = {}; - info.options.host = info.parsedUrl.hostname; - info.options.port = info.parsedUrl.port - ? parseInt(info.parsedUrl.port) - : defaultPort; - info.options.path = - (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); - info.options.method = method; - info.options.headers = this._mergeHeaders(headers); - if (this.userAgent != null) { - info.options.headers['user-agent'] = this.userAgent; - } - info.options.agent = this._getAgent(info.parsedUrl); - // gives handlers an opportunity to participate - if (this.handlers) { - for (const handler of this.handlers) { - handler.prepareRequest(info.options); - } - } - return info; + + if (!expectsPayload) { + socket[kReset] = true } - _mergeHeaders(headers) { - if (this.requestOptions && this.requestOptions.headers) { - return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); + + request.onRequestSent() + client[kResume]() + } catch (error) { + abort(error) + } +} + +function writeStream (abort, socket, expectsPayload, h2stream, body, client, request, contentLength) { + assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') + + // For HTTP/2, is enough to pipe the stream + const pipe = pipeline( + body, + h2stream, + (err) => { + if (err) { + util.destroy(pipe, err) + abort(err) + } else { + util.removeAllListeners(pipe) + request.onRequestSent() + + if (!expectsPayload) { + socket[kReset] = true } - return lowercaseKeys(headers || {}); + + client[kResume]() + } } - _getExistingOrDefaultHeader(additionalHeaders, header, _default) { - let clientHeader; - if (this.requestOptions && this.requestOptions.headers) { - clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; - } - return additionalHeaders[header] || clientHeader || _default; + ) + + util.addListener(pipe, 'data', onPipeData) + + function onPipeData (chunk) { + request.onBodySent(chunk) + } +} + +async function writeBlob (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() } - _getAgent(parsedUrl) { - let agent; - const proxyUrl = pm.getProxyUrl(parsedUrl); - const useProxy = proxyUrl && proxyUrl.hostname; - if (this._keepAlive && useProxy) { - agent = this._proxyAgent; - } - if (!useProxy) { - agent = this._agent; - } - // if agent is already assigned use that agent. - if (agent) { - return agent; - } - const usingSsl = parsedUrl.protocol === 'https:'; - let maxSockets = 100; - if (this.requestOptions) { - maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; - } - // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. - if (proxyUrl && proxyUrl.hostname) { - const agentOptions = { - maxSockets, - keepAlive: this._keepAlive, - proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { - proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` - })), { host: proxyUrl.hostname, port: proxyUrl.port }) - }; - let tunnelAgent; - const overHttps = proxyUrl.protocol === 'https:'; - if (usingSsl) { - tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; - } - else { - tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; - } - agent = tunnelAgent(agentOptions); - this._proxyAgent = agent; - } - // if tunneling agent isn't assigned create a new agent - if (!agent) { - const options = { keepAlive: this._keepAlive, maxSockets }; - agent = usingSsl ? new https.Agent(options) : new http.Agent(options); - this._agent = agent; - } - if (usingSsl && this._ignoreSslError) { - // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process - // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options - // we have to cast it to any and change it directly - agent.options = Object.assign(agent.options || {}, { - rejectUnauthorized: false - }); - } - return agent; + + const buffer = Buffer.from(await body.arrayBuffer()) + + h2stream.cork() + h2stream.write(buffer) + h2stream.uncork() + h2stream.end() + + request.onBodySent(buffer) + request.onRequestSent() + + if (!expectsPayload) { + socket[kReset] = true } - _getProxyAgentDispatcher(parsedUrl, proxyUrl) { - let proxyAgent; - if (this._keepAlive) { - proxyAgent = this._proxyAgentDispatcher; - } - // if agent is already assigned use that agent. - if (proxyAgent) { - return proxyAgent; - } - const usingSsl = parsedUrl.protocol === 'https:'; - proxyAgent = new undici_1.ProxyAgent(Object.assign({ uri: proxyUrl.href, pipelining: !this._keepAlive ? 0 : 1 }, ((proxyUrl.username || proxyUrl.password) && { - token: `Basic ${Buffer.from(`${proxyUrl.username}:${proxyUrl.password}`).toString('base64')}` - }))); - this._proxyAgentDispatcher = proxyAgent; - if (usingSsl && this._ignoreSslError) { - // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process - // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options - // we have to cast it to any and change it directly - proxyAgent.options = Object.assign(proxyAgent.options.requestTls || {}, { - rejectUnauthorized: false - }); - } - return proxyAgent; + + client[kResume]() + } catch (err) { + abort(err) + } +} + +async function writeIterable (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { + assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') + + let callback = null + function onDrain () { + if (callback) { + const cb = callback + callback = null + cb() } - _performExponentialBackoff(retryNumber) { - return __awaiter(this, void 0, void 0, function* () { - retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); - const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); - return new Promise(resolve => setTimeout(() => resolve(), ms)); - }); + } + + const waitForDrain = () => new Promise((resolve, reject) => { + assert(callback === null) + + if (socket[kError]) { + reject(socket[kError]) + } else { + callback = resolve } - _processResponse(res, options) { - return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { - const statusCode = res.message.statusCode || 0; - const response = { - statusCode, - result: null, - headers: {} - }; - // not found leads to null obj returned - if (statusCode === HttpCodes.NotFound) { - resolve(response); - } - // get the result from the body - function dateTimeDeserializer(key, value) { - if (typeof value === 'string') { - const a = new Date(value); - if (!isNaN(a.valueOf())) { - return a; - } - } - return value; - } - let obj; - let contents; - try { - contents = yield res.readBody(); - if (contents && contents.length > 0) { - if (options && options.deserializeDates) { - obj = JSON.parse(contents, dateTimeDeserializer); - } - else { - obj = JSON.parse(contents); - } - response.result = obj; - } - response.headers = res.message.headers; - } - catch (err) { - // Invalid resource (contents not json); leaving result obj null - } - // note that 3xx redirects are handled by the http layer. - if (statusCode > 299) { - let msg; - // if exception/error in body, attempt to get better error - if (obj && obj.message) { - msg = obj.message; - } - else if (contents && contents.length > 0) { - // it may be the case that the exception is in the body message as string - msg = contents; - } - else { - msg = `Failed request: (${statusCode})`; - } - const err = new HttpClientError(msg, statusCode); - err.result = response.result; - reject(err); - } - else { - resolve(response); - } - })); - }); + }) + + h2stream + .on('close', onDrain) + .on('drain', onDrain) + + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + const res = h2stream.write(chunk) + request.onBodySent(chunk) + if (!res) { + await waitForDrain() + } + } + + h2stream.end() + + request.onRequestSent() + + if (!expectsPayload) { + socket[kReset] = true } + + client[kResume]() + } catch (err) { + abort(err) + } finally { + h2stream + .off('close', onDrain) + .off('drain', onDrain) + } } -exports.HttpClient = HttpClient; -const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); -//# sourceMappingURL=index.js.map + +module.exports = connectH2 + /***/ }), -/***/ 4988: -/***/ ((__unused_webpack_module, exports) => { +/***/ 3701: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.checkBypass = exports.getProxyUrl = void 0; -function getProxyUrl(reqUrl) { - const usingSsl = reqUrl.protocol === 'https:'; - if (checkBypass(reqUrl)) { - return undefined; - } - const proxyVar = (() => { - if (usingSsl) { - return process.env['https_proxy'] || process.env['HTTPS_PROXY']; - } - else { - return process.env['http_proxy'] || process.env['HTTP_PROXY']; - } - })(); - if (proxyVar) { - try { - return new DecodedURL(proxyVar); - } - catch (_a) { - if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://')) - return new DecodedURL(`http://${proxyVar}`); - } - } - else { - return undefined; - } + +const assert = __nccwpck_require__(4589) +const net = __nccwpck_require__(7030) +const http = __nccwpck_require__(7067) +const util = __nccwpck_require__(3440) +const { ClientStats } = __nccwpck_require__(6854) +const { channels } = __nccwpck_require__(2414) +const Request = __nccwpck_require__(4655) +const DispatcherBase = __nccwpck_require__(1841) +const { + InvalidArgumentError, + InformationalError, + ClientDestroyedError +} = __nccwpck_require__(8707) +const buildConnector = __nccwpck_require__(9136) +const { + kUrl, + kServerName, + kClient, + kBusy, + kConnect, + kResuming, + kRunning, + kPending, + kSize, + kQueue, + kConnected, + kConnecting, + kNeedDrain, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kConnector, + kMaxRequests, + kCounter, + kClose, + kDestroy, + kDispatch, + kLocalAddress, + kMaxResponseSize, + kOnError, + kHTTPContext, + kMaxConcurrentStreams, + kHostAuthority, + kResume, + kHTTP2Options, + kUseMilo +} = __nccwpck_require__(6443) +const connectH1 = __nccwpck_require__(637) +const connectH2 = __nccwpck_require__(8788) + +const kClosedResolve = Symbol('kClosedResolve') + +const getDefaultNodeMaxHeaderSize = http && + http.maxHeaderSize && + Number.isInteger(http.maxHeaderSize) && + http.maxHeaderSize > 0 + ? () => http.maxHeaderSize + : () => { throw new InvalidArgumentError('http module not available or http.maxHeaderSize invalid') } + +const noop = () => { } + +function getPipelining (client) { + return client[kPipelining] ?? client[kHTTPContext]?.defaultPipelining ?? 1 } -exports.getProxyUrl = getProxyUrl; -function checkBypass(reqUrl) { - if (!reqUrl.hostname) { - return false; + +let h2NamespaceOptsWarning = false +function emitH2OptionsNamespaceWarning (optName) { + if (h2NamespaceOptsWarning === true) return + + process.emitWarning(`Use h2Options.${optName} instead. ${optName} for H2 will be deprecated in future major.`, { + code: 'UNDICI-H2-OPTIONS' + }) + h2NamespaceOptsWarning = true +} + +// Protocol-aware dispatch ceiling. h1 RFC7230 pipelining is unrelated to h2 +// stream multiplexing — over h2 the ceiling is the (server-confirmed) +// maxConcurrentStreams. Before a context is attached we use the h1 +// pipelining factor; once h2 attaches the queued requests can drain in +// one batch up to maxConcurrentStreams. +function getMaxConcurrent (client) { + if (client[kHTTPContext]?.version === 'h2') { + return client[kMaxConcurrentStreams] + } + return getPipelining(client) +} + +/** + * @type {import('../../types/client.js').default} + */ +class Client extends DispatcherBase { + /** + * + * @param {string|URL} url + * @param {import('../../types/client.js').Client.Options} options + */ + constructor (url, { + maxHeaderSize, + headersTimeout, + socketTimeout, + requestTimeout, + connectTimeout, + bodyTimeout, + idleTimeout, + keepAlive, + keepAliveTimeout, + maxKeepAliveTimeout, + keepAliveMaxTimeout, + keepAliveTimeoutThreshold, + socketPath, + pipelining, + tls, + strictContentLength, + maxCachedSessions, + connect, + maxRequestsPerClient, + localAddress, + maxResponseSize, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + // h2 + maxConcurrentStreams, + allowH2, + useH2c, + initialWindowSize, + connectionWindowSize, + pingInterval, + useMilo, + webSocket, + h2Options, + eventSource + } = {}) { + if (keepAlive !== undefined) { + throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') } - const reqHost = reqUrl.hostname; - if (isLoopbackAddress(reqHost)) { - return true; + + if (socketTimeout !== undefined) { + throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') } - const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; - if (!noProxy) { - return false; + + if (requestTimeout !== undefined) { + throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') } - // Determine the request port - let reqPort; - if (reqUrl.port) { - reqPort = Number(reqUrl.port); + + if (idleTimeout !== undefined) { + throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') } - else if (reqUrl.protocol === 'http:') { - reqPort = 80; + + if (maxKeepAliveTimeout !== undefined) { + throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') } - else if (reqUrl.protocol === 'https:') { - reqPort = 443; + + if (maxHeaderSize != null) { + if (!Number.isInteger(maxHeaderSize) || maxHeaderSize < 1) { + throw new InvalidArgumentError('invalid maxHeaderSize') + } + } else { + // If maxHeaderSize is not provided, use the default value from the http module + // or if that is not available, throw an error. + maxHeaderSize = getDefaultNodeMaxHeaderSize() } - // Format the request hostname and hostname with port - const upperReqHosts = [reqUrl.hostname.toUpperCase()]; - if (typeof reqPort === 'number') { - upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); + + if (socketPath != null && typeof socketPath !== 'string') { + throw new InvalidArgumentError('invalid socketPath') } - // Compare request host against noproxy - for (const upperNoProxyItem of noProxy - .split(',') - .map(x => x.trim().toUpperCase()) - .filter(x => x)) { - if (upperNoProxyItem === '*' || - upperReqHosts.some(x => x === upperNoProxyItem || - x.endsWith(`.${upperNoProxyItem}`) || - (upperNoProxyItem.startsWith('.') && - x.endsWith(`${upperNoProxyItem}`)))) { - return true; - } + + if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { + throw new InvalidArgumentError('invalid connectTimeout') } - return false; -} -exports.checkBypass = checkBypass; -function isLoopbackAddress(host) { - const hostLower = host.toLowerCase(); - return (hostLower === 'localhost' || - hostLower.startsWith('127.') || - hostLower.startsWith('[::1]') || - hostLower.startsWith('[0:0:0:0:0:0:0:1]')); -} -class DecodedURL extends URL { - constructor(url, base) { - super(url, base); - this._decodedUsername = decodeURIComponent(super.username); - this._decodedPassword = decodeURIComponent(super.password); + + if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveTimeout') } - get username() { - return this._decodedUsername; + + if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveMaxTimeout') } - get password() { - return this._decodedPassword; + + if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { + throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') } -} -//# sourceMappingURL=proxy.js.map -/***/ }), + if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') + } -/***/ 5207: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') + } -"use strict"; + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } -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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var _a; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0; -const fs = __importStar(__nccwpck_require__(9896)); -const path = __importStar(__nccwpck_require__(6928)); -_a = fs.promises -// export const {open} = 'fs' -, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; -// export const {open} = 'fs' -exports.IS_WINDOWS = process.platform === 'win32'; -// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691 -exports.UV_FS_O_EXLOCK = 0x10000000; -exports.READONLY = fs.constants.O_RDONLY; -function exists(fsPath) { - return __awaiter(this, void 0, void 0, function* () { - try { - yield exports.stat(fsPath); - } - catch (err) { - if (err.code === 'ENOENT') { - return false; - } - throw err; - } - return true; - }); -} -exports.exists = exists; -function isDirectory(fsPath, useStat = false) { - return __awaiter(this, void 0, void 0, function* () { - const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); - return stats.isDirectory(); - }); -} -exports.isDirectory = isDirectory; -/** - * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: - * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). - */ -function isRooted(p) { - p = normalizeSeparators(p); - if (!p) { - throw new Error('isRooted() parameter "p" cannot be empty'); + if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { + throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') } - if (exports.IS_WINDOWS) { - return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello - ); // e.g. C: or C:\hello + + if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { + throw new InvalidArgumentError('localAddress must be valid string IP address') } - return p.startsWith('/'); -} -exports.isRooted = isRooted; -/** - * Best effort attempt to determine whether a file exists and is executable. - * @param filePath file path to check - * @param extensions additional file extensions to try - * @return if file exists and is executable, returns the file path. otherwise empty string. - */ -function tryGetExecutablePath(filePath, extensions) { - return __awaiter(this, void 0, void 0, function* () { - let stats = undefined; - try { - // test file exists - stats = yield exports.stat(filePath); - } - catch (err) { - if (err.code !== 'ENOENT') { - // eslint-disable-next-line no-console - console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); - } - } - if (stats && stats.isFile()) { - if (exports.IS_WINDOWS) { - // on Windows, test for valid extension - const upperExt = path.extname(filePath).toUpperCase(); - if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { - return filePath; - } - } - else { - if (isUnixExecutable(stats)) { - return filePath; - } - } - } - // try each extension - const originalFilePath = filePath; - for (const extension of extensions) { - filePath = originalFilePath + extension; - stats = undefined; - try { - stats = yield exports.stat(filePath); - } - catch (err) { - if (err.code !== 'ENOENT') { - // eslint-disable-next-line no-console - console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); - } - } - if (stats && stats.isFile()) { - if (exports.IS_WINDOWS) { - // preserve the case of the actual file (since an extension was appended) - try { - const directory = path.dirname(filePath); - const upperName = path.basename(filePath).toUpperCase(); - for (const actualName of yield exports.readdir(directory)) { - if (upperName === actualName.toUpperCase()) { - filePath = path.join(directory, actualName); - break; - } - } - } - catch (err) { - // eslint-disable-next-line no-console - console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); - } - return filePath; - } - else { - if (isUnixExecutable(stats)) { - return filePath; - } - } - } - } - return ''; - }); -} -exports.tryGetExecutablePath = tryGetExecutablePath; -function normalizeSeparators(p) { - p = p || ''; - if (exports.IS_WINDOWS) { - // convert slashes on Windows - p = p.replace(/\//g, '\\'); - // remove redundant slashes - return p.replace(/\\\\+/g, '\\'); + + if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { + throw new InvalidArgumentError('maxResponseSize must be a positive number') } - // remove redundant slashes - return p.replace(/\/\/+/g, '/'); -} -// on Mac/Linux, test the execute bit -// R W X R W X R W X -// 256 128 64 32 16 8 4 2 1 -function isUnixExecutable(stats) { - return ((stats.mode & 1) > 0 || - ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || - ((stats.mode & 64) > 0 && stats.uid === process.getuid())); -} -// Get the path of cmd.exe in windows -function getCmdPath() { - var _a; - return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`; -} -exports.getCmdPath = getCmdPath; -//# sourceMappingURL=io-util.js.map -/***/ }), + if ( + autoSelectFamilyAttemptTimeout != null && + (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) + ) { + throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') + } -/***/ 4994: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + // h2 + if (allowH2 != null && typeof allowH2 !== 'boolean') { + throw new InvalidArgumentError('allowH2 must be a valid boolean value') + } -"use strict"; + // We validate only if allowH2 is enabled or null (enabled by default) + if (allowH2 !== false) { + // Prioritise new h2Options object, otherwise fallback to prior configuration options + if (h2Options != null) { + if (h2Options.useH2c != null && typeof h2Options.useH2c !== 'boolean') { + throw new InvalidArgumentError('h2Options.useH2c must be a valid boolean value') + } -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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0; -const assert_1 = __nccwpck_require__(2613); -const path = __importStar(__nccwpck_require__(6928)); -const ioUtil = __importStar(__nccwpck_require__(5207)); -/** - * Copies a file or folder. - * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js - * - * @param source source path - * @param dest destination path - * @param options optional. See CopyOptions. - */ -function cp(source, dest, options = {}) { - return __awaiter(this, void 0, void 0, function* () { - const { force, recursive, copySourceDirectory } = readCopyOptions(options); - const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; - // Dest is an existing file, but not forcing - if (destStat && destStat.isFile() && !force) { - return; + if (h2Options.settings?.initialWindowSize != null && (!Number.isInteger(h2Options.settings.initialWindowSize) || h2Options.settings.initialWindowSize < 1)) { + throw new InvalidArgumentError('h2Options.settings.initialWindowSize must be a positive integer, greater than 0') } - // If dest is an existing directory, should copy inside. - const newDest = destStat && destStat.isDirectory() && copySourceDirectory - ? path.join(dest, path.basename(source)) - : dest; - if (!(yield ioUtil.exists(source))) { - throw new Error(`no such file or directory: ${source}`); + + if (h2Options.maxConcurrentStreams != null && (!Number.isInteger(h2Options.maxConcurrentStreams) || h2Options.maxConcurrentStreams < 1)) { + throw new InvalidArgumentError('h2Options.maxConcurrentStreams must be a positive integer, greater than 0') } - const sourceStat = yield ioUtil.stat(source); - if (sourceStat.isDirectory()) { - if (!recursive) { - throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); - } - else { - yield cpDirRecursive(source, newDest, 0, force); - } + + if (h2Options.connectionWindowSize != null && (!Number.isInteger(h2Options.connectionWindowSize) || h2Options.connectionWindowSize < 1)) { + throw new InvalidArgumentError('h2Options.connectionWindowSize must be a positive integer, greater than 0') } - else { - if (path.relative(source, newDest) === '') { - // a file cannot be copied to itself - throw new Error(`'${newDest}' and '${source}' are the same file`); - } - yield copyFile(source, newDest, force); + + if (h2Options.pingInterval != null && (typeof h2Options.pingInterval !== 'number' || !Number.isInteger(h2Options.pingInterval) || h2Options.pingInterval < 0)) { + throw new InvalidArgumentError('h2Options.pingInterval must be a positive integer, greater or equal to 0') } - }); -} -exports.cp = cp; -/** - * Moves a path. - * - * @param source source path - * @param dest destination path - * @param options optional. See MoveOptions. - */ -function mv(source, dest, options = {}) { - return __awaiter(this, void 0, void 0, function* () { - if (yield ioUtil.exists(dest)) { - let destExists = true; - if (yield ioUtil.isDirectory(dest)) { - // If dest is directory copy src into dest - dest = path.join(dest, path.basename(source)); - destExists = yield ioUtil.exists(dest); - } - if (destExists) { - if (options.force == null || options.force) { - yield rmRF(dest); - } - else { - throw new Error('Destination already exists'); - } - } + } else { + if (useH2c != null && typeof useH2c !== 'boolean') { + emitH2OptionsNamespaceWarning('useH2c') + throw new InvalidArgumentError('useH2c must be a valid boolean value') } - yield mkdirP(path.dirname(dest)); - yield ioUtil.rename(source, dest); - }); -} -exports.mv = mv; -/** - * Remove a path recursively with force - * - * @param inputPath path to remove - */ -function rmRF(inputPath) { - return __awaiter(this, void 0, void 0, function* () { - if (ioUtil.IS_WINDOWS) { - // Check for invalid characters - // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file - if (/[*"<>|]/.test(inputPath)) { - throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows'); - } + + if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { + emitH2OptionsNamespaceWarning('maxConcurrentStreams') + throw new InvalidArgumentError('maxConcurrentStreams must be a positive integer, greater than 0') } - try { - // note if path does not exist, error is silent - yield ioUtil.rm(inputPath, { - force: true, - maxRetries: 3, - recursive: true, - retryDelay: 300 - }); + + if (initialWindowSize != null && (!Number.isInteger(initialWindowSize) || initialWindowSize < 1)) { + emitH2OptionsNamespaceWarning('initialWindowSize') + throw new InvalidArgumentError('initialWindowSize must be a positive integer, greater than 0') } - catch (err) { - throw new Error(`File was unable to be removed ${err}`); + + if (connectionWindowSize != null && (!Number.isInteger(connectionWindowSize) || connectionWindowSize < 1)) { + emitH2OptionsNamespaceWarning('connectionWindowSize') + throw new InvalidArgumentError('connectionWindowSize must be a positive integer, greater than 0') } - }); -} -exports.rmRF = rmRF; -/** - * Make a directory. Creates the full path with folders in between - * Will throw if it fails - * - * @param fsPath path to create - * @returns Promise - */ -function mkdirP(fsPath) { - return __awaiter(this, void 0, void 0, function* () { - assert_1.ok(fsPath, 'a path argument must be provided'); - yield ioUtil.mkdir(fsPath, { recursive: true }); - }); -} -exports.mkdirP = mkdirP; -/** - * Returns path of a tool had the tool actually been invoked. Resolves via paths. - * If you check and the tool does not exist, it will throw. - * - * @param tool name of the tool - * @param check whether to check if tool exists - * @returns Promise path to tool - */ -function which(tool, check) { - return __awaiter(this, void 0, void 0, function* () { - if (!tool) { - throw new Error("parameter 'tool' is required"); + + if (pingInterval != null && (typeof pingInterval !== 'number' || !Number.isInteger(pingInterval) || pingInterval < 0)) { + emitH2OptionsNamespaceWarning('pingInterval') + throw new InvalidArgumentError('pingInterval must be a positive integer, greater or equal to 0') } - // recursive when check=true - if (check) { - const result = yield which(tool, false); - if (!result) { - if (ioUtil.IS_WINDOWS) { - throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); - } - else { - throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); - } - } - return result; + } + } + + super({ webSocket, eventSource }) + + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + useH2c: h2Options?.useH2c ?? useH2c, + timeout: connectTimeout, + ...(typeof autoSelectFamily === 'boolean' ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) + } else { + const customConnect = connect + connect = (opts, callback) => customConnect({ + ...opts, + ...(socketPath != null ? { socketPath } : null), + ...(allowH2 != null ? { allowH2 } : null) + }, callback) + } + + this[kUrl] = util.parseOrigin(url) + this[kHostAuthority] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` + this[kConnector] = connect + this[kPipelining] = pipelining != null ? pipelining : 1 + this[kMaxHeadersSize] = maxHeaderSize + this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout + this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout + this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 2e3 : keepAliveTimeoutThreshold + this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] + this[kServerName] = null + this[kLocalAddress] = localAddress != null ? localAddress : null + this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kHostHeader] = `host: ${this[kHostAuthority]}\r\n` + this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 + this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3 + this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength + this[kMaxRequests] = maxRequestsPerClient + this[kClosedResolve] = null + this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 + this[kHTTPContext] = null + // h2 + this[kHTTP2Options] = { + pingInterval: h2Options?.pingInterval ?? pingInterval ?? 60e3, + connectionWindowSize: h2Options?.connectionWindowSize ?? connectionWindowSize ?? 524288, + maxConcurrentStreams: h2Options?.maxConcurrentStreams ?? maxConcurrentStreams ?? 100, // Max peerConcurrentStreams for a Node h2 server + sessionOptions: { + // HTTP/2 window sizes are set to higher defaults than Node.js core for better performance: + // - initialWindowSize: 262144 (256KB) vs Node.js default 65535 (64KB - 1) + // Allows more data to be sent before requiring acknowledgment, improving throughput + // especially on high-latency networks. This matches common production HTTP/2 servers. + // - connectionWindowSize: 524288 (512KB) vs Node.js default (none set) + // Provides better flow control for the entire connection across multiple streams. + initialWindowSize: h2Options?.initialWindowSize ?? initialWindowSize ?? 262144 + } + } + this[kUseMilo] = useMilo + + // kQueue is built up of 3 sections separated by + // the kRunningIdx and kPendingIdx indices. + // | complete | running | pending | + // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length + // kRunningIdx points to the first running element. + // kPendingIdx points to the first pending element. + // This implements a fast queue with an amortized + // time of O(1). + + this[kQueue] = [] + this[kRunningIdx] = 0 + this[kPendingIdx] = 0 + + this[kResume] = (sync) => resume(this, sync) + this[kOnError] = (err) => onError(this, err) + } + + get pipelining () { + return this[kPipelining] + } + + set pipelining (value) { + this[kPipelining] = value + this[kResume](true) + } + + get stats () { + return new ClientStats(this) + } + + get [kPending] () { + return this[kQueue].length - this[kPendingIdx] + } + + get [kRunning] () { + return this[kPendingIdx] - this[kRunningIdx] + } + + get [kSize] () { + return this[kQueue].length - this[kRunningIdx] + } + + get [kConnected] () { + return !!this[kHTTPContext] && !this[kConnecting] && !this[kHTTPContext].destroyed + } + + get [kBusy] () { + // The `kPending > 0` check below is the gate Pool uses to decide whether + // to spin up an additional Client. For h1 that fan-out is correct — + // each socket only handles one pipelined request at a time. Once an h2 + // context is attached we want concurrent dispatches to multiplex onto + // the shared session, so suppress that signal in the h2 case. + const allowsMux = this[kHTTPContext]?.version === 'h2' + + return Boolean( + this[kHTTPContext]?.busy(null) || + (this[kSize] >= (getMaxConcurrent(this) || 1)) || + (this[kPending] > 0 && !allowsMux) + ) + } + + [kConnect] (cb) { + connect(this) + this.once('connect', cb) + } + + [kDispatch] (opts, handler) { + const request = new Request(this[kUrl].origin, opts, handler) + + this[kQueue].push(request) + if (this[kResuming]) { + // Do nothing. + } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { + // Wait a tick in case stream/iterator is ended in the same tick. + this[kResuming] = 1 + queueMicrotask(() => resume(this)) + } else { + this[kResume](true) + } + + if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { + this[kNeedDrain] = 2 + } + + return this[kNeedDrain] < 2 + } + + [kClose] () { + // TODO: for H2 we need to gracefully flush the remaining enqueued + // request and close each stream. + return new Promise((resolve) => { + if (this[kSize]) { + this[kClosedResolve] = resolve + } else { + resolve(null) + } + }) + } + + [kDestroy] (err) { + return new Promise((resolve) => { + const requests = this[kQueue].splice(this[kPendingIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + if (request != null) { + util.errorRequest(this, request, err) } - const matches = yield findInPath(tool); - if (matches && matches.length > 0) { - return matches[0]; + } + + const callback = () => { + if (this[kClosedResolve]) { + // TODO (fix): Should we error here with ClientDestroyedError? + this[kClosedResolve]() + this[kClosedResolve] = null } - return ''; - }); + resolve(null) + } + + if (this[kHTTPContext]) { + this[kHTTPContext].destroy(err, callback) + this[kHTTPContext] = null + } else { + queueMicrotask(callback) + } + + this[kResume]() + }) + } +} + +function onError (client, err) { + if ( + client[kRunning] === 0 && + err.code !== 'UND_ERR_INFO' && + err.code !== 'UND_ERR_SOCKET' + ) { + // Error is not caused by running request and not a recoverable + // socket error. + + assert(client[kPendingIdx] === client[kRunningIdx]) + + const requests = client[kQueue].splice(client[kRunningIdx]) + + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + if (request != null) { + util.errorRequest(client, request, err) + } + } + assert(client[kSize] === 0) + } } -exports.which = which; + /** - * Returns a list of all occurrences of the given tool on the system path. - * - * @returns Promise the paths of the tool + * @param {Client} client + * @returns {void} */ -function findInPath(tool) { - return __awaiter(this, void 0, void 0, function* () { - if (!tool) { - throw new Error("parameter 'tool' is required"); - } - // build the list of extensions to try - const extensions = []; - if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) { - for (const extension of process.env['PATHEXT'].split(path.delimiter)) { - if (extension) { - extensions.push(extension); - } - } - } - // if it's rooted, return it if exists. otherwise return empty. - if (ioUtil.isRooted(tool)) { - const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); - if (filePath) { - return [filePath]; - } - return []; - } - // if any path separators, return empty - if (tool.includes(path.sep)) { - return []; - } - // build the list of directories - // - // Note, technically "where" checks the current directory on Windows. From a toolkit perspective, - // it feels like we should not do this. Checking the current directory seems like more of a use - // case of a shell, and the which() function exposed by the toolkit should strive for consistency - // across platforms. - const directories = []; - if (process.env.PATH) { - for (const p of process.env.PATH.split(path.delimiter)) { - if (p) { - directories.push(p); - } - } - } - // find all matches - const matches = []; - for (const directory of directories) { - const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions); - if (filePath) { - matches.push(filePath); - } - } - return matches; - }); +function connect (client) { + assert(!client[kConnecting]) + assert(!client[kHTTPContext]) + + let { host, hostname, protocol, port } = client[kUrl] + + // Resolve ipv6 + if (hostname[0] === '[') { + const idx = hostname.indexOf(']') + + assert(idx !== -1) + const ip = hostname.substring(1, idx) + + assert(net.isIPv6(ip)) + hostname = ip + } + + client[kConnecting] = true + + if (channels.beforeConnect.hasSubscribers) { + channels.beforeConnect.publish({ + connectParams: { + host, + hostname, + protocol, + port, + version: client[kHTTPContext]?.version, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector] + }) + } + + try { + client[kConnector]({ + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, (err, socket) => { + if (err) { + handleConnectError(client, err, { host, hostname, protocol, port }) + client[kResume]() + return + } + + if (client.destroyed) { + util.destroy(socket.on('error', noop), new ClientDestroyedError()) + client[kResume]() + return + } + + assert(socket) + + try { + client[kHTTPContext] = socket.alpnProtocol === 'h2' + ? connectH2(client, socket) + : connectH1(client, socket) + } catch (err) { + socket.destroy().on('error', noop) + handleConnectError(client, err, { host, hostname, protocol, port }) + client[kResume]() + return + } + + client[kConnecting] = false + + socket[kCounter] = 0 + socket[kMaxRequests] = client[kMaxRequests] + socket[kClient] = client + socket[kError] = null + + if (channels.connected.hasSubscribers) { + channels.connected.publish({ + connectParams: { + host, + hostname, + protocol, + port, + version: client[kHTTPContext]?.version, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + socket + }) + } + + client.emit('connect', client[kUrl], [client]) + client[kResume]() + }) + } catch (err) { + handleConnectError(client, err, { host, hostname, protocol, port }) + client[kResume]() + } } -exports.findInPath = findInPath; -function readCopyOptions(options) { - const force = options.force == null ? true : options.force; - const recursive = Boolean(options.recursive); - const copySourceDirectory = options.copySourceDirectory == null - ? true - : Boolean(options.copySourceDirectory); - return { force, recursive, copySourceDirectory }; + +function handleConnectError (client, err, { host, hostname, protocol, port }) { + if (client.destroyed) { + return + } + + client[kConnecting] = false + + if (channels.connectError.hasSubscribers) { + channels.connectError.publish({ + connectParams: { + host, + hostname, + protocol, + port, + version: client[kHTTPContext]?.version, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + error: err + }) + } + + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + const running = client[kQueue].splice(client[kRunningIdx], client[kRunning]) + client[kPendingIdx] = client[kRunningIdx] + + for (let i = 0; i < running.length; i++) { + util.errorRequest(client, running[i], err) + } + + while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { + const request = client[kQueue].splice(client[kPendingIdx], 1)[0] + util.errorRequest(client, request, err) + } + } else { + onError(client, err) + } + + client.emit('connectionError', client[kUrl], [client], err) } -function cpDirRecursive(sourceDir, destDir, currentDepth, force) { - return __awaiter(this, void 0, void 0, function* () { - // Ensure there is not a run away recursive copy - if (currentDepth >= 255) - return; - currentDepth++; - yield mkdirP(destDir); - const files = yield ioUtil.readdir(sourceDir); - for (const fileName of files) { - const srcFile = `${sourceDir}/${fileName}`; - const destFile = `${destDir}/${fileName}`; - const srcFileStat = yield ioUtil.lstat(srcFile); - if (srcFileStat.isDirectory()) { - // Recurse - yield cpDirRecursive(srcFile, destFile, currentDepth, force); - } - else { - yield copyFile(srcFile, destFile, force); - } - } - // Change the mode for the newly created directory - yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); - }); + +function emitDrain (client) { + client[kNeedDrain] = 0 + client.emit('drain', client[kUrl], [client]) } -// Buffered file copy -function copyFile(srcFile, destFile, force) { - return __awaiter(this, void 0, void 0, function* () { - if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { - // unlink/re-link it - try { - yield ioUtil.lstat(destFile); - yield ioUtil.unlink(destFile); - } - catch (e) { - // Try to override file permission - if (e.code === 'EPERM') { - yield ioUtil.chmod(destFile, '0666'); - yield ioUtil.unlink(destFile); - } - // other errors = it doesn't exist, no work to do - } - // Copy over symlink - const symlinkFull = yield ioUtil.readlink(srcFile); - yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); - } - else if (!(yield ioUtil.exists(destFile)) || force) { - yield ioUtil.copyFile(srcFile, destFile); - } - }); + +function resume (client, sync) { + if (client[kResuming] === 2) { + return + } + + client[kResuming] = 2 + + _resume(client, sync) + client[kResuming] = 0 + + if (client[kRunningIdx] > 256) { + client[kQueue].splice(0, client[kRunningIdx]) + client[kPendingIdx] -= client[kRunningIdx] + client[kRunningIdx] = 0 + } } -//# sourceMappingURL=io.js.map -/***/ }), +function _resume (client, sync) { + while (true) { + if (client.destroyed) { + assert(client[kPending] === 0) + return + } -/***/ 8036: -/***/ (function(module, exports, __nccwpck_require__) { + if (client[kClosedResolve] && !client[kSize]) { + client[kClosedResolve]() + client[kClosedResolve] = null + return + } -"use strict"; + if (client[kHTTPContext]) { + client[kHTTPContext].resume() + } -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports._readLinuxVersionFile = exports._getOsVersion = exports._findMatch = void 0; -const semver = __importStar(__nccwpck_require__(9318)); -const core_1 = __nccwpck_require__(7484); -// needs to be require for core node modules to be mocked -/* eslint @typescript-eslint/no-require-imports: 0 */ -const os = __nccwpck_require__(857); -const cp = __nccwpck_require__(5317); -const fs = __nccwpck_require__(9896); -function _findMatch(versionSpec, stable, candidates, archFilter) { - return __awaiter(this, void 0, void 0, function* () { - const platFilter = os.platform(); - let result; - let match; - let file; - for (const candidate of candidates) { - const version = candidate.version; - (0, core_1.debug)(`check ${version} satisfies ${versionSpec}`); - if (semver.satisfies(version, versionSpec) && - (!stable || candidate.stable === stable)) { - file = candidate.files.find(item => { - (0, core_1.debug)(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); - let chk = item.arch === archFilter && item.platform === platFilter; - if (chk && item.platform_version) { - const osVersion = module.exports._getOsVersion(); - if (osVersion === item.platform_version) { - chk = true; - } - else { - chk = semver.satisfies(osVersion, item.platform_version); - } - } - return chk; - }); - if (file) { - (0, core_1.debug)(`matched ${candidate.version}`); - match = candidate; - break; - } - } - } - if (match && file) { - // clone since we're mutating the file list to be only the file that matches - result = Object.assign({}, match); - result.files = [file]; - } - return result; - }); -} -exports._findMatch = _findMatch; -function _getOsVersion() { - // TODO: add windows and other linux, arm variants - // right now filtering on version is only an ubuntu and macos scenario for tools we build for hosted (python) - const plat = os.platform(); - let version = ''; - if (plat === 'darwin') { - version = cp.execSync('sw_vers -productVersion').toString(); + if (client[kBusy]) { + client[kNeedDrain] = 2 + } else if (client[kNeedDrain] === 2) { + if (sync) { + client[kNeedDrain] = 1 + queueMicrotask(() => emitDrain(client)) + } else { + emitDrain(client) + } + continue } - else if (plat === 'linux') { - // lsb_release process not in some containers, readfile - // Run cat /etc/lsb-release - // DISTRIB_ID=Ubuntu - // DISTRIB_RELEASE=18.04 - // DISTRIB_CODENAME=bionic - // DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS" - const lsbContents = module.exports._readLinuxVersionFile(); - if (lsbContents) { - const lines = lsbContents.split('\n'); - for (const line of lines) { - const parts = line.split('='); - if (parts.length === 2 && - (parts[0].trim() === 'VERSION_ID' || - parts[0].trim() === 'DISTRIB_RELEASE')) { - version = parts[1].trim().replace(/^"/, '').replace(/"$/, ''); - break; - } - } - } + + if (client[kPending] === 0) { + return } - return version; -} -exports._getOsVersion = _getOsVersion; -function _readLinuxVersionFile() { - const lsbReleaseFile = '/etc/lsb-release'; - const osReleaseFile = '/etc/os-release'; - let contents = ''; - if (fs.existsSync(lsbReleaseFile)) { - contents = fs.readFileSync(lsbReleaseFile).toString(); + + if (client[kRunning] >= (getMaxConcurrent(client) || 1)) { + return } - else if (fs.existsSync(osReleaseFile)) { - contents = fs.readFileSync(osReleaseFile).toString(); + + const request = client[kQueue][client[kPendingIdx]] + + if (request === null) { + return } - return contents; -} -exports._readLinuxVersionFile = _readLinuxVersionFile; -//# sourceMappingURL=manifest.js.map -/***/ }), + if (request.aborted) { + client[kQueue].splice(client[kPendingIdx], 1) + continue + } -/***/ 7380: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { + if (client[kRunning] > 0) { + return + } -"use strict"; + client[kServerName] = request.servername + client[kHTTPContext]?.destroy(new InformationalError('servername changed'), () => { + client[kHTTPContext] = null + resume(client) + }) + } -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.RetryHelper = void 0; -const core = __importStar(__nccwpck_require__(7484)); -/** - * Internal class for retries - */ -class RetryHelper { - constructor(maxAttempts, minSeconds, maxSeconds) { - if (maxAttempts < 1) { - throw new Error('max attempts should be greater than or equal to 1'); - } - this.maxAttempts = maxAttempts; - this.minSeconds = Math.floor(minSeconds); - this.maxSeconds = Math.floor(maxSeconds); - if (this.minSeconds > this.maxSeconds) { - throw new Error('min seconds should be less than or equal to max seconds'); - } + if (client[kConnecting]) { + return } - execute(action, isRetryable) { - return __awaiter(this, void 0, void 0, function* () { - let attempt = 1; - while (attempt < this.maxAttempts) { - // Try - try { - return yield action(); - } - catch (err) { - if (isRetryable && !isRetryable(err)) { - throw err; - } - core.info(err.message); - } - // Sleep - const seconds = this.getSleepAmount(); - core.info(`Waiting ${seconds} seconds before trying again`); - yield this.sleep(seconds); - attempt++; - } - // Last attempt - return yield action(); - }); + + if (!client[kHTTPContext]) { + client[kServerName] = request.servername + connect(client) + return } - getSleepAmount() { - return (Math.floor(Math.random() * (this.maxSeconds - this.minSeconds + 1)) + - this.minSeconds); + + if (client[kHTTPContext].destroyed) { + return } - sleep(seconds) { - return __awaiter(this, void 0, void 0, function* () { - return new Promise(resolve => setTimeout(resolve, seconds * 1000)); - }); + + if (client[kHTTPContext].busy(request)) { + return + } + + if (!request.aborted && client[kHTTPContext].write(request)) { + client[kPendingIdx]++ + } else { + client[kQueue].splice(client[kPendingIdx], 1) } + } } -exports.RetryHelper = RetryHelper; -//# sourceMappingURL=retry-helper.js.map + +module.exports = Client + /***/ }), -/***/ 3472: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 1841: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const buffer = __nccwpck_require__(4573) +const Dispatcher = __nccwpck_require__(883) +const { + ClientDestroyedError, + ClientClosedError, + InvalidArgumentError +} = __nccwpck_require__(8707) +const { kDestroy, kClose, kClosed, kDestroyed, kDispatch } = __nccwpck_require__(6443) +const { defaultWebSocketMaxFragments, defaultWebSocketMaxPayloadSize } = __nccwpck_require__(735) + +const kOnDestroyed = Symbol('onDestroyed') +const kOnClosed = Symbol('onClosed') +const kWebSocketOptions = Symbol('webSocketOptions') +const kEventSourceOptions = Symbol('eventSourceOptions') + +class DispatcherBase extends Dispatcher { + /** @type {boolean} */ + [kDestroyed] = false; + + /** @type {Array|null} */ + [kOnClosed] = null + + /** + * @param {import('../../types/dispatcher').DispatcherOptions} [opts] + */ + constructor (opts) { + super() + this[kWebSocketOptions] = opts?.webSocket ?? {} + this[kEventSourceOptions] = opts?.eventSource ?? {} + } + + /** + * @returns {import('../../types/client').Client.WebSocketOptions} + */ + get webSocketOptions () { + return { + maxFragments: this[kWebSocketOptions].maxFragments ?? defaultWebSocketMaxFragments, + maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? defaultWebSocketMaxPayloadSize + } + } + + /** + * @returns {import('../../types/client').Client.EventSourceOptions} + */ + get eventSourceOptions () { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + } + } + + /** @returns {boolean} */ + get destroyed () { + return this[kDestroyed] + } -"use strict"; + /** @returns {boolean} */ + get closed () { + return this[kClosed] + } -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.evaluateVersions = exports.isExplicitVersion = exports.findFromManifest = exports.getManifestFromRepo = exports.findAllVersions = exports.find = exports.cacheFile = exports.cacheDir = exports.extractZip = exports.extractXar = exports.extractTar = exports.extract7z = exports.downloadTool = exports.HTTPError = void 0; -const core = __importStar(__nccwpck_require__(7484)); -const io = __importStar(__nccwpck_require__(4994)); -const crypto = __importStar(__nccwpck_require__(6982)); -const fs = __importStar(__nccwpck_require__(9896)); -const mm = __importStar(__nccwpck_require__(8036)); -const os = __importStar(__nccwpck_require__(857)); -const path = __importStar(__nccwpck_require__(6928)); -const httpm = __importStar(__nccwpck_require__(4844)); -const semver = __importStar(__nccwpck_require__(9318)); -const stream = __importStar(__nccwpck_require__(2203)); -const util = __importStar(__nccwpck_require__(9023)); -const assert_1 = __nccwpck_require__(2613); -const exec_1 = __nccwpck_require__(5236); -const retry_helper_1 = __nccwpck_require__(7380); -class HTTPError extends Error { - constructor(httpStatusCode) { - super(`Unexpected HTTP response: ${httpStatusCode}`); - this.httpStatusCode = httpStatusCode; - Object.setPrototypeOf(this, new.target.prototype); - } -} -exports.HTTPError = HTTPError; -const IS_WINDOWS = process.platform === 'win32'; -const IS_MAC = process.platform === 'darwin'; -const userAgent = 'actions/tool-cache'; -/** - * Download a tool from an url and stream it into a file - * - * @param url url of tool to download - * @param dest path to download tool - * @param auth authorization header - * @param headers other headers - * @returns path to downloaded tool - */ -function downloadTool(url, dest, auth, headers) { - return __awaiter(this, void 0, void 0, function* () { - dest = dest || path.join(_getTempDirectory(), crypto.randomUUID()); - yield io.mkdirP(path.dirname(dest)); - core.debug(`Downloading ${url}`); - core.debug(`Destination ${dest}`); - const maxAttempts = 3; - const minSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS', 10); - const maxSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS', 20); - const retryHelper = new retry_helper_1.RetryHelper(maxAttempts, minSeconds, maxSeconds); - return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { - return yield downloadToolAttempt(url, dest || '', auth, headers); - }), (err) => { - if (err instanceof HTTPError && err.httpStatusCode) { - // Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests - if (err.httpStatusCode < 500 && - err.httpStatusCode !== 408 && - err.httpStatusCode !== 429) { - return false; - } - } - // Otherwise retry - return true; - }); - }); -} -exports.downloadTool = downloadTool; -function downloadToolAttempt(url, dest, auth, headers) { - return __awaiter(this, void 0, void 0, function* () { - if (fs.existsSync(dest)) { - throw new Error(`Destination file path ${dest} already exists`); - } - // Get the response headers - const http = new httpm.HttpClient(userAgent, [], { - allowRetries: false - }); - if (auth) { - core.debug('set auth'); - if (headers === undefined) { - headers = {}; - } - headers.authorization = auth; - } - const response = yield http.get(url, headers); - if (response.message.statusCode !== 200) { - const err = new HTTPError(response.message.statusCode); - core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); - throw err; - } - // Download the response body - const pipeline = util.promisify(stream.pipeline); - const responseMessageFactory = _getGlobal('TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY', () => response.message); - const readStream = responseMessageFactory(); - let succeeded = false; - try { - yield pipeline(readStream, fs.createWriteStream(dest)); - core.debug('download complete'); - succeeded = true; - return dest; - } - finally { - // Error, delete dest before retry - if (!succeeded) { - core.debug('download failed'); - try { - yield io.rmRF(dest); - } - catch (err) { - core.debug(`Failed to delete '${dest}'. ${err.message}`); - } - } - } - }); -} -/** - * Extract a .7z file - * - * @param file path to the .7z file - * @param dest destination directory. Optional. - * @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this - * problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will - * gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is - * bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line - * interface, it is smaller than the full command line interface, and it does support long paths. At the - * time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. - * Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path - * to 7zr.exe can be pass to this function. - * @returns path to the destination directory - */ -function extract7z(file, dest, _7zPath) { - return __awaiter(this, void 0, void 0, function* () { - (0, assert_1.ok)(IS_WINDOWS, 'extract7z() not supported on current OS'); - (0, assert_1.ok)(file, 'parameter "file" is required'); - dest = yield _createExtractFolder(dest); - const originalCwd = process.cwd(); - process.chdir(dest); - if (_7zPath) { - try { - const logLevel = core.isDebug() ? '-bb1' : '-bb0'; - const args = [ - 'x', - logLevel, - '-bd', - '-sccUTF-8', - file - ]; - const options = { - silent: true - }; - yield (0, exec_1.exec)(`"${_7zPath}"`, args, options); - } - finally { - process.chdir(originalCwd); - } - } - else { - const escapedScript = path - .join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') - .replace(/'/g, "''") - .replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines - const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); - const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); - const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; - const args = [ - '-NoLogo', - '-Sta', - '-NoProfile', - '-NonInteractive', - '-ExecutionPolicy', - 'Unrestricted', - '-Command', - command - ]; - const options = { - silent: true - }; - try { - const powershellPath = yield io.which('powershell', true); - yield (0, exec_1.exec)(`"${powershellPath}"`, args, options); - } - finally { - process.chdir(originalCwd); - } - } - return dest; - }); -} -exports.extract7z = extract7z; -/** - * Extract a compressed tar archive - * - * @param file path to the tar - * @param dest destination directory. Optional. - * @param flags flags for the tar command to use for extraction. Defaults to 'xz' (extracting gzipped tars). Optional. - * @returns path to the destination directory - */ -function extractTar(file, dest, flags = 'xz') { - return __awaiter(this, void 0, void 0, function* () { - if (!file) { - throw new Error("parameter 'file' is required"); - } - // Create dest - dest = yield _createExtractFolder(dest); - // Determine whether GNU tar - core.debug('Checking tar --version'); - let versionOutput = ''; - yield (0, exec_1.exec)('tar --version', [], { - ignoreReturnCode: true, - silent: true, - listeners: { - stdout: (data) => (versionOutput += data.toString()), - stderr: (data) => (versionOutput += data.toString()) - } - }); - core.debug(versionOutput.trim()); - const isGnuTar = versionOutput.toUpperCase().includes('GNU TAR'); - // Initialize args - let args; - if (flags instanceof Array) { - args = flags; - } - else { - args = [flags]; - } - if (core.isDebug() && !flags.includes('v')) { - args.push('-v'); - } - let destArg = dest; - let fileArg = file; - if (IS_WINDOWS && isGnuTar) { - args.push('--force-local'); - destArg = dest.replace(/\\/g, '/'); - // Technically only the dest needs to have `/` but for aesthetic consistency - // convert slashes in the file arg too. - fileArg = file.replace(/\\/g, '/'); - } - if (isGnuTar) { - // Suppress warnings when using GNU tar to extract archives created by BSD tar - args.push('--warning=no-unknown-keyword'); - args.push('--overwrite'); - } - args.push('-C', destArg, '-f', fileArg); - yield (0, exec_1.exec)(`tar`, args); - return dest; - }); -} -exports.extractTar = extractTar; -/** - * Extract a xar compatible archive - * - * @param file path to the archive - * @param dest destination directory. Optional. - * @param flags flags for the xar. Optional. - * @returns path to the destination directory - */ -function extractXar(file, dest, flags = []) { - return __awaiter(this, void 0, void 0, function* () { - (0, assert_1.ok)(IS_MAC, 'extractXar() not supported on current OS'); - (0, assert_1.ok)(file, 'parameter "file" is required'); - dest = yield _createExtractFolder(dest); - let args; - if (flags instanceof Array) { - args = flags; - } - else { - args = [flags]; - } - args.push('-x', '-C', dest, '-f', file); - if (core.isDebug()) { - args.push('-v'); - } - const xarPath = yield io.which('xar', true); - yield (0, exec_1.exec)(`"${xarPath}"`, _unique(args)); - return dest; - }); + close (callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.close((err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + const err = new ClientDestroyedError() + queueMicrotask(() => callback(err, null)) + return + } + + if (this[kClosed]) { + if (this[kOnClosed]) { + this[kOnClosed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } + + this[kClosed] = true + this[kOnClosed] ??= [] + this[kOnClosed].push(callback) + + const onClosed = () => { + const callbacks = this[kOnClosed] + this[kOnClosed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } + + // Should not error. + this[kClose]() + .then(() => this.destroy()) + .then(() => queueMicrotask(onClosed)) + } + + destroy (err, callback) { + if (typeof err === 'function') { + callback = err + err = null + } + + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.destroy(err, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + if (this[kOnDestroyed]) { + this[kOnDestroyed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } + + if (!err) { + err = new ClientDestroyedError() + } + + this[kDestroyed] = true + this[kOnDestroyed] ??= [] + this[kOnDestroyed].push(callback) + + const onDestroyed = () => { + const callbacks = this[kOnDestroyed] + this[kOnDestroyed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } + + // Should not error. + this[kDestroy](err) + .then(() => queueMicrotask(onDestroyed)) + } + + dispatch (opts, handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + try { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object.') + } + + if (opts.dispatcher) { + throw new InvalidArgumentError('opts.dispatcher is not supported by instance methods. Pass opts.dispatcher to the top-level undici functions or call the dispatcher instance method directly.') + } + + if (this[kDestroyed] || this[kOnDestroyed]) { + throw new ClientDestroyedError() + } + + if (this[kClosed]) { + throw new ClientClosedError() + } + + return this[kDispatch](opts, handler) + } catch (err) { + if (typeof handler.onResponseError !== 'function') { + throw err + } + + handler.onResponseError(null, err) + + return false + } + } } -exports.extractXar = extractXar; -/** - * Extract a zip - * - * @param file path to the zip - * @param dest destination directory. Optional. - * @returns path to the destination directory - */ -function extractZip(file, dest) { - return __awaiter(this, void 0, void 0, function* () { - if (!file) { - throw new Error("parameter 'file' is required"); - } - dest = yield _createExtractFolder(dest); - if (IS_WINDOWS) { - yield extractZipWin(file, dest); - } - else { - yield extractZipNix(file, dest); - } - return dest; - }); + +module.exports = DispatcherBase + + +/***/ }), + +/***/ 883: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + +const EventEmitter = __nccwpck_require__(8474) +const { kOriginless, kUrl } = __nccwpck_require__(6443) + +class Dispatcher extends EventEmitter { + dispatch () { + throw new Error('not implemented') + } + + close () { + throw new Error('not implemented') + } + + destroy () { + throw new Error('not implemented') + } + + compose (...args) { + // So we handle [interceptor1, interceptor2] or interceptor1, interceptor2, ... + const interceptors = Array.isArray(args[0]) ? args[0] : args + // null disables origin-dependent interceptors; undefined uses opts.origin. + const interceptorOrigin = this[kOriginless] === true + ? null + : this[kUrl]?.origin + let dispatch = this.dispatch.bind(this) + + for (const interceptor of interceptors) { + if (interceptor == null) { + continue + } + + if (typeof interceptor !== 'function') { + throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`) + } + + dispatch = interceptor(dispatch, interceptorOrigin) + + if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) { + throw new TypeError('invalid interceptor') + } + } + + const originalDispatch = dispatch + const self = this + dispatch = function (opts, handler) { + if (opts && typeof opts === 'object' && !opts.origin && self[kUrl]) { + opts = Object.assign({}, opts, { origin: self[kUrl].origin }) + } + return originalDispatch(opts, handler) + } + + return new Proxy(this, { + get: (target, key) => key === 'dispatch' ? dispatch : target[key] + }) + } } -exports.extractZip = extractZip; -function extractZipWin(file, dest) { - return __awaiter(this, void 0, void 0, function* () { - // build the powershell command - const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines - const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); - const pwshPath = yield io.which('pwsh', false); - //To match the file overwrite behavior on nix systems, we use the overwrite = true flag for ExtractToDirectory - //and the -Force flag for Expand-Archive as a fallback - if (pwshPath) { - //attempt to use pwsh with ExtractToDirectory, if this fails attempt Expand-Archive - const pwshCommand = [ - `$ErrorActionPreference = 'Stop' ;`, - `try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`, - `try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`, - `catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { throw $_ } } ;` - ].join(' '); - const args = [ - '-NoLogo', - '-NoProfile', - '-NonInteractive', - '-ExecutionPolicy', - 'Unrestricted', - '-Command', - pwshCommand - ]; - core.debug(`Using pwsh at path: ${pwshPath}`); - yield (0, exec_1.exec)(`"${pwshPath}"`, args); - } - else { - const powershellCommand = [ - `$ErrorActionPreference = 'Stop' ;`, - `try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`, - `if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force }`, - `else {[System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }` - ].join(' '); - const args = [ - '-NoLogo', - '-Sta', - '-NoProfile', - '-NonInteractive', - '-ExecutionPolicy', - 'Unrestricted', - '-Command', - powershellCommand - ]; - const powershellPath = yield io.which('powershell', true); - core.debug(`Using powershell at path: ${powershellPath}`); - yield (0, exec_1.exec)(`"${powershellPath}"`, args); - } - }); + +module.exports = Dispatcher + + +/***/ }), + +/***/ 3650: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Dispatcher = __nccwpck_require__(883) +const { InvalidArgumentError } = __nccwpck_require__(8707) +const { toRawHeaders } = __nccwpck_require__(3440) +const { kOriginless, kUrl } = __nccwpck_require__(6443) + +class LegacyHandlerWrapper { + #handler + + constructor (handler) { + this.#handler = handler + } + + onRequestStart (controller, context) { + this.#handler.onConnect?.((reason) => controller.abort(reason), context) + } + + onRequestUpgrade (controller, statusCode, headers, socket) { + const rawHeaders = Array.isArray(controller?.rawHeaders) + ? controller.rawHeaders + : toRawHeaders(controller?.rawHeaders ?? headers ?? {}) + this.#handler.onUpgrade?.(statusCode, rawHeaders, socket) + } + + onResponseStart (controller, statusCode, headers, statusMessage) { + const rawHeaders = Array.isArray(controller?.rawHeaders) + ? controller.rawHeaders + : toRawHeaders(controller?.rawHeaders ?? headers ?? {}) + + if (this.#handler.onHeaders?.(statusCode, rawHeaders, () => controller.resume(), statusMessage) === false) { + controller.pause() + } + } + + onResponseData (controller, chunk) { + if (this.#handler.onData?.(chunk) === false) { + controller.pause() + } + } + + onResponseEnd (controller, trailers) { + const rawTrailers = Array.isArray(controller?.rawTrailers) + ? controller.rawTrailers + : toRawHeaders(controller?.rawTrailers ?? trailers ?? {}) + this.#handler.onComplete?.(rawTrailers) + } + + onResponseError (_controller, err) { + if (!this.#handler.onError) { + throw err + } + + this.#handler.onError(err) + } + + onBodySent (chunk) { + this.#handler.onBodySent?.(chunk) + } + + onRequestSent () { + this.#handler.onRequestSent?.() + } + + onResponseStarted () { + this.#handler.onResponseStarted?.() + } } -function extractZipNix(file, dest) { - return __awaiter(this, void 0, void 0, function* () { - const unzipPath = yield io.which('unzip', true); - const args = [file]; - if (!core.isDebug()) { - args.unshift('-q'); - } - args.unshift('-o'); //overwrite with -o, otherwise a prompt is shown which freezes the run - yield (0, exec_1.exec)(`"${unzipPath}"`, args, { cwd: dest }); - }); + +class Dispatcher1Wrapper extends Dispatcher { + #dispatcher + + constructor (dispatcher) { + super() + + if (!dispatcher || typeof dispatcher.dispatch !== 'function') { + throw new InvalidArgumentError('Argument dispatcher must implement dispatch') + } + + this.#dispatcher = dispatcher + this[kUrl] = dispatcher[kUrl] + this[kOriginless] = dispatcher[kOriginless] + } + + static wrapHandler (handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + if (typeof handler.onRequestStart === 'function') { + return handler + } + + return new LegacyHandlerWrapper(handler) + } + + dispatch (opts, handler) { + // Legacy (v1) consumers do not support HTTP/2, so force HTTP/1.1. + // See https://github.com/nodejs/undici/issues/4989 + if (opts.allowH2 !== false) { + opts = { ...opts, allowH2: false } + } + + return this.#dispatcher.dispatch(opts, Dispatcher1Wrapper.wrapHandler(handler)) + } + + // Older undici versions read WebSocket and EventSource receive limits from + // the (legacy) global dispatcher, which is this wrapper, so report the + // wrapped dispatcher's settings. + get webSocketOptions () { + return this.#dispatcher.webSocketOptions + } + + get eventSourceOptions () { + return this.#dispatcher.eventSourceOptions + } + + close (...args) { + return this.#dispatcher.close(...args) + } + + destroy (...args) { + return this.#dispatcher.destroy(...args) + } } -/** - * Caches a directory and installs it into the tool cacheDir - * - * @param sourceDir the directory to cache into tools - * @param tool tool name - * @param version version of the tool. semver format - * @param arch architecture of the tool. Optional. Defaults to machine architecture - */ -function cacheDir(sourceDir, tool, version, arch) { - return __awaiter(this, void 0, void 0, function* () { - version = semver.clean(version) || version; - arch = arch || os.arch(); - core.debug(`Caching tool ${tool} ${version} ${arch}`); - core.debug(`source dir: ${sourceDir}`); - if (!fs.statSync(sourceDir).isDirectory()) { - throw new Error('sourceDir is not a directory'); - } - // Create the tool dir - const destPath = yield _createToolPath(tool, version, arch); - // copy each child item. do not move. move can fail on Windows - // due to anti-virus software having an open handle on a file. - for (const itemName of fs.readdirSync(sourceDir)) { - const s = path.join(sourceDir, itemName); - yield io.cp(s, destPath, { recursive: true }); + +module.exports = Dispatcher1Wrapper + + +/***/ }), + +/***/ 3137: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const DispatcherBase = __nccwpck_require__(1841) +const { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = __nccwpck_require__(6443) +const ProxyAgent = __nccwpck_require__(6672) +const Agent = __nccwpck_require__(7405) + +const DEFAULT_PORTS = { + 'http:': 80, + 'https:': 443 +} + +class EnvHttpProxyAgent extends DispatcherBase { + #noProxyValue = null + #noProxyEntries = null + #opts = null + + constructor (opts = {}) { + super(opts) + this.#opts = opts + + const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts + + this[kNoProxyAgent] = new Agent(agentOpts) + + const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY + if (HTTP_PROXY) { + this[kHttpProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTP_PROXY }) + } else { + this[kHttpProxyAgent] = this[kNoProxyAgent] + } + + const HTTPS_PROXY = httpsProxy ?? process.env.https_proxy ?? process.env.HTTPS_PROXY + if (HTTPS_PROXY) { + this[kHttpsProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTPS_PROXY }) + } else { + this[kHttpsProxyAgent] = this[kHttpProxyAgent] + } + + this.#parseNoProxy() + } + + [kDispatch] (opts, handler) { + const url = new URL(opts.origin) + const agent = this.#getProxyAgentForUrl(url) + return agent.dispatch(opts, handler) + } + + [kClose] () { + return Promise.all([ + this[kNoProxyAgent].close(), + !this[kHttpProxyAgent][kClosed] && this[kHttpProxyAgent].close(), + !this[kHttpsProxyAgent][kClosed] && this[kHttpsProxyAgent].close() + ]) + } + + [kDestroy] (err) { + return Promise.all([ + this[kNoProxyAgent].destroy(err), + !this[kHttpProxyAgent][kDestroyed] && this[kHttpProxyAgent].destroy(err), + !this[kHttpsProxyAgent][kDestroyed] && this[kHttpsProxyAgent].destroy(err) + ]) + } + + #getProxyAgentForUrl (url) { + let { protocol, host: hostname, port } = url + + // Remove the port suffix (e.g. ":8080") and then strip surrounding + // brackets from IPv6 literals (e.g. "[::1]" -> "::1") so that the + // result matches the unbracketed form stored by #parseNoProxy. + hostname = hostname.replace(/:\d*$/, '').replace(/^\[(.+)\]$/, '$1').toLowerCase() + // Drop a trailing dot: it only marks the fully qualified form of a domain + // name ("example.com." and "example.com" are the same name, RFC 1034 root + // label). This runs on every dispatch, so it is a charCode check rather + // than a third regex. `length > 1` leaves the degenerate host "." alone. + if (hostname.length > 1 && hostname.charCodeAt(hostname.length - 1) === 46) { + hostname = hostname.slice(0, -1) + } + port = Number.parseInt(port, 10) || DEFAULT_PORTS[protocol] || 0 + if (!this.#shouldProxy(hostname, port)) { + return this[kNoProxyAgent] + } + if (protocol === 'https:') { + return this[kHttpsProxyAgent] + } + return this[kHttpProxyAgent] + } + + #shouldProxy (hostname, port) { + if (this.#noProxyChanged) { + this.#parseNoProxy() + } + + if (this.#noProxyEntries.length === 0) { + return true // Always proxy if NO_PROXY is not set or empty. + } + + for (let i = 0; i < this.#noProxyEntries.length; i++) { + const entry = this.#noProxyEntries[i] + // A bare `*` entry matches all hosts regardless of its position or the + // surrounding whitespace (e.g. ` * ` or `none.invalid,*`). If a port is + // attached (`*:80`) it only bypasses that port. + if (entry.hostname === '*') { + if (entry.port && entry.port !== port) { + continue } - // write .complete - _completeToolPath(tool, version, arch); - return destPath; - }); + return false // Never proxy if a wildcard entry is present. + } + if (entry.port && entry.port !== port) { + continue // Skip if ports don't match. + } + // Don't proxy if the hostname is equal with the no_proxy host. A + // `*.example.com` wildcard matches subdomains only, not the apex + // `example.com`, so exact matches are skipped for wildcard entries. + if (!entry.wildcard && hostname === entry.hostname) { + return false + } + // Don't proxy if the hostname is the subdomain of the no_proxy host. + // Reference - https://github.com/denoland/deno/blob/6fbce91e40cc07fc6da74068e5cc56fdd40f7b4c/ext/fetch/proxy.rs#L485 + if (hostname.slice(-(entry.hostname.length + 1)) === `.${entry.hostname}`) { + return false + } + } + + return true + } + + #parseNoProxy () { + const noProxyValue = this.#opts.noProxy ?? this.#noProxyEnv + const noProxySplit = noProxyValue.split(/[,\s]/) + const noProxyEntries = [] + + for (let i = 0; i < noProxySplit.length; i++) { + const entry = noProxySplit[i] + if (!entry) { + continue + } + + // An IPv6 entry with a port must be bracketed: [::1]:443. + // A bare IPv6 address like ::1 contains colons that must not be + // confused with a host:port separator, so we handle it separately. + let hostname, port + const ipv6WithPort = entry.match(/^\[(.+)\]:(\d+)$/) + if (ipv6WithPort) { + hostname = ipv6WithPort[1] + port = Number.parseInt(ipv6WithPort[2], 10) + } else { + // Bracketed IPv6 without port, or plain hostname[:port], or bare IPv6. + // Strip optional brackets first. + const unbracketed = entry.replace(/^\[(.+)\]$/, '$1') + // A bare IPv6 address contains multiple colons; a hostname:port entry + // has exactly one colon followed by digits. Only attempt host:port + // splitting when that is unambiguously the case. + const colonCount = (unbracketed.match(/:/g) || []).length + const parsed = colonCount === 1 && unbracketed.match(/^(.+):(\d+)$/) + hostname = parsed ? parsed[1] : unbracketed + port = parsed ? Number.parseInt(parsed[2], 10) : 0 + } + + // A leading `*` marks a subdomain wildcard (`*.example.com`), distinct + // from a plain or leading-dot suffix (`example.com` / `.example.com`) + // which also matches the apex. `*.example.com` must only match + // subdomains, never the apex `example.com` itself. + const wildcard = entry.charCodeAt(0) === 42 /* '*' */ + + noProxyEntries.push({ + // strip leading dot or asterisk with dot, and any trailing dot + hostname: hostname.replace(/^\*?\./, '').replace(/^(.+)\.$/, '$1').toLowerCase(), + port, + wildcard + }) + } + + this.#noProxyValue = noProxyValue + this.#noProxyEntries = noProxyEntries + } + + get #noProxyChanged () { + if (this.#opts.noProxy !== undefined) { + return false + } + return this.#noProxyValue !== this.#noProxyEnv + } + + get #noProxyEnv () { + return process.env.no_proxy ?? process.env.NO_PROXY ?? '' + } } -exports.cacheDir = cacheDir; + +module.exports = EnvHttpProxyAgent + + +/***/ }), + +/***/ 4660: +/***/ ((module) => { + +"use strict"; + + +// Extracted from node/lib/internal/fixed_queue.js + +// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. +const kSize = 2048 +const kMask = kSize - 1 + +// The FixedQueue is implemented as a singly-linked list of fixed-size +// circular buffers. It looks something like this: +// +// head tail +// | | +// v v +// +-----------+ <-----\ +-----------+ <------\ +-----------+ +// | [null] | \----- | next | \------- | next | +// +-----------+ +-----------+ +-----------+ +// | item | <-- bottom | item | <-- bottom | undefined | +// | item | | item | | undefined | +// | item | | item | | undefined | +// | item | | item | | undefined | +// | item | | item | bottom --> | item | +// | item | | item | | item | +// | ... | | ... | | ... | +// | item | | item | | item | +// | item | | item | | item | +// | undefined | <-- top | item | | item | +// | undefined | | item | | item | +// | undefined | | undefined | <-- top top --> | undefined | +// +-----------+ +-----------+ +-----------+ +// +// Or, if there is only one circular buffer, it looks something +// like either of these: +// +// head tail head tail +// | | | | +// v v v v +// +-----------+ +-----------+ +// | [null] | | [null] | +// +-----------+ +-----------+ +// | undefined | | item | +// | undefined | | item | +// | item | <-- bottom top --> | undefined | +// | item | | undefined | +// | undefined | <-- top bottom --> | item | +// | undefined | | item | +// +-----------+ +-----------+ +// +// Adding a value means moving `top` forward by one, removing means +// moving `bottom` forward by one. After reaching the end, the queue +// wraps around. +// +// When `top === bottom` the current queue is empty and when +// `top + 1 === bottom` it's full. This wastes a single space of storage +// but allows much quicker checks. + /** - * Caches a downloaded file (GUID) and installs it - * into the tool cache with a given targetName - * - * @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. - * @param targetFile the name of the file name in the tools directory - * @param tool tool name - * @param version version of the tool. semver format - * @param arch architecture of the tool. Optional. Defaults to machine architecture + * @type {FixedCircularBuffer} + * @template T */ -function cacheFile(sourceFile, targetFile, tool, version, arch) { - return __awaiter(this, void 0, void 0, function* () { - version = semver.clean(version) || version; - arch = arch || os.arch(); - core.debug(`Caching tool ${tool} ${version} ${arch}`); - core.debug(`source file: ${sourceFile}`); - if (!fs.statSync(sourceFile).isFile()) { - throw new Error('sourceFile is not a file'); - } - // create the tool dir - const destFolder = yield _createToolPath(tool, version, arch); - // copy instead of move. move can fail on Windows due to - // anti-virus software having an open handle on a file. - const destPath = path.join(destFolder, targetFile); - core.debug(`destination file ${destPath}`); - yield io.cp(sourceFile, destPath); - // write .complete - _completeToolPath(tool, version, arch); - return destFolder; - }); +class FixedCircularBuffer { + /** @type {number} */ + bottom = 0 + /** @type {number} */ + top = 0 + /** @type {Array} */ + list = new Array(kSize).fill(undefined) + /** @type {T|null} */ + next = null + + /** @returns {boolean} */ + isEmpty () { + return this.top === this.bottom + } + + /** @returns {boolean} */ + isFull () { + return ((this.top + 1) & kMask) === this.bottom + } + + /** + * @param {T} data + * @returns {void} + */ + push (data) { + this.list[this.top] = data + this.top = (this.top + 1) & kMask + } + + /** @returns {T|null} */ + shift () { + const nextItem = this.list[this.bottom] + if (nextItem === undefined) { return null } + this.list[this.bottom] = undefined + this.bottom = (this.bottom + 1) & kMask + return nextItem + } } -exports.cacheFile = cacheFile; + /** - * Finds the path to a tool version in the local installed tool cache - * - * @param toolName name of the tool - * @param versionSpec version of the tool - * @param arch optional arch. defaults to arch of computer + * @template T */ -function find(toolName, versionSpec, arch) { - if (!toolName) { - throw new Error('toolName parameter is required'); +module.exports = class FixedQueue { + constructor () { + /** @type {FixedCircularBuffer} */ + this.head = this.tail = new FixedCircularBuffer() + } + + /** @returns {boolean} */ + isEmpty () { + return this.head.isEmpty() + } + + /** @param {T} data */ + push (data) { + if (this.head.isFull()) { + // Head is full: Creates a new queue, sets the old queue's `.next` to it, + // and sets it as the new main queue. + this.head = this.head.next = new FixedCircularBuffer() + } + this.head.push(data) + } + + /** @returns {T|null} */ + shift () { + const tail = this.tail + const next = tail.shift() + if (tail.isEmpty() && tail.next !== null) { + // If there is another queue, it forms the new tail. + this.tail = tail.next + tail.next = null + } + return next + } +} + + +/***/ }), + +/***/ 6815: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { InvalidArgumentError } = __nccwpck_require__(8707) +const Client = __nccwpck_require__(3701) + +class H2CClient extends Client { + constructor (origin, clientOpts) { + if (typeof origin === 'string') { + origin = new URL(origin) + } + + if (origin.protocol !== 'http:') { + throw new InvalidArgumentError( + 'h2c-client: Only h2c protocol is supported' + ) + } + + const { maxConcurrentStreams, pipelining, ...opts } = + clientOpts ?? {} + const defaultMaxConcurrentStreams = maxConcurrentStreams ?? 100 + let defaultPipelining = 100 + + if ( + maxConcurrentStreams != null && + (!Number.isInteger(maxConcurrentStreams) || + maxConcurrentStreams < 1) + ) { + throw new InvalidArgumentError('maxConcurrentStreams must be a positive integer, greater than 0') + } + + if (pipelining != null && Number.isInteger(pipelining) && pipelining > 0) { + defaultPipelining = pipelining + } + + if (defaultPipelining > defaultMaxConcurrentStreams) { + throw new InvalidArgumentError( + 'h2c-client: pipelining cannot be greater than maxConcurrentStreams' + ) + } + + super(origin, { + ...opts, + maxConcurrentStreams: defaultMaxConcurrentStreams, + pipelining: defaultPipelining, + allowH2: true, + useH2c: true + }) + } +} + +module.exports = H2CClient + + +/***/ }), + +/***/ 1969: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(4589) +const util = __nccwpck_require__(3440) +const timers = __nccwpck_require__(6603) +const { + HeadersTimeoutError, + HeadersOverflowError, + SocketError, + InformationalError, + BodyTimeoutError, + HTTPParserError, + ResponseContentLengthMismatchError, + ResponseExceededMaxSizeError +} = __nccwpck_require__(8707) +const { + kUrl, + kReset, + kClient, + kParser, + kBlocking, + kRunning, + kWriting, + kQueue, + kKeepAliveDefaultTimeout, + kRunningIdx, + kError, + kPipelining, + kSocket, + kKeepAliveTimeoutValue, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kBodyTimeout, + kMaxResponseSize, + kResume, + kHTTPContext, + kMaxHeadersSize +} = __nccwpck_require__(6443) + +const FastBuffer = Buffer[Symbol.species] +const removeAllListeners = util.removeAllListeners + +const kPausedByHandler = Symbol('kPausedByHandler') + +const BUFFER_PAGE_SIZE = 4096 +const INITIAL_BUFFER_SIZE = 128 * 1024 +const EMPTY_BUF = Buffer.alloc(0) +const BODY_KIND_CONTENT_LENGTH = 0 +const EVENT_RANGE_SIZE = 9 +const EVENT_HEADERS_SIZE = 19 + +let miloPackage + +// We disable wasm SIMD on ppc64 as it seems to be broken on Power 9 architectures. +let useWasmSIMD = process.arch !== 'ppc64' +// The Env Variable UNDICI_NO_WASM_SIMD allows explicitly overriding the default behavior. +if (process.env.UNDICI_NO_WASM_SIMD === '1') { + useWasmSIMD = false +} else if (process.env.UNDICI_NO_WASM_SIMD === '0') { + useWasmSIMD = true +} + +const USE_NATIVE_TIMER = 0 +const USE_FAST_TIMER = 1 +const TIMEOUT_HEADERS = 2 | USE_FAST_TIMER +const TIMEOUT_BODY = 4 | USE_FAST_TIMER +const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER + +let miloEnabled = + process.env.UNDICI_USE_MILO === '1' || process.env.UNDICI_USE_MILO === 'true' +let miloInstance = null +let currentBuffer = null +let currentBufferSize = 0 +let currentBufferPtr = null +let currentBufferRef = null + +function onParserTimeout (parserWeakRef) { + const parser = parserWeakRef.deref ? parserWeakRef.deref() : parserWeakRef + if (!parser) { + return + } + + const { socket, timeoutType, client, paused } = parser + + if (timeoutType === TIMEOUT_HEADERS) { + if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { + assert(!paused, 'cannot be paused while waiting for headers') + util.destroy(socket, new HeadersTimeoutError()) + } + } else if (timeoutType === TIMEOUT_BODY) { + if (!paused) { + util.destroy(socket, new BodyTimeoutError()) + } + } else if (timeoutType === TIMEOUT_KEEP_ALIVE) { + assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) + util.destroy(socket, new InformationalError('socket idle timeout')) + } +} + +function getMilo () { + if (miloInstance) { + return miloInstance + } + + // Milo modules compile WASM on load; defer loading until the parser is needed. + if (useWasmSIMD) { + try { + miloPackage = __nccwpck_require__(9545) + } catch {} + } + + miloPackage = miloPackage || __nccwpck_require__(5997) + miloInstance = miloPackage.setup() + return miloInstance +} + +class H1Parser { + constructor (client, socket) { + this.milo = getMilo() + + this.client = client + this.socket = socket + this.parser = this.milo.create() + this.events = new FastBuffer( + this.milo.memory.buffer, + this.parser + this.milo.ParserFields.EVENTS, + 4 + ).readUInt32LE(0) + + this.milo.setShouldAutodetect(this.parser, false) + this.milo.setIsRequest(this.parser, false) + this.milo.setShouldManageUnconsumed(this.parser, false) + this.milo.setShouldSuspendAfterHeaders(this.parser, true) + this.milo.setMaxHeaderLength(this.parser, client[kMaxHeadersSize]) + this.milo.setActiveEvents( + this.parser, + this.milo.EVENT_ACTIVE_ON_ERROR | + this.milo.EVENT_ACTIVE_ON_MESSAGE_COMPLETE | + this.milo.EVENT_ACTIVE_ON_REASON | + this.milo.EVENT_ACTIVE_ON_HEADER_NAME | + this.milo.EVENT_ACTIVE_ON_HEADER_VALUE | + this.milo.EVENT_ACTIVE_ON_HEADERS | + this.milo.EVENT_ACTIVE_ON_DATA | + this.milo.EVENT_ACTIVE_ON_TRAILER_NAME | + this.milo.EVENT_ACTIVE_ON_TRAILER_VALUE + ) + + this.timeout = null + this.timeoutWeakRef = new WeakRef(this) + this.timeoutValue = null + this.timeoutType = null + this.statusCode = 0 + this.statusText = '' + this.upgrade = false + this.responseStarted = false + this.pausedByParser = false + this.pauseStateIsStart = false + this.headers = [] + this.trailers = [] + this.headersSize = 0 + this.trailersSize = 0 + this.headersMaxSize = client[kMaxHeadersSize] + this.shouldKeepAlive = false + this.paused = false + this.errored = false + this.waitingForMoreData = 0 + this.resume = this.resume.bind(this) + this.bytesRead = 0 + this.keepAlive = '' + this.connection = '' + this.contentLength = -1 + this.maxResponseSize = client[kMaxResponseSize] + this.directBodyRemaining = 0 + this.directBodyCompletePending = false + this.headersSuspended = false + this.skipBody = false + + this[kPausedByHandler] = false + + if ( + INITIAL_BUFFER_SIZE > currentBufferSize || + currentBuffer.buffer !== this.milo.memory.buffer + ) { + this.ensureBuffers(INITIAL_BUFFER_SIZE) + } else { + this.updateBuffers() + } + } + + setTimeout (delay, type) { + if ( + delay !== this.timeoutValue || + (type & USE_FAST_TIMER) ^ (this.timeoutType & USE_FAST_TIMER) + ) { + if (this.timeout) { + timers.clearTimeout(this.timeout) + this.timeout = null + } + + if (delay) { + if (type & USE_FAST_TIMER) { + this.timeout = timers.setFastTimeout( + onParserTimeout, + delay, + this.timeoutWeakRef + ) + } else { + this.timeout = setTimeout( + onParserTimeout, + delay, + this.timeoutWeakRef + ) + this.timeout?.unref() + } + } + + this.timeoutValue = delay + } else if (this.timeout?.refresh) { + this.timeout.refresh() + } + + this.timeoutType = type + } + + ensureBuffers (size) { + const { milo } = this + + if (currentBufferPtr != null) { + milo.dealloc(currentBufferPtr, currentBufferSize) } - if (!versionSpec) { - throw new Error('versionSpec parameter is required'); + + // Reallocate buffers + currentBufferSize = Math.ceil(size / BUFFER_PAGE_SIZE) * BUFFER_PAGE_SIZE + currentBufferPtr = milo.alloc(currentBufferSize) + currentBuffer = new FastBuffer( + milo.memory.buffer, + currentBufferPtr, + currentBufferSize + ) + + this.updateBuffers() + } + + updateBuffers () { + this.parserFields = new FastBuffer(this.milo.memory.buffer, this.parser) + this.parserEvents = new FastBuffer( + this.milo.memory.buffer, + this.events, + 64 * 1024 + ) + } + + resume () { + if (this.socket.destroyed || !this.paused) { + return } - arch = arch || os.arch(); - // attempt to resolve an explicit version - if (!isExplicitVersion(versionSpec)) { - const localVersions = findAllVersions(toolName, arch); - const match = evaluateVersions(localVersions, versionSpec); - versionSpec = match; + + this.milo.resume(this.parser) + + assert(this.timeoutType === TIMEOUT_BODY) + if (this.timeout?.refresh) { + this.timeout.refresh() } - // check for the explicit version in the cache - let toolPath = ''; - if (versionSpec) { - versionSpec = semver.clean(versionSpec) || ''; - const cachePath = path.join(_getCacheDirectory(), toolName, versionSpec, arch); - core.debug(`checking cache: ${cachePath}`); - if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { - core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); - toolPath = cachePath; - } - else { - core.debug('not found'); - } + + this.paused = false + if (this.directBodyCompletePending) { + try { + this.completeDirectBody() + } catch (err) { + util.destroy(this.socket, err) + return + } + + if (this.paused) { + return + } } - return toolPath; -} -exports.find = find; -/** - * Finds the paths to all versions of a tool that are installed in the local tool cache - * - * @param toolName name of the tool - * @param arch optional arch. defaults to arch of computer - */ -function findAllVersions(toolName, arch) { - const versions = []; - arch = arch || os.arch(); - const toolPath = path.join(_getCacheDirectory(), toolName); - if (fs.existsSync(toolPath)) { - const children = fs.readdirSync(toolPath); - for (const child of children) { - if (isExplicitVersion(child)) { - const fullPath = path.join(toolPath, child, arch || ''); - if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { - versions.push(child); - } - } - } + + this.readMore() + } + + readMore () { + if (this.paused || !this.parser) { + return } - return versions; -} -exports.findAllVersions = findAllVersions; -function getManifestFromRepo(owner, repo, auth, branch = 'master') { - return __awaiter(this, void 0, void 0, function* () { - let releases = []; - const treeUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}`; - const http = new httpm.HttpClient('tool-cache'); - const headers = {}; - if (auth) { - core.debug('set auth'); - headers.authorization = auth; + + while (!this.paused && this.parser) { + if ( + this.waitingForMoreData && + this.socket.readableLength <= this.waitingForMoreData + ) { + break + } + + this.waitingForMoreData = 0 + + const chunk = this.socket.read() + if (chunk === null) { + break + } + + if (this.execute(chunk) === false) { + break + } + } + } + + execute (data) { + const available = data.length + assert(!this.paused) + + const { socket, milo } = this + + try { + if (this.directBodyRemaining > 0) { + return this.consumeDirectBody(data) + } + + if (currentBuffer.buffer !== milo.memory.buffer) { + currentBuffer = new FastBuffer( + milo.memory.buffer, + currentBufferPtr, + currentBufferSize + ) + this.updateBuffers() + } else if (this.parserEvents.buffer !== milo.memory.buffer) { + this.updateBuffers() + } + + let offset = 0 + let parseLen = available + const headersEnd = this.statusCode === 0 ? data.indexOf('\r\n\r\n') : -1 + + if (headersEnd !== -1) { + parseLen = headersEnd + 4 + } + + for (;;) { + if (parseLen > currentBufferSize) { + this.ensureBuffers(parseLen) } - const response = yield http.getJson(treeUrl, headers); - if (!response.result) { - return releases; + + const parseData = data.subarray(offset, offset + parseLen) + currentBuffer.set(parseData) + currentBufferRef = parseData + + const consumed = milo.parse(this.parser, currentBufferPtr, parseLen) + this.drainEvents() + + const consumedTotal = offset + consumed + + if ( + this.errored || + (consumed === 0 && + this.parserFields[milo.ParserFields.ERROR_CODE] !== milo.ERROR_NONE) + ) { + throw this.createError(data.subarray(consumedTotal)) + } else if (this.upgrade) { + this.onUpgrade(data.subarray(consumedTotal)) + return false + } else if (this.directBodyCompletePending) { + this.completeDirectBody() + + if (this.paused) { + return false + } + } else if (this.pausedByParser) { + this.pausedByParser = false + this.headersSuspended = false + if (this[kPausedByHandler] && this.pauseStateIsStart) { + this.pauseStateIsStart = false + milo.resume(this.parser) + this[kPausedByHandler] = false + return false + } + + this.pauseStateIsStart = false + this.paused = true + socket.unshift(data.subarray(consumedTotal)) + return false } - let manifestUrl = ''; - for (const item of response.result.tree) { - if (item.path === 'versions-manifest.json') { - manifestUrl = item.url; - break; - } + + if (this.directBodyRemaining > 0) { + return this.consumeDirectBody(data.subarray(consumedTotal)) } - headers['accept'] = 'application/vnd.github.VERSION.raw'; - let versionsRaw = yield (yield http.get(manifestUrl, headers)).readBody(); - if (versionsRaw) { - // shouldn't be needed but protects against invalid json saved with BOM - versionsRaw = versionsRaw.replace(/^\uFEFF/, ''); - try { - releases = JSON.parse(versionsRaw); - } - catch (_a) { - core.debug('Invalid json'); - } + + if (consumed < parseLen) { + const remaining = data.subarray(consumedTotal) + socket.unshift(remaining) + this.waitingForMoreData = consumed === 0 ? remaining.length : 0 + return false } - return releases; - }); -} -exports.getManifestFromRepo = getManifestFromRepo; -function findFromManifest(versionSpec, stable, manifest, archFilter = os.arch()) { - return __awaiter(this, void 0, void 0, function* () { - // wrap the internal impl - const match = yield mm._findMatch(versionSpec, stable, manifest, archFilter); - return match; - }); -} -exports.findFromManifest = findFromManifest; -function _createExtractFolder(dest) { - return __awaiter(this, void 0, void 0, function* () { - if (!dest) { - // create a temp dir - dest = path.join(_getTempDirectory(), crypto.randomUUID()); + + offset = consumedTotal + + if (offset >= available) { + if (this.headersSuspended) { + this.headersSuspended = false + parseLen = 0 + continue + } + + return true } - yield io.mkdirP(dest); - return dest; - }); -} -function _createToolPath(tool, version, arch) { - return __awaiter(this, void 0, void 0, function* () { - const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); - core.debug(`destination ${folderPath}`); - const markerPath = `${folderPath}.complete`; - yield io.rmRF(folderPath); - yield io.rmRF(markerPath); - yield io.mkdirP(folderPath); - return folderPath; - }); -} -function _completeToolPath(tool, version, arch) { - const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); - const markerPath = `${folderPath}.complete`; - fs.writeFileSync(markerPath, ''); - core.debug('finished caching tool'); -} -/** - * Check if version string is explicit - * - * @param versionSpec version string to check - */ -function isExplicitVersion(versionSpec) { - const c = semver.clean(versionSpec) || ''; - core.debug(`isExplicit: ${c}`); - const valid = semver.valid(c) != null; - core.debug(`explicit? ${valid}`); - return valid; -} -exports.isExplicitVersion = isExplicitVersion; -/** - * Get the highest satisfiying semantic version in `versions` which satisfies `versionSpec` - * - * @param versions array of versions to evaluate - * @param versionSpec semantic version spec to satisfy - */ -function evaluateVersions(versions, versionSpec) { - let version = ''; - core.debug(`evaluating ${versions.length} versions`); - versions = versions.sort((a, b) => { - if (semver.gt(a, b)) { - return 1; + + this.headersSuspended = false + parseLen = available - offset + } + } catch (err) { + util.destroy(socket, err) + return false + } finally { + currentBufferRef = null + } + } + + consumeDirectBody (data) { + const { socket, client, maxResponseSize } = this + const available = data.length + const len = Math.min(available, this.directBodyRemaining) + + if (this.timeout?.refresh) { + this.timeout.refresh() + } + + if (len > 0) { + const request = client[kQueue][client[kRunningIdx]] + assert(request) + assert(this.timeoutType === TIMEOUT_BODY) + assert(this.statusCode >= 200) + + if (maxResponseSize > -1 && this.bytesRead + len > maxResponseSize) { + throw new ResponseExceededMaxSizeError() + } + + this.bytesRead += len + this.directBodyRemaining -= len + + if (request.onResponseData(data.subarray(0, len)) === false) { + this.directBodyCompletePending = this.directBodyRemaining === 0 + this.pauseParser() + this[kPausedByHandler] = true + this.pausedByParser = false + this.paused = true + + if (len < available) { + socket.unshift(data.subarray(len)) } - return -1; - }); - for (let i = versions.length - 1; i >= 0; i--) { - const potential = versions[i]; - const satisfied = semver.satisfies(potential, versionSpec); - if (satisfied) { - version = potential; - break; + + return false + } + } + + if (this.directBodyRemaining === 0) { + this.completeDirectBody() + + const remaining = data.subarray(len) + if ( + this.errored || + this.parserFields[this.milo.ParserFields.ERROR_CODE] !== + this.milo.ERROR_NONE + ) { + throw this.createError(remaining) + } else if (this.pausedByParser) { + this.pausedByParser = false + this.pauseStateIsStart = false + this.paused = true + if (remaining.length > 0) { + socket.unshift(remaining) } + return false + } + + if (remaining.length > 0) { + socket.unshift(remaining) + return false + } + } + + return true + } + + completeDirectBody () { + const { milo } = this + + if (currentBuffer.buffer !== milo.memory.buffer) { + currentBuffer = new FastBuffer( + milo.memory.buffer, + currentBufferPtr, + currentBufferSize + ) + this.updateBuffers() + } else if (this.parserEvents.buffer !== milo.memory.buffer) { + this.updateBuffers() } - if (version) { - core.debug(`matched: ${version}`); + + this.directBodyCompletePending = false + currentBufferRef = EMPTY_BUF + + milo.complete(this.parser) + this.drainEvents() + } + + setShouldSkipBody (value) { + if (this.skipBody !== value) { + this.skipBody = value + this.milo.setShouldSkipBody(this.parser, value) } - else { - core.debug('match not found'); + } + + finish () { + if (!this.parser) { + return null } - return version; -} -exports.evaluateVersions = evaluateVersions; -/** - * Gets RUNNER_TOOL_CACHE - */ -function _getCacheDirectory() { - const cacheDirectory = process.env['RUNNER_TOOL_CACHE'] || ''; - (0, assert_1.ok)(cacheDirectory, 'Expected RUNNER_TOOL_CACHE to be defined'); - return cacheDirectory; -} -/** - * Gets RUNNER_TEMP - */ -function _getTempDirectory() { - const tempDirectory = process.env['RUNNER_TEMP'] || ''; - (0, assert_1.ok)(tempDirectory, 'Expected RUNNER_TEMP to be defined'); - return tempDirectory; -} -/** - * Gets a global variable - */ -function _getGlobal(key, defaultValue) { - /* eslint-disable @typescript-eslint/no-explicit-any */ - const value = global[key]; - /* eslint-enable @typescript-eslint/no-explicit-any */ - return value !== undefined ? value : defaultValue; -} -/** - * Returns an array of unique values. - * @param values Values to make unique. - */ -function _unique(values) { - return Array.from(new Set(values)); -} -//# sourceMappingURL=tool-cache.js.map -/***/ }), + if (this.directBodyRemaining > 0) { + return new ResponseContentLengthMismatchError() + } + + if (this.parserEvents.buffer !== this.milo.memory.buffer) { + this.updateBuffers() + } -/***/ 9318: -/***/ ((module, exports) => { + this.milo.finish(this.parser) + this.drainEvents() -exports = module.exports = SemVer + if (!this.errored) { + return null + } -var debug -/* istanbul ignore next */ -if (typeof process === 'object' && - process.env && - process.env.NODE_DEBUG && - /\bsemver\b/i.test(process.env.NODE_DEBUG)) { - debug = function () { - var args = Array.prototype.slice.call(arguments, 0) - args.unshift('SEMVER') - console.log.apply(console, args) + return this.createError(EMPTY_BUF) } -} else { - debug = function () {} -} -// Note: this is the semver.org version of the spec that it implements -// Not necessarily the package version of this code. -exports.SEMVER_SPEC_VERSION = '2.0.0' + createError (data) { + const { contentLength, bytesRead } = this -var MAX_LENGTH = 256 -var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || - /* istanbul ignore next */ 9007199254740991 + if (contentLength !== -1 && bytesRead !== contentLength) { + return new ResponseContentLengthMismatchError() + } -// Max safe segment length for coercion. -var MAX_SAFE_COMPONENT_LENGTH = 16 + const errorCode = this.parserFields[this.milo.ParserFields.ERROR_CODE] + const errorName = this.milo.Errors[errorCode] + const errorDescription = + errorName === 'UNEXPECTED_EOF' + ? 'Invalid EOF state' + : this.milo.getErrorDescription(this.parser) + const reason = + errorName === 'UNEXPECTED_EOF' + ? errorDescription + : errorDescription + ? `[ERROR_${errorName}] ${errorDescription}` + : `ERROR_${errorName}` + return new HTTPParserError( + `Response does not match the HTTP/1.1 protocol (${reason})`, + errorName, + data + ) + } -var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + destroy () { + if (this.parser) { + this.milo.destroy(this.parser) + this.parser = null + } -// The actual regexps go on exports.re -var re = exports.re = [] -var safeRe = exports.safeRe = [] -var src = exports.src = [] -var t = exports.tokens = {} -var R = 0 + this.timeout && timers.clearTimeout(this.timeout) + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + this.paused = false + this.responseStarted = false + this.pausedByParser = false + this.pauseStateIsStart = false + this.connection = '' + this.skipBody = false + } -function tok (n) { - t[n] = R++ -} + pauseParser (stateIsStart = false) { + this.milo.pause(this.parser) + this.pausedByParser = true + this.pauseStateIsStart = stateIsStart + } -var LETTERDASHNUMBER = '[a-zA-Z0-9-]' + drainEvents () { + const { socket, client, milo } = this + let cursor = 0 -// Replace some greedy regex tokens to prevent regex dos issues. These regex are -// used internally via the safeRe object since all inputs in this library get -// normalized first to trim and collapse all extra whitespace. The original -// regexes are exported for userland consumption and lower level usage. A -// future breaking change could export the safer regex only with a note that -// all input should have extra whitespace removed. -var safeRegexReplacements = [ - ['\\s', 1], - ['\\d', MAX_LENGTH], - [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], -] + const firstEvent = this.parserEvents[0] + if ( + firstEvent !== milo.EVENT_END && + firstEvent !== milo.EVENT_ERROR && + !this.responseStarted + ) { + this.responseStarted = true -function makeSafeRe (value) { - for (var i = 0; i < safeRegexReplacements.length; i++) { - var token = safeRegexReplacements[i][0] - var max = safeRegexReplacements[i][1] - value = value - .split(token + '*').join(token + '{0,' + max + '}') - .split(token + '+').join(token + '{1,' + max + '}') - } - return value -} + if (socket.destroyed) { + return this.fail(this.milo.ERROR_CALLBACK_ERROR, 'Other side closed') + } -// The following Regular Expressions can be used for tokenizing, -// validating, and parsing SemVer version strings. + const request = client[kQueue][client[kRunningIdx]] + if (!request) { + return this.fail(this.milo.ERROR_CALLBACK_ERROR, 'Missing request') + } -// ## Numeric Identifier -// A single `0`, or a non-zero digit followed by zero or more digits. + request.onResponseStarted() + } -tok('NUMERICIDENTIFIER') -src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' -tok('NUMERICIDENTIFIERLOOSE') -src[t.NUMERICIDENTIFIERLOOSE] = '\\d+' + for (;;) { + const event = this.parserEvents[cursor] + let eventLen = EVENT_RANGE_SIZE + switch (event) { + case milo.EVENT_END: + return + case milo.EVENT_ERROR: + this.errored = true + return + case milo.EVENT_MESSAGE_COMPLETE: { + const { + client, + socket, + statusCode, + upgrade, + trailers, + contentLength, + bytesRead, + shouldKeepAlive + } = this -// ## Non-numeric Identifier -// Zero or more digits, followed by a letter or hyphen, and then zero or -// more letters, digits, or hyphens. + this.responseStarted = false -tok('NONNUMERICIDENTIFIER') -src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*' + if (socket.destroyed && (!statusCode || shouldKeepAlive)) { + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Other side closed') + } -// ## Main Version -// Three dot-separated numeric identifiers. + if (upgrade) { + this.pauseParser() + return + } -tok('MAINVERSION') -src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIER] + ')' + assert(statusCode >= 100) + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + this.statusCode = 0 + this.statusText = '' + this.bytesRead = 0 + this.contentLength = -1 + this.directBodyRemaining = 0 + this.directBodyCompletePending = false + this.headersSuspended = false + this.skipBody = false + this.keepAlive = '' + this.connection = '' + this.trailers = [] + this.trailersSize = 0 + + if (statusCode < 200) { + break + } -tok('MAINVERSIONLOOSE') -src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')' + if ( + request.method !== 'HEAD' && + contentLength !== -1 && + bytesRead !== contentLength + ) { + util.destroy(socket, new ResponseContentLengthMismatchError()) + this.pauseParser() + break + } -// ## Pre-release Version Identifier -// A numeric identifier, or a non-numeric identifier. + request.onResponseEnd(trailers) + + client[kQueue][client[kRunningIdx]++] = null + + if (socket[kWriting]) { + assert(client[kRunning] === 0) + util.destroy(socket, new InformationalError('reset')) + this.pauseParser(true) + } else if (!shouldKeepAlive) { + util.destroy(socket, new InformationalError('reset')) + this.pauseParser(true) + } else if (socket[kReset] && client[kRunning] === 0) { + util.destroy(socket, new InformationalError('reset')) + this.pauseParser(true) + } else if (client[kPipelining] == null || client[kPipelining] === 1) { + setImmediate(client[kResume]) + } else { + client[kResume]() + } -tok('PRERELEASEIDENTIFIER') -src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] + - '|' + src[t.NONNUMERICIDENTIFIER] + ')' + break + } + case milo.EVENT_REASON: { + const at = this.parserEvents.readUInt32LE(cursor + 1) + const len = this.parserEvents.readUInt32LE(cursor + 5) + this.statusText = new FastBuffer( + currentBufferRef.buffer, + currentBufferRef.byteOffset + at, + len + ).toString() + break + } + case milo.EVENT_HEADER_NAME: { + const at = this.parserEvents.readUInt32LE(cursor + 1) + const len = this.parserEvents.readUInt32LE(cursor + 5) + const data = + len > 0 + ? new FastBuffer( + currentBufferRef.buffer, + currentBufferRef.byteOffset + at, + len + ) + : EMPTY_BUF + + this.headers.push(data) + this.headersSize += len + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Headers overflow') + } -tok('PRERELEASEIDENTIFIERLOOSE') -src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] + - '|' + src[t.NONNUMERICIDENTIFIER] + ')' + break + } + case milo.EVENT_HEADER_VALUE: { + const at = this.parserEvents.readUInt32LE(cursor + 1) + const len = this.parserEvents.readUInt32LE(cursor + 5) + const data = + len > 0 + ? new FastBuffer( + currentBufferRef.buffer, + currentBufferRef.byteOffset + at, + len + ) + : EMPTY_BUF + const key = this.headers[this.headers.length - 1] + + this.headers.push(data) + + if (key.length === 10) { + const headerName = util.bufferToLowerCasedHeaderName(key) + if (headerName === 'keep-alive') { + this.keepAlive += (this.keepAlive.length === 0 ? '' : ',') + data.toString() + } else if (headerName === 'connection') { + this.connection += (this.connection.length === 0 ? '' : ',') + data.toString() + } + } -// ## Pre-release Version -// Hyphen, followed by one or more dot-separated pre-release version -// identifiers. + this.headersSize += len + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Headers overflow') + } -tok('PRERELEASE') -src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] + - '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))' + break + } + case milo.EVENT_HEADERS: { + eventLen = EVENT_HEADERS_SIZE -tok('PRERELEASELOOSE') -src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + - '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))' + const statusCode = this.parserEvents.readUInt16LE(cursor + 5) + const shouldKeepAlive = this.parserEvents[cursor + 7] !== 0 + const shouldUpgrade = this.parserEvents[cursor + 8] !== 0 + const hasTrailers = this.parserEvents[cursor + 9] !== 0 + const bodyKind = this.parserEvents[cursor + 10] + const contentLength = + this.parserEvents.readUInt32LE(cursor + 11) + + this.parserEvents.readUInt32LE(cursor + 15) * 0x100000000 -// ## Build Metadata Identifier -// Any combination of digits, letters, or hyphens. + const { socket, client, headers, statusText } = this -tok('BUILDIDENTIFIER') -src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+' + if (socket.destroyed) { + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Other side closed') + } -// ## Build Metadata -// Plus sign, followed by one or more period-separated build metadata -// identifiers. + const request = client[kQueue][client[kRunningIdx]] + if (!request) { + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Missing request') + } -tok('BUILD') -src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] + - '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))' + assert(!this.upgrade) + assert(this.statusCode < 200) -// ## Full Version String -// A main version, followed optionally by a pre-release version and -// build metadata. + if (statusCode === 100) { + util.destroy( + socket, + new SocketError('bad response', util.getSocketInfo(socket)) + ) + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Bad response') + } -// Note that the only major, minor, patch, and pre-release sections of -// the version string are capturing groups. The build metadata is not a -// capturing group, because it should not ever be used in version -// comparison. + if (shouldUpgrade && !request.upgrade) { + util.destroy( + socket, + new SocketError('bad upgrade', util.getSocketInfo(socket)) + ) + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Bad upgrade') + } -tok('FULL') -tok('FULLPLAIN') -src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] + - src[t.PRERELEASE] + '?' + - src[t.BUILD] + '?' + assert(this.timeoutType === TIMEOUT_HEADERS) + + this.statusCode = statusCode + this.shouldKeepAlive = + shouldKeepAlive || + (request.method === 'HEAD' && + !socket[kReset] && + /(?:^|,)[\t ]*keep-alive[\t ]*(?:,|$)/i.test(this.connection) && + !/(?:^|,)[\t ]*close[\t ]*(?:,|$)/i.test(this.connection)) + this.contentLength = + bodyKind === BODY_KIND_CONTENT_LENGTH ? contentLength : -1 + + if (this.statusCode >= 200) { + const bodyTimeout = + request.bodyTimeout != null + ? request.bodyTimeout + : client[kBodyTimeout] + this.setTimeout(bodyTimeout, TIMEOUT_BODY) + } else if (this.timeout?.refresh) { + this.timeout.refresh() + } -src[t.FULL] = '^' + src[t.FULLPLAIN] + '$' + if (request.method === 'CONNECT') { + assert(client[kRunning] === 1) + milo.setIsConnect(this.parser, true) + this.upgrade = true + return + } -// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. -// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty -// common in the npm registry. -tok('LOOSEPLAIN') -src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] + - src[t.PRERELEASELOOSE] + '?' + - src[t.BUILD] + '?' + if (shouldUpgrade) { + assert(client[kRunning] === 1) + this.upgrade = true + this.pauseParser() + return + } -tok('LOOSE') -src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$' + this.headers = [] + this.headersSize = 0 + + if (this.shouldKeepAlive && client[kPipelining]) { + const keepAliveTimeout = this.keepAlive + ? util.parseKeepAliveTimeout(this.keepAlive) + : null + + if (keepAliveTimeout != null) { + const timeout = Math.min( + keepAliveTimeout - client[kKeepAliveTimeoutThreshold], + client[kKeepAliveMaxTimeout] + ) + if (timeout <= 0) { + socket[kReset] = true + } else { + client[kKeepAliveTimeoutValue] = timeout + } + } else { + client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] + } + } else { + socket[kReset] = true + } -tok('GTLT') -src[t.GTLT] = '((?:<|>)?=?)' + const pause = + request.onResponseStart( + statusCode, + headers, + this.resume, + statusText + ) === false -// Something like "2.*" or "1.2.x". -// Note that "x.x" is a valid xRange identifer, meaning "any version" -// Only the first item is strictly required. -tok('XRANGEIDENTIFIERLOOSE') -src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' -tok('XRANGEIDENTIFIER') -src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*' - -tok('XRANGEPLAIN') -src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + - '(?:' + src[t.PRERELEASE] + ')?' + - src[t.BUILD] + '?' + - ')?)?' - -tok('XRANGEPLAINLOOSE') -src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + - '(?:' + src[t.PRERELEASELOOSE] + ')?' + - src[t.BUILD] + '?' + - ')?)?' - -tok('XRANGE') -src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$' -tok('XRANGELOOSE') -src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$' + if (request.aborted) { + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Request aborted') + } -// Coercion. -// Extract anything that could conceivably be a part of a valid semver -tok('COERCE') -src[t.COERCE] = '(^|[^\\d])' + - '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:$|[^\\d])' -tok('COERCERTL') -re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') -safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g') + if (request.method === 'HEAD' || statusCode < 200) { + this.setShouldSkipBody(true) + } -// Tilde ranges. -// Meaning is "reasonably at or greater than" -tok('LONETILDE') -src[t.LONETILDE] = '(?:~>?)' + this.headersSuspended = true + if ( + !pause && + request.method !== 'HEAD' && + statusCode >= 200 && + statusCode !== 204 && + statusCode !== 205 && + statusCode !== 304 && + bodyKind === BODY_KIND_CONTENT_LENGTH && + contentLength > 0 && + !hasTrailers + ) { + this.directBodyRemaining = contentLength + } -tok('TILDETRIM') -src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' -re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') -safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g') -var tildeTrimReplace = '$1~' + if (socket[kBlocking]) { + socket[kBlocking] = false + client[kResume]() + } -tok('TILDE') -src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$' -tok('TILDELOOSE') -src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$' + if (pause) { + this.pauseParser() + this[kPausedByHandler] = true + } else if ( + request.method === 'HEAD' || + statusCode < 200 || + statusCode === 204 || + statusCode === 205 || + statusCode === 304 || + (bodyKind === BODY_KIND_CONTENT_LENGTH && contentLength === 0) + ) { + this.directBodyCompletePending = true + } -// Caret ranges. -// Meaning is "at least and backwards compatible with" -tok('LONECARET') -src[t.LONECARET] = '(?:\\^)' + break + } + case milo.EVENT_DATA: { + const at = this.parserEvents.readUInt32LE(cursor + 1) + const len = this.parserEvents.readUInt32LE(cursor + 5) + const { client, socket, statusCode, maxResponseSize } = this -tok('CARETTRIM') -src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' -re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') -safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g') -var caretTrimReplace = '$1^' + if (socket.destroyed) { + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Other side closed') + } -tok('CARET') -src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$' -tok('CARETLOOSE') -src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$' + const request = client[kQueue][client[kRunningIdx]] + assert(request) + assert(this.timeoutType === TIMEOUT_BODY) -// A simple gt/lt/eq thing, or just "" to indicate "any version" -tok('COMPARATORLOOSE') -src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$' -tok('COMPARATOR') -src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$' + if (this.timeout?.refresh) { + this.timeout.refresh() + } -// An expression to strip any whitespace between the gtlt and the thing -// it modifies, so that `> 1.2.3` ==> `>1.2.3` -tok('COMPARATORTRIM') -src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + - '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')' + assert(statusCode >= 200) -// this one has to use the /g flag -re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') -safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g') -var comparatorTrimReplace = '$1$2$3' + if (maxResponseSize > -1 && this.bytesRead + len > maxResponseSize) { + util.destroy(socket, new ResponseExceededMaxSizeError()) + return this.fail( + milo.ERROR_CALLBACK_ERROR, + 'Response size exceeded' + ) + } -// Something like `1.2.3 - 1.2.4` -// Note that these all use the loose form, because they'll be -// checked against either the strict or loose comparator form -// later. -tok('HYPHENRANGE') -src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' + - '\\s+-\\s+' + - '(' + src[t.XRANGEPLAIN] + ')' + - '\\s*$' - -tok('HYPHENRANGELOOSE') -src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' + - '\\s+-\\s+' + - '(' + src[t.XRANGEPLAINLOOSE] + ')' + - '\\s*$' + this.bytesRead += len -// Star ranges basically just allow anything at all. -tok('STAR') -src[t.STAR] = '(<|>)?=?\\s*\\*' + const buffer = currentBufferRef + if ( + request.onResponseData( + new FastBuffer(buffer.buffer, buffer.byteOffset + at, len) + ) === false + ) { + this.pauseParser() + this[kPausedByHandler] = true + } -// Compile to actual regexp objects. -// All are flag-free, unless they were created above with a flag. -for (var i = 0; i < R; i++) { - debug(i, src[i]) - if (!re[i]) { - re[i] = new RegExp(src[i]) + break + } + case milo.EVENT_TRAILER_NAME: { + const at = this.parserEvents.readUInt32LE(cursor + 1) + const len = this.parserEvents.readUInt32LE(cursor + 5) + const data = + len > 0 + ? new FastBuffer( + currentBufferRef.buffer, + currentBufferRef.byteOffset + at, + len + ) + : EMPTY_BUF + + this.trailers.push(data) + + this.trailersSize += len + if (this.trailersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Headers overflow') + } - // Replace all greedy whitespace to prevent regex dos issues. These regex are - // used internally via the safeRe object since all inputs in this library get - // normalized first to trim and collapse all extra whitespace. The original - // regexes are exported for userland consumption and lower level usage. A - // future breaking change could export the safer regex only with a note that - // all input should have extra whitespace removed. - safeRe[i] = new RegExp(makeSafeRe(src[i])) - } -} + break + } + case milo.EVENT_TRAILER_VALUE: { + const at = this.parserEvents.readUInt32LE(cursor + 1) + const len = this.parserEvents.readUInt32LE(cursor + 5) + const data = + len > 0 + ? new FastBuffer( + currentBufferRef.buffer, + currentBufferRef.byteOffset + at, + len + ) + : EMPTY_BUF + + this.trailers.push(data) + + this.trailersSize += len + if (this.trailersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + return this.fail(milo.ERROR_CALLBACK_ERROR, 'Headers overflow') + } + + break + } + default: + return + } -exports.parse = parse -function parse (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false + cursor += eventLen } } - if (version instanceof SemVer) { - return version + fail (code, message) { + this.milo.fail(this.parser, code, message) + this.errored = true } - if (typeof version !== 'string') { - return null - } + onUpgrade (head) { + const { upgrade, client, socket, headers, statusCode } = this - if (version.length > MAX_LENGTH) { - return null - } + assert(upgrade) + assert(client[kSocket] === socket) + assert(!socket.destroyed) + assert(!this.paused) - var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL] - if (!r.test(version)) { - return null - } + const request = client[kQueue][client[kRunningIdx]] + assert(request) + assert(request.upgrade || request.method === 'CONNECT') - try { - return new SemVer(version, options) - } catch (er) { - return null - } -} + this.statusCode = 0 + this.statusText = '' + this.shouldKeepAlive = false + this.headers = [] + this.headersSize = 0 -exports.valid = valid -function valid (version, options) { - var v = parse(version, options) - return v ? v.version : null -} + socket.unshift(head) + socket[kParser].destroy() + socket[kParser] = null + socket[kClient] = null + socket[kError] = null -exports.clean = clean -function clean (version, options) { - var s = parse(version.trim().replace(/^[=v]+/, ''), options) - return s ? s.version : null + removeAllListeners(socket) + + client[kSocket] = null + client[kHTTPContext] = null + client[kQueue][client[kRunningIdx]++] = null + client.emit( + 'disconnect', + client[kUrl], + [client], + new InformationalError('upgrade') + ) + + try { + request.onRequestUpgrade(statusCode, headers, socket) + } catch (err) { + util.destroy(socket, err) + } + + client[kResume]() + } } -exports.SemVer = SemVer +function setMiloEnabled (value) { + miloEnabled = value +} -function SemVer (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - if (version instanceof SemVer) { - if (version.loose === options.loose) { - return version - } else { - version = version.version - } - } else if (typeof version !== 'string') { - throw new TypeError('Invalid Version: ' + version) - } +function getMiloEnabled () { + return miloEnabled +} - if (version.length > MAX_LENGTH) { - throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') - } +module.exports = { H1Parser, getMiloEnabled, setMiloEnabled } - if (!(this instanceof SemVer)) { - return new SemVer(version, options) - } - debug('SemVer', version, options) - this.options = options - this.loose = !!options.loose +/***/ }), - var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]) +/***/ 2128: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!m) { - throw new TypeError('Invalid Version: ' + version) - } +"use strict"; - this.raw = version - // these are actually numbers - this.major = +m[1] - this.minor = +m[2] - this.patch = +m[3] +const { PoolStats } = __nccwpck_require__(6854) +const DispatcherBase = __nccwpck_require__(1841) +const FixedQueue = __nccwpck_require__(4660) +const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = __nccwpck_require__(6443) - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError('Invalid major version') - } +const kClients = Symbol('clients') +const kNeedDrain = Symbol('needDrain') +const kQueue = Symbol('queue') +const kClosedResolve = Symbol('closed resolve') +const kOnDrain = Symbol('onDrain') +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kOnClientBusy = Symbol('on client busy') +const kOnClientDrain = Symbol('on client drain') +const kDrainQueue = Symbol('drain queue') +const kGetDispatcher = Symbol('get dispatcher') +const kHasDispatcher = Symbol('has dispatcher') +const kAddClient = Symbol('add client') +const kRemoveClient = Symbol('remove client') +const kRetireClient = Symbol('retire client') +const kRetiring = Symbol('retiring clients') - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError('Invalid minor version') +// Closes every live client, including clients that have been +// taken out of rotation but are still finishing their own +// requests. +function closeClients (pool) { + const closeAll = [] + for (let i = 0; i < pool[kClients].length; i++) { + const client = pool[kClients][i] + if (!client.destroyed) { + closeAll.push(client.close()) + } } - - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError('Invalid patch version') + for (const closed of pool[kRetiring].values()) { + closeAll.push(closed) } + return Promise.all(closeAll) +} - // numberify any prerelease numeric ids - if (!m[4]) { - this.prerelease = [] - } else { - this.prerelease = m[4].split('.').map(function (id) { - if (/^[0-9]+$/.test(id)) { - var num = +id - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num - } - } - return id - }) - } +class PoolBase extends DispatcherBase { + [kQueue] = new FixedQueue(); - this.build = m[5] ? m[5].split('.') : [] - this.format() -} + [kQueued] = 0; -SemVer.prototype.format = function () { - this.version = this.major + '.' + this.minor + '.' + this.patch - if (this.prerelease.length) { - this.version += '-' + this.prerelease.join('.') - } - return this.version -} + [kClients] = []; -SemVer.prototype.toString = function () { - return this.version -} + // Clients removed from kClients that have not finished closing, + // mapped to a promise that settles once they have. + [kRetiring] = new Map(); -SemVer.prototype.compare = function (other) { - debug('SemVer.compare', this.version, this.options, other) - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + [kNeedDrain] = false; - return this.compareMain(other) || this.comparePre(other) -} + [kOnDrain] (client, origin, targets) { + if (client.closed || client.destroyed) { + return + } -SemVer.prototype.compareMain = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + const queue = this[kQueue] + let needDrain = false - return compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) -} + this[kOnClientDrain](client) -SemVer.prototype.comparePre = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + while (!needDrain) { + const item = queue.shift() + if (!item) { + break + } + this[kQueued]-- + needDrain = !client.dispatch(item.opts, item.handler) + } - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) { - return -1 - } else if (!this.prerelease.length && other.prerelease.length) { - return 1 - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0 - } + client[kNeedDrain] = needDrain + if (needDrain) { + this[kOnClientBusy](client) - var i = 0 - do { - var a = this.prerelease[i] - var b = other.prerelease[i] - debug('prerelease compare', i, a, b) - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) + // This client is full but requests are still queued, e.g. an h2 + // client that has just released everything queued while ALPN was + // negotiated and hit maxConcurrentStreams. Hand the rest to other + // clients, creating new ones up to the connection limit, instead of + // leaving them for this client to drain one batch at a time. + if (!queue.isEmpty()) { + return this[kDrainQueue](origin, targets) + } } - } while (++i) -} -SemVer.prototype.compareBuild = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + if (!needDrain && this[kNeedDrain]) { + this[kNeedDrain] = false + this.emit('drain', origin, [this, ...targets]) + } - var i = 0 - do { - var a = this.build[i] - var b = other.build[i] - debug('prerelease compare', i, a, b) - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) + if (this[kClosedResolve] && queue.isEmpty()) { + return closeClients(this).then(this[kClosedResolve]) } - } while (++i) -} + } -// preminor will bump the version up to the next minor release, and immediately -// down to pre-release. premajor and prepatch work the same way. -SemVer.prototype.inc = function (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0 - this.patch = 0 - this.minor = 0 - this.major++ - this.inc('pre', identifier) - break - case 'preminor': - this.prerelease.length = 0 - this.patch = 0 - this.minor++ - this.inc('pre', identifier) - break - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0 - this.inc('patch', identifier) - this.inc('pre', identifier) - break - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier) - } - this.inc('pre', identifier) - break + [kOnClientBusy] () {} - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if (this.minor !== 0 || - this.patch !== 0 || - this.prerelease.length === 0) { - this.major++ - } - this.minor = 0 - this.patch = 0 - this.prerelease = [] - break - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++ - } - this.patch = 0 - this.prerelease = [] - break - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) { - this.patch++ - } - this.prerelease = [] - break - // This probably shouldn't be used publicly. - // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0] - } else { - var i = this.prerelease.length - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++ - i = -2 - } - } - if (i === -1) { - // didn't increment anything - this.prerelease.push(0) - } - } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0] - } - } else { - this.prerelease = [identifier, 0] - } - } - break + [kOnClientDrain] () {} - default: - throw new Error('invalid increment argument: ' + release) - } - this.format() - this.raw = this.version - return this -} + [kDrainQueue] (origin, targets) { + const queue = this[kQueue] + let hasDispatcher = true -exports.inc = inc -function inc (version, release, loose, identifier) { - if (typeof (loose) === 'string') { - identifier = loose - loose = undefined - } + while (!queue.isEmpty()) { + const dispatcher = this[kGetDispatcher]() + if (!dispatcher) { + hasDispatcher = false + break + } - try { - return new SemVer(version, loose).inc(release, identifier).version - } catch (er) { - return null - } -} + const item = queue.shift() + this[kQueued]-- -exports.diff = diff -function diff (version1, version2) { - if (eq(version1, version2)) { - return null - } else { - var v1 = parse(version1) - var v2 = parse(version2) - var prefix = '' - if (v1.prerelease.length || v2.prerelease.length) { - prefix = 'pre' - var defaultResult = 'prerelease' - } - for (var key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key + if (!dispatcher.dispatch(item.opts, item.handler)) { + dispatcher[kNeedDrain] = true + this[kOnClientBusy](dispatcher) + hasDispatcher = this[kHasDispatcher]() + if (!hasDispatcher) { + break } } } - return defaultResult // may be undefined - } -} -exports.compareIdentifiers = compareIdentifiers - -var numeric = /^[0-9]+$/ -function compareIdentifiers (a, b) { - var anum = numeric.test(a) - var bnum = numeric.test(b) + if (hasDispatcher && this[kNeedDrain]) { + this[kNeedDrain] = false + this.emit('drain', origin, [this, ...targets]) + } - if (anum && bnum) { - a = +a - b = +b + if (this[kClosedResolve] && queue.isEmpty()) { + return closeClients(this).then(this[kClosedResolve]) + } } - return a === b ? 0 - : (anum && !bnum) ? -1 - : (bnum && !anum) ? 1 - : a < b ? -1 - : 1 -} - -exports.rcompareIdentifiers = rcompareIdentifiers -function rcompareIdentifiers (a, b) { - return compareIdentifiers(b, a) -} - -exports.major = major -function major (a, loose) { - return new SemVer(a, loose).major -} - -exports.minor = minor -function minor (a, loose) { - return new SemVer(a, loose).minor -} + [kOnConnect] = (origin, targets) => { + this.emit('connect', origin, [this, ...targets]) + }; -exports.patch = patch -function patch (a, loose) { - return new SemVer(a, loose).patch -} + [kOnDisconnect] = (origin, targets, err) => { + this.emit('disconnect', origin, [this, ...targets], err) + }; -exports.compare = compare -function compare (a, b, loose) { - return new SemVer(a, loose).compare(new SemVer(b, loose)) -} + [kOnConnectionError] = (origin, targets, err) => { + this.emit('connectionError', origin, [this, ...targets], err) + } -exports.compareLoose = compareLoose -function compareLoose (a, b) { - return compare(a, b, true) -} + get [kBusy] () { + return this[kNeedDrain] + } -exports.compareBuild = compareBuild -function compareBuild (a, b, loose) { - var versionA = new SemVer(a, loose) - var versionB = new SemVer(b, loose) - return versionA.compare(versionB) || versionA.compareBuild(versionB) -} + get [kConnected] () { + let ret = 0 + for (const { [kConnected]: connected } of this[kClients]) { + ret += connected + } + return ret + } -exports.rcompare = rcompare -function rcompare (a, b, loose) { - return compare(b, a, loose) -} + get [kFree] () { + let ret = 0 + for (const { [kConnected]: connected, [kNeedDrain]: needDrain } of this[kClients]) { + ret += connected && !needDrain + } + return ret + } -exports.sort = sort -function sort (list, loose) { - return list.sort(function (a, b) { - return exports.compareBuild(a, b, loose) - }) -} + get [kPending] () { + let ret = this[kQueued] + for (const { [kPending]: pending } of this[kClients]) { + ret += pending + } + return ret + } -exports.rsort = rsort -function rsort (list, loose) { - return list.sort(function (a, b) { - return exports.compareBuild(b, a, loose) - }) -} + get [kRunning] () { + let ret = 0 + for (const { [kRunning]: running } of this[kClients]) { + ret += running + } + return ret + } -exports.gt = gt -function gt (a, b, loose) { - return compare(a, b, loose) > 0 -} + get [kSize] () { + let ret = this[kQueued] + for (const { [kSize]: size } of this[kClients]) { + ret += size + } + return ret + } -exports.lt = lt -function lt (a, b, loose) { - return compare(a, b, loose) < 0 -} + get stats () { + return new PoolStats(this) + } -exports.eq = eq -function eq (a, b, loose) { - return compare(a, b, loose) === 0 -} + [kClose] () { + if (this[kQueue].isEmpty()) { + return closeClients(this) + } else { + return new Promise((resolve) => { + this[kClosedResolve] = resolve + }) + } + } -exports.neq = neq -function neq (a, b, loose) { - return compare(a, b, loose) !== 0 -} + [kDestroy] (err) { + while (true) { + const item = this[kQueue].shift() + if (!item) { + break + } + item.handler.onResponseError(null, err) + } -exports.gte = gte -function gte (a, b, loose) { - return compare(a, b, loose) >= 0 -} + const destroyAll = new Array(this[kClients].length) + for (let i = 0; i < this[kClients].length; i++) { + destroyAll[i] = this[kClients][i].destroy(err) + } + for (const client of this[kRetiring].keys()) { + destroyAll.push(client.destroy(err)) + } + return Promise.all(destroyAll) + } -exports.lte = lte -function lte (a, b, loose) { - return compare(a, b, loose) <= 0 -} + [kDispatch] (opts, handler) { + const dispatcher = this[kGetDispatcher]() -exports.cmp = cmp -function cmp (a, op, b, loose) { - switch (op) { - case '===': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a === b + if (!dispatcher) { + this[kNeedDrain] = true + this[kQueue].push({ opts, handler }) + this[kQueued]++ + } else if (!dispatcher.dispatch(opts, handler)) { + dispatcher[kNeedDrain] = true + this[kOnClientBusy](dispatcher) + this[kNeedDrain] = !this[kHasDispatcher]() + } - case '!==': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a !== b + return !this[kNeedDrain] + } - case '': - case '=': - case '==': - return eq(a, b, loose) + [kHasDispatcher] () { + for (let i = 0; i < this[kClients].length; i++) { + const dispatcher = this[kClients][i] - case '!=': - return neq(a, b, loose) + if ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + ) { + return true + } + } - case '>': - return gt(a, b, loose) + return false + } - case '>=': - return gte(a, b, loose) + [kAddClient] (client) { + client + .on('drain', this[kOnDrain].bind(this, client)) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) - case '<': - return lt(a, b, loose) + this[kClients].push(client) - case '<=': - return lte(a, b, loose) + if (this[kNeedDrain]) { + queueMicrotask(() => { + if (this[kNeedDrain] && !client[kNeedDrain]) { + this[kOnDrain](client, client[kUrl], [client, this]) + } + }) + } - default: - throw new TypeError('Invalid operator: ' + op) + return this } -} -exports.Comparator = Comparator -function Comparator (comp, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false + // Takes a client out of rotation. A closed client no longer takes requests + // from the pool queue (see kOnDrain), but it finishes the requests it + // already has. Until it has, pool.close() waits for it and pool.destroy() + // destroys it. + [kRetireClient] (client) { + const idx = this[kClients].indexOf(client) + if (idx !== -1) { + this[kClients].splice(idx, 1) } - } - if (comp instanceof Comparator) { - if (comp.loose === !!options.loose) { - return comp - } else { - comp = comp.value + if (client.destroyed || this[kRetiring].has(client)) { + return } - } - if (!(this instanceof Comparator)) { - return new Comparator(comp, options) + // Use the callback form: custom dispatchers from `factory` are not + // required to return a promise, and may call back synchronously. + let done = false + let resolveClosed + const closed = new Promise((resolve) => { resolveClosed = resolve }) + this[kRetiring].set(client, closed) + client.close(() => { + if (!done) { + done = true + this[kRetiring].delete(client) + resolveClosed() + } + }) } - comp = comp.trim().split(/\s+/).join(' ') - debug('comparator', comp, options) - this.options = options - this.loose = !!options.loose - this.parse(comp) + [kRemoveClient] (client) { + this[kRetireClient](client) - if (this.semver === ANY) { - this.value = '' - } else { - this.value = this.operator + this.semver.version + this[kNeedDrain] = !this[kClients].some(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )) } +} - debug('comp', this) +module.exports = { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kRetireClient, + kDrainQueue, + kOnClientBusy, + kOnClientDrain, + kGetDispatcher, + kHasDispatcher } -var ANY = {} -Comparator.prototype.parse = function (comp) { - var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] - var m = comp.match(r) - if (!m) { - throw new TypeError('Invalid comparator: ' + comp) - } +/***/ }), - this.operator = m[1] !== undefined ? m[1] : '' - if (this.operator === '=') { - this.operator = '' - } +/***/ 628: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // if it literally is just '>' or '' then allow anything. - if (!m[2]) { - this.semver = ANY - } else { - this.semver = new SemVer(m[2], this.options.loose) - } -} +"use strict"; -Comparator.prototype.toString = function () { - return this.value -} -Comparator.prototype.test = function (version) { - debug('Comparator.test', version, this.options.loose) +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kDrainQueue, + kOnClientBusy, + kOnClientDrain, + kGetDispatcher, + kHasDispatcher, + kRemoveClient, + kRetireClient +} = __nccwpck_require__(2128) +const Client = __nccwpck_require__(3701) +const { + InvalidArgumentError +} = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) +const { kConnecting, kHTTPContext, kUrl, kQueued } = __nccwpck_require__(6443) +const buildConnector = __nccwpck_require__(9136) - if (this.semver === ANY || version === ANY) { - return true - } +const kOptions = Symbol('options') +const kConnections = Symbol('connections') +const kFactory = Symbol('factory') +const kProtocol = Symbol('protocol') +const kProtocolProbe = Symbol('protocol probe') - if (typeof version === 'string') { - try { - version = new SemVer(version, this.options) - } catch (er) { - return false - } - } +function defaultFactory (origin, opts) { + return new Client(origin, opts) +} - return cmp(version, this.operator, this.semver, this.options) +function shouldCreateProtocolProbe (pool, dispatcher) { + return dispatcher instanceof Client && + pool[kProtocol] !== 'h1' && + (pool[kOptions].useH2c === true || (pool[kUrl].protocol === 'https:' && pool[kOptions].allowH2 !== false)) } -Comparator.prototype.intersects = function (comp, options) { - if (!(comp instanceof Comparator)) { - throw new TypeError('a Comparator is required') - } +function createClient (pool) { + const dispatcher = pool[kFactory](pool[kUrl], pool[kOptions]) - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } + // HTTPS does not reveal whether the peer selected h1 or h2 until ALPN + // completes. While h2 is still possible, let one Client probe the protocol + // and keep later requests in the Pool queue instead of opening one TLS + // connection per request. A confirmed h1 connection disables this gate and + // restores the usual Pool fan-out. + if (shouldCreateProtocolProbe(pool, dispatcher)) { + pool[kProtocolProbe] = dispatcher } - var rangeTmp + pool[kAddClient](dispatcher) + return dispatcher +} - if (this.operator === '') { - if (this.value === '') { - return true +class Pool extends PoolBase { + constructor (origin, { + connections, + factory = defaultFactory, + connect, + connectTimeout, + tls, + maxCachedSessions, + socketPath, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + allowH2, + useH2c, + clientTtl, + ...options + } = {}) { + if (connections != null && (!Number.isFinite(connections) || connections < 0)) { + throw new InvalidArgumentError('invalid connections') } - rangeTmp = new Range(comp.value, options) - return satisfies(this.value, rangeTmp, options) - } else if (comp.operator === '') { - if (comp.value === '') { - return true + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') } - rangeTmp = new Range(this.value, options) - return satisfies(comp.semver, rangeTmp, options) - } - - var sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - var sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - var sameSemVer = this.semver.version === comp.semver.version - var differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - var oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - ((this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<')) - var oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - ((this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>')) - - return sameDirectionIncreasing || sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || oppositeDirectionsGreaterThan -} - -exports.Range = Range -function Range (range, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - - if (range instanceof Range) { - if (range.loose === !!options.loose && - range.includePrerelease === !!options.includePrerelease) { - return range - } else { - return new Range(range.raw, options) + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') } - } - if (range instanceof Comparator) { - return new Range(range.value, options) - } + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + useH2c, + socketPath, + timeout: connectTimeout, + ...(typeof autoSelectFamily === 'boolean' ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) + } - if (!(this instanceof Range)) { - return new Range(range, options) - } + super(options) - this.options = options - this.loose = !!options.loose - this.includePrerelease = !!options.includePrerelease + this[kConnections] = connections || null + this[kUrl] = util.parseOrigin(origin) + this[kOptions] = { ...util.deepClone(options), connect, allowH2, useH2c, clientTtl, socketPath } + this[kFactory] = factory + this[kProtocol] = null + this[kProtocolProbe] = null - // First reduce all whitespace as much as possible so we do not have to rely - // on potentially slow regexes like \s*. This is then stored and used for - // future error messages as well. - this.raw = range - .trim() - .split(/\s+/) - .join(' ') + this.on('connect', (origin, targets) => { + if (clientTtl != null && clientTtl > 0) { + for (const target of targets) { + Object.assign(target, { ttl: Date.now() }) + } + } - // First, split based on boolean or || - this.set = this.raw.split('||').map(function (range) { - return this.parseRange(range.trim()) - }, this).filter(function (c) { - // throw out any that are not relevant for whatever reason - return c.length - }) + const client = targets[targets.length - 1] + if (client instanceof Client) { + this[kProtocol] = client[kHTTPContext]?.version + } - if (!this.set.length) { - throw new TypeError('Invalid SemVer Range: ' + this.raw) - } + if (client === this[kProtocolProbe]) { + // An h2 Client's drain event releases the requests accumulated during + // negotiation onto that Client. If ALPN selected h1, release the probe + // immediately and restore normal Pool fan-out instead. + if (this[kProtocol] !== 'h2') { + this[kProtocolProbe] = null + this[kDrainQueue](origin, targets.slice(1)) + } + } + }) - this.format() -} + this.on('disconnect', (origin, targets) => { + if (targets.includes(this[kProtocolProbe])) { + this[kProtocolProbe] = null + this[kDrainQueue](origin, targets.slice(1)) + } + }) -Range.prototype.format = function () { - this.range = this.set.map(function (comps) { - return comps.join(' ').trim() - }).join('||').trim() - return this.range -} + this.on('connectionError', (origin, targets) => { + let resumeQueued = false -Range.prototype.toString = function () { - return this.range -} + // If a connection error occurs, we remove the client from the pool, + // and emit a connectionError event. They will not be re-used. + // Fixes https://github.com/nodejs/undici/issues/3895 + for (const target of targets) { + if (target === this[kProtocolProbe]) { + this[kProtocolProbe] = null + resumeQueued = true + } -Range.prototype.parseRange = function (range) { - var loose = this.options.loose - // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE] - range = range.replace(hr, hyphenReplace) - debug('hyphen replace', range) - // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace) - debug('comparator trim', range, safeRe[t.COMPARATORTRIM]) + // Retire (close) the client rather than only dropping it from + // kClients: otherwise its drain listener keeps pulling requests from + // the pool queue onto a client that pool.destroy() can't reach. + if (this[kClients].includes(target)) { + this[kRetireClient](target) + } + } - // `~ 1.2.3` => `~1.2.3` - range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace) + // The retired client no longer drains the pool queue, so hand any + // queued requests to another (possibly new) client. + if (resumeQueued || this[kQueued] > 0) { + this[kDrainQueue](origin, targets.slice(1)) + } + }) + } - // `^ 1.2.3` => `^1.2.3` - range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace) + [kOnClientBusy] (client) { + if ( + this[kProtocolProbe] === null && + client[kConnecting] && + shouldCreateProtocolProbe(this, client) + ) { + this[kProtocolProbe] = client + } + } - // normalize spaces - range = range.split(/\s+/).join(' ') + [kOnClientDrain] (client) { + if (client === this[kProtocolProbe]) { + this[kProtocolProbe] = null + } + } - // At this point, the range is completely trimmed and - // ready to be split into comparators. + [kGetDispatcher] () { + const clientTtlOption = this[kOptions].clientTtl + for (let i = 0; i < this[kClients].length; i++) { + const client = this[kClients][i] - var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] - var set = range.split(' ').map(function (comp) { - return parseComparator(comp, this.options) - }, this).join(' ').split(/\s+/) - if (this.options.loose) { - // in loose mode, throw out any that are not valid comparators - set = set.filter(function (comp) { - return !!comp.match(compRe) - }) - } - set = set.map(function (comp) { - return new Comparator(comp, this.options) - }, this) + // check ttl of client and if it's stale, remove it from the pool + if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && ((Date.now() - client.ttl) > clientTtlOption)) { + this[kRemoveClient](client) + i-- + } else if (!client[kNeedDrain]) { + return client + } + } - return set -} + if (this[kProtocolProbe] !== null) { + return + } -Range.prototype.intersects = function (range, options) { - if (!(range instanceof Range)) { - throw new TypeError('a Range is required') + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + return createClient(this) + } } - return this.set.some(function (thisComparators) { - return ( - isSatisfiable(thisComparators, options) && - range.set.some(function (rangeComparators) { - return ( - isSatisfiable(rangeComparators, options) && - thisComparators.every(function (thisComparator) { - return rangeComparators.every(function (rangeComparator) { - return thisComparator.intersects(rangeComparator, options) - }) - }) - ) - }) - ) - }) -} + [kHasDispatcher] () { + const clientTtlOption = this[kOptions].clientTtl + for (let i = 0; i < this[kClients].length; i++) { + const client = this[kClients][i] -// take a set of comparators and determine whether there -// exists a version which can satisfy it -function isSatisfiable (comparators, options) { - var result = true - var remainingComparators = comparators.slice() - var testComparator = remainingComparators.pop() + if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && ((Date.now() - client.ttl) > clientTtlOption)) { + this[kRemoveClient](client) + i-- + } else if (!client[kNeedDrain]) { + return true + } + } - while (result && remainingComparators.length) { - result = remainingComparators.every(function (otherComparator) { - return testComparator.intersects(otherComparator, options) - }) + if (this[kProtocolProbe] !== null) { + return false + } - testComparator = remainingComparators.pop() - } + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + createClient(this) + return true + } - return result + return false + } } -// Mostly just for testing and legacy API reasons -exports.toComparators = toComparators -function toComparators (range, options) { - return new Range(range, options).set.map(function (comp) { - return comp.map(function (c) { - return c.value - }).join(' ').trim().split(' ') - }) -} +module.exports = Pool -// comprised of xranges, tildes, stars, and gtlt's at this point. -// already replaced the hyphen ranges -// turn into a set of JUST comparators. -function parseComparator (comp, options) { - debug('comp', comp, options) - comp = replaceCarets(comp, options) - debug('caret', comp) - comp = replaceTildes(comp, options) - debug('tildes', comp) - comp = replaceXRanges(comp, options) - debug('xrange', comp) - comp = replaceStars(comp, options) - debug('stars', comp) - return comp -} -function isX (id) { - return !id || id.toLowerCase() === 'x' || id === '*' -} +/***/ }), -// ~, ~> --> * (any, kinda silly) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 -function replaceTildes (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceTilde(comp, options) - }).join(' ') -} - -function replaceTilde (comp, options) { - var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE] - return comp.replace(r, function (_, M, m, p, pr) { - debug('tilde', comp, _, M, m, p, pr) - var ret +/***/ 6672: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - // ~1.2 == >=1.2.0 <1.3.0 - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else if (pr) { - debug('replaceTilde pr', pr) - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } else { - // ~1.2.3 == >=1.2.3 <1.3.0 - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } +"use strict"; - debug('tilde return', ret) - return ret - }) -} -// ^ --> * (any, kinda silly) -// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 -// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 -// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 -// ^1.2.3 --> >=1.2.3 <2.0.0 -// ^1.2.0 --> >=1.2.0 <2.0.0 -function replaceCarets (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceCaret(comp, options) - }).join(' ') -} - -function replaceCaret (comp, options) { - debug('caret', comp, options) - var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET] - return comp.replace(r, function (_, M, m, p, pr) { - debug('caret', comp, _, M, m, p, pr) - var ret +const { kProxy, kClose, kDestroy, kDispatch } = __nccwpck_require__(6443) +const Agent = __nccwpck_require__(7405) +const Pool = __nccwpck_require__(628) +const DispatcherBase = __nccwpck_require__(1841) +const { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError, ProxyConnectionError } = __nccwpck_require__(8707) +const buildConnector = __nccwpck_require__(9136) +const Client = __nccwpck_require__(3701) +const { channels } = __nccwpck_require__(2414) +const Socks5ProxyAgent = __nccwpck_require__(7223) +const { hasSafeIterator } = __nccwpck_require__(3440) - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - if (M === '0') { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else { - ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' - } - } else if (pr) { - debug('replaceCaret pr', pr) - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + (+M + 1) + '.0.0' - } - } else { - debug('no pr') - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + (+M + 1) + '.0.0' - } - } +const kAgent = Symbol('proxy agent') +const kClient = Symbol('proxy client') +const kProxyHeaders = Symbol('proxy headers') +const kRequestTls = Symbol('request tls settings') +const kProxyTls = Symbol('proxy tls settings') +const kConnectEndpoint = Symbol('connect endpoint function') +const kConnectEndpointHTTP1 = Symbol('connect endpoint function (http/1.1 only)') +const kTunnelProxy = Symbol('tunnel proxy') +const proxyAuthorization = 'proxy-authorization' - debug('caret return', ret) - return ret - }) +function defaultProtocolPort (protocol) { + return protocol === 'https:' ? 443 : 80 } -function replaceXRanges (comp, options) { - debug('replaceXRanges', comp, options) - return comp.split(/\s+/).map(function (comp) { - return replaceXRange(comp, options) - }).join(' ') +function defaultFactory (origin, opts) { + return new Pool(origin, opts) } -function replaceXRange (comp, options) { - comp = comp.trim() - var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE] - return comp.replace(r, function (ret, gtlt, M, m, p, pr) { - debug('xRange', comp, ret, gtlt, M, m, p, pr) - var xM = isX(M) - var xm = xM || isX(m) - var xp = xm || isX(p) - var anyX = xp +const noop = () => {} - if (gtlt === '=' && anyX) { - gtlt = '' +function defaultAgentFactory (origin, opts) { + if (opts.connections === 1) { + return new Client(origin, opts) + } + return new Pool(origin, opts) +} + +function shouldProxyTunnel (requestProtocol, proxyTunnel) { + return proxyTunnel === true || requestProtocol !== 'http:' +} + +class Http1ProxyWrapper extends DispatcherBase { + #client + #proxyServername + + constructor (proxyUrl, { headers = {}, connect, factory, proxyServername }) { + if (!proxyUrl) { + throw new InvalidArgumentError('Proxy URL is mandatory') } - // if we're including prereleases in the match, then we need - // to fix this to -0, the lowest possible prerelease value - pr = options.includePrerelease ? '-0' : '' + super() - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<0.0.0-0' - } else { - // nothing is forbidden - ret = '*' - } - } else if (gtlt && anyX) { - // we know patch is an x, because we have any x at all. - // replace X with 0 - if (xm) { - m = 0 - } - p = 0 + this[kProxyHeaders] = headers + this.#proxyServername = proxyServername + if (factory) { + this.#client = factory(proxyUrl, { connect }) + } else { + this.#client = new Client(proxyUrl, { connect }) + } + } - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - // >1.2.3 => >= 1.2.4 - gtlt = '>=' - if (xm) { - M = +M + 1 - m = 0 - p = 0 - } else { - m = +m + 1 - p = 0 - } - } else if (gtlt === '<=') { - // <=0.7.x is actually <0.8.0, since any 0.7.x should - // pass. Similarly, <=7.x is actually <8.0.0, etc. - gtlt = '<' - if (xm) { - M = +M + 1 - } else { - m = +m + 1 + [kDispatch] (opts, handler) { + const onResponseStart = handler.onResponseStart + handler.onResponseStart = function (controller, statusCode, data, statusMessage) { + if (statusCode === 407) { + if (typeof handler.onResponseError === 'function') { + handler.onResponseError(controller, new InvalidArgumentError('Proxy Authentication Required (407)')) } + return } - - ret = gtlt + M + '.' + m + '.' + p + pr - } else if (xm) { - ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr - } else if (xp) { - ret = '>=' + M + '.' + m + '.0' + pr + - ' <' + M + '.' + (+m + 1) + '.0' + pr + if (onResponseStart) onResponseStart.call(this, controller, statusCode, data, statusMessage) } - debug('xRange return', ret) + // Rewrite request as an HTTP1 Proxy request, without tunneling. + const { + origin, + path = '/', + headers = {} + } = opts - return ret - }) -} + opts.path = origin + path -// Because * is AND-ed with everything else in the comparator, -// and '' means "any version", just remove the *s entirely. -function replaceStars (comp, options) { - debug('replaceStars', comp, options) - // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(safeRe[t.STAR], '') -} + opts.headers = { ...this[kProxyHeaders], ...headers } + if (!hasHostHeader(headers)) { + opts.headers.host = new URL(origin).host + } -// This function is passed to string.replace(re[t.HYPHENRANGE]) -// M, m, patch, prerelease, build -// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 -// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do -// 1.2 - 3.4 => >=1.2.0 <3.5.0 -function hyphenReplace ($0, - from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) { - if (isX(fM)) { - from = '' - } else if (isX(fm)) { - from = '>=' + fM + '.0.0' - } else if (isX(fp)) { - from = '>=' + fM + '.' + fm + '.0' - } else { - from = '>=' + from - } + // Pin the SNI/cert hostname to the proxy. Without this the underlying + // Client would derive it from the (rewritten) Host header, which points + // at the target — wrong for the TLS handshake to the proxy itself. + if (this.#proxyServername != null) { + opts.servername = this.#proxyServername + } - if (isX(tM)) { - to = '' - } else if (isX(tm)) { - to = '<' + (+tM + 1) + '.0.0' - } else if (isX(tp)) { - to = '<' + tM + '.' + (+tm + 1) + '.0' - } else if (tpr) { - to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr - } else { - to = '<=' + to + return this.#client[kDispatch](opts, handler) } - return (from + ' ' + to).trim() -} - -// if ANY of the sets match ALL of its comparators, then pass -Range.prototype.test = function (version) { - if (!version) { - return false + [kClose] () { + return this.#client.close() } - if (typeof version === 'string') { - try { - version = new SemVer(version, this.options) - } catch (er) { - return false - } + [kDestroy] (err) { + return this.#client.destroy(err) } +} - for (var i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version, this.options)) { - return true +class ProxyAgent extends DispatcherBase { + constructor (opts) { + if (!opts || (typeof opts === 'object' && !(opts instanceof URL) && !opts.uri)) { + throw new InvalidArgumentError('Proxy uri is mandatory') } - } - return false -} -function testSet (set, version, options) { - for (var i = 0; i < set.length; i++) { - if (!set[i].test(version)) { - return false + const { clientFactory = defaultFactory } = opts + if (typeof clientFactory !== 'function') { + throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') } - } - if (version.prerelease.length && !options.includePrerelease) { - // Find the set of versions that are allowed to have prereleases - // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 - // That should allow `1.2.3-pr.2` to pass. - // However, `1.2.4-alpha.notready` should NOT be allowed, - // even though it's within the range set by the comparators. - for (i = 0; i < set.length; i++) { - debug(set[i].semver) - if (set[i].semver === ANY) { - continue - } + const { proxyTunnel, connectTimeout } = opts - if (set[i].semver.prerelease.length > 0) { - var allowed = set[i].semver - if (allowed.major === version.major && - allowed.minor === version.minor && - allowed.patch === version.patch) { - return true - } - } - } + super(opts) - // Version has a -pre, but it's not one of the ones we like. - return false - } + const url = this.#getUrl(opts) + const { href, origin, port, protocol, username, password, hostname: proxyHostname } = url - return true -} + this[kProxy] = { uri: href, protocol } + this[kRequestTls] = opts.requestTls + this[kProxyTls] = opts.proxyTls + this[kProxyHeaders] = opts.headers || {} + this[kTunnelProxy] = proxyTunnel -exports.satisfies = satisfies -function satisfies (version, range, options) { - try { - range = new Range(range, options) - } catch (er) { - return false - } - return range.test(version) -} + if (opts.auth && opts.token) { + throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') + } else if (opts.auth) { + /* @deprecated in favour of opts.token */ + this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` + } else if (opts.token) { + this[kProxyHeaders]['proxy-authorization'] = opts.token + } else if (username && password) { + this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}` + } else if (username) { + this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:`).toString('base64')}` + } -exports.maxSatisfying = maxSatisfying -function maxSatisfying (versions, range, options) { - var max = null - var maxSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!max || maxSV.compare(v) === -1) { - // compare(max, v, true) - max = v - maxSV = new SemVer(max, options) + const connect = buildConnector({ timeout: connectTimeout, ...opts.proxyTls }) + const connectHTTP1 = buildConnector({ timeout: connectTimeout, ...opts.proxyTls, allowH2: false }) + this[kConnectEndpoint] = buildConnector({ timeout: connectTimeout, ...opts.requestTls }) + this[kConnectEndpointHTTP1] = buildConnector({ timeout: connectTimeout, ...opts.requestTls, allowH2: false }) + + const agentFactory = opts.factory || defaultAgentFactory + const factory = (origin, options) => { + const { protocol } = new URL(origin) + + // Handle SOCKS5 proxy + if (this[kProxy].protocol === 'socks5:' || this[kProxy].protocol === 'socks:') { + return new Socks5ProxyAgent(this[kProxy].uri, { + headers: this[kProxyHeaders], + connect, + factory: agentFactory, + username: opts.username || username, + password: opts.password || password, + connectTimeout, + proxyTls: opts.proxyTls, + requestTls: opts.requestTls + }) } - } - }) - return max -} -exports.minSatisfying = minSatisfying -function minSatisfying (versions, range, options) { - var min = null - var minSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!min || minSV.compare(v) === 1) { - // compare(min, v, true) - min = v - minSV = new SemVer(min, options) + if (!shouldProxyTunnel(protocol, this[kTunnelProxy])) { + const forwardConnect = this[kProxy].protocol === 'https:' + ? (opts, cb) => connectHTTP1(opts, (err, socket) => { + if (err && err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + cb(new SecureProxyConnectionError(err)) + } else { + cb(err, socket) + } + }) + : connectHTTP1 + return new Http1ProxyWrapper(this[kProxy].uri, { + headers: this[kProxyHeaders], + connect: forwardConnect, + factory: agentFactory, + proxyServername: this[kProxy].protocol === 'https:' + ? (this[kProxyTls]?.servername || proxyHostname) + : undefined + }) } + return agentFactory(origin, options) } - }) - return min -} -exports.minVersion = minVersion -function minVersion (range, loose) { - range = new Range(range, loose) + // For SOCKS5 proxies, we don't need a client to the proxy itself + // The SOCKS5 connection is handled within Socks5ProxyAgent + if (protocol === 'socks5:' || protocol === 'socks:') { + this[kClient] = null + } else { + this[kClient] = clientFactory(url, { connect }) + } - var minver = new SemVer('0.0.0') - if (range.test(minver)) { - return minver - } + this[kAgent] = new Agent({ + ...opts, + factory, + connect: async (opts, callback) => { + // SOCKS5 proxies handle their own connections via Socks5ProxyAgent, + // so this connect function should never be called for them. + if (!this[kClient]) { + callback(new InvalidArgumentError('Cannot establish tunnel connection without a proxy client')) + return + } - minver = new SemVer('0.0.0-0') - if (range.test(minver)) { - return minver - } + let requestedPath = opts.host + if (!opts.port) { + requestedPath += `:${defaultProtocolPort(opts.protocol)}` + } + try { + const connectParams = { + origin, + port, + path: requestedPath, + signal: opts.signal, + headers: { + ...this[kProxyHeaders], + host: opts.host, + ...(opts.connections == null || opts.connections > 0 ? { 'proxy-connection': 'keep-alive' } : {}) + }, + servername: this[kProxyTls]?.servername || proxyHostname + } + const { socket, statusCode } = await this[kClient].connect(connectParams) + if (statusCode !== 200) { + socket.on('error', noop).destroy() + callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)) + return + } - minver = null - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] + if (channels.proxyConnected.hasSubscribers) { + channels.proxyConnected.publish({ + socket, + connectParams + }) + } - comparators.forEach(function (comparator) { - // Clone to avoid manipulating the comparator's semver object. - var compver = new SemVer(comparator.semver.version) - switch (comparator.operator) { - case '>': - if (compver.prerelease.length === 0) { - compver.patch++ + if (opts.protocol !== 'https:') { + callback(null, socket) + return + } + let servername + if (this[kRequestTls]) { + servername = this[kRequestTls].servername } else { - compver.prerelease.push(0) + servername = opts.servername } - compver.raw = compver.format() - /* fallthrough */ - case '': - case '>=': - if (!minver || gt(minver, compver)) { - minver = compver + const connectEndpoint = opts.allowH2 === false + ? this[kConnectEndpointHTTP1] + : this[kConnectEndpoint] + + connectEndpoint({ ...opts, servername, httpSocket: socket }, callback) + } catch (err) { + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + // Throw a custom error to avoid loop in client.js#connect + callback(new SecureProxyConnectionError(err)) + } else if (err.code === 'UND_ERR_SOCKET') { + // A socket failure while establishing the tunnel means the CONNECT + // never completed, so there is nothing to recover - the proxy just + // tore down the connection. client.js#onError treats UND_ERR_SOCKET + // as a recoverable error on an established connection and leaves the + // request queued, which makes connect() retry forever. Surface it as + // a non-recoverable proxy error so the request fails instead. (#3897) + callback(new ProxyConnectionError(err)) + } else { + callback(err) } - break - case '<': - case '<=': - /* Ignore maximum versions */ - break - /* istanbul ignore next */ - default: - throw new Error('Unexpected operation: ' + comparator.operator) + } } }) } - if (minver && range.test(minver)) { - return minver + dispatch (opts, handler) { + let headers = buildHeaders(opts.headers) + throwIfProxyAuthIsSent(headers) + + if (headers && !hasHostHeader(headers)) { + if (headers === opts.headers) { + headers = { ...headers } + } + headers.host = new URL(opts.origin).host + } + + return this[kAgent].dispatch( + { + ...opts, + headers + }, + handler + ) } - return null -} + /** + * @param {import('../../types/proxy-agent').ProxyAgent.Options | string | URL} opts + * @returns {URL} + */ + #getUrl (opts) { + if (typeof opts === 'string') { + return new URL(opts) + } else if (opts instanceof URL) { + return opts + } else { + return new URL(opts.uri) + } + } -exports.validRange = validRange -function validRange (range, options) { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range(range, options).range || '*' - } catch (er) { - return null + [kClose] () { + const promises = [this[kAgent].close()] + if (this[kClient]) { + promises.push(this[kClient].close()) + } + return Promise.all(promises) } -} -// Determine if version is less than all the versions possible in the range -exports.ltr = ltr -function ltr (version, range, options) { - return outside(version, range, '<', options) + [kDestroy] () { + const promises = [this[kAgent].destroy()] + if (this[kClient]) { + promises.push(this[kClient].destroy()) + } + return Promise.all(promises) + } } -// Determine if version is greater than all the versions possible in the range. -exports.gtr = gtr -function gtr (version, range, options) { - return outside(version, range, '>', options) -} +/** + * @param {string[] | Record | Iterable<[string, string | string[] | undefined]>} headers + * @returns {Record} + */ +function buildHeaders (headers) { + // When using undici.fetch, the headers list is stored + // as an array. + if (Array.isArray(headers)) { + /** @type {Record} */ + const headersPair = {} -exports.outside = outside -function outside (version, range, hilo, options) { - version = new SemVer(version, options) - range = new Range(range, options) + for (let i = 0; i < headers.length; i += 2) { + if (isProxyAuthorizationHeader(headers[i])) { + throwProxyAuthError() + } - var gtfn, ltefn, ltfn, comp, ecomp - switch (hilo) { - case '>': - gtfn = gt - ltefn = lte - ltfn = lt - comp = '>' - ecomp = '>=' - break - case '<': - gtfn = lt - ltefn = gte - ltfn = gt - comp = '<' - ecomp = '<=' - break - default: - throw new TypeError('Must provide a hilo val of "<" or ">"') - } + headersPair[headers[i]] = headers[i + 1] + } - // If it satisifes the range it is not outside - if (satisfies(version, range, options)) { - return false + return headersPair } - // From now on, variable terms are as if we're in "gtr" mode. - // but note that everything is flipped for the "ltr" function. - - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] + // Materialize iterable header containers (e.g. Map, Headers) into a record so + // that throwIfProxyAuthIsSent() can inspect their entries. Object.keys and + // for...in see nothing on a Map/Headers instance, so without this the + // Proxy-Authorization guard is bypassed and proxy credentials can reach the + // origin server (GHSA-6cv7-626c-qhqw). + if (headers && typeof headers === 'object' && hasSafeIterator(headers)) { + const headersPair = {} - var high = null - var low = null + for (const [key, value] of headers) { + if (!Object.hasOwn(headersPair, key)) { + headersPair[key] = value + continue + } - comparators.forEach(function (comparator) { - if (comparator.semver === ANY) { - comparator = new Comparator('>=0.0.0') + const previous = headersPair[key] + const values = [] + if (previous !== undefined) { + values.push(...(Array.isArray(previous) ? previous : [previous])) } - high = high || comparator - low = low || comparator - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator + if (value !== undefined) { + values.push(...(Array.isArray(value) ? value : [value])) } - }) - - // If the edge version comparator has a operator then our version - // isn't outside it - if (high.operator === comp || high.operator === ecomp) { - return false + headersPair[key] = values.length > 1 ? values : values[0] } - // If the lowest version comparator has an operator and our version - // is less than it then it isn't higher than the range - if ((!low.operator || low.operator === comp) && - ltefn(version, low.semver)) { - return false - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false - } + return headersPair } - return true -} - -exports.prerelease = prerelease -function prerelease (version, options) { - var parsed = parse(version, options) - return (parsed && parsed.prerelease.length) ? parsed.prerelease : null -} -exports.intersects = intersects -function intersects (r1, r2, options) { - r1 = new Range(r1, options) - r2 = new Range(r2, options) - return r1.intersects(r2) + return headers } -exports.coerce = coerce -function coerce (version, options) { - if (version instanceof SemVer) { - return version - } - - if (typeof version === 'number') { - version = String(version) - } - - if (typeof version !== 'string') { - return null +/** + * @param {Record} headers + * + * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers + * Nevertheless, it was changed and to avoid a security vulnerability by end users + * this check was created. + * It should be removed in the next major version for performance reasons + */ +function throwIfProxyAuthIsSent (headers) { + for (const key in headers) { + if (isProxyAuthorizationHeader(key)) { + throwProxyAuthError() + } } +} - options = options || {} +/** + * @param {string} key + * @returns {boolean} + */ +function isProxyAuthorizationHeader (key) { + return key.length === proxyAuthorization.length && key.toLowerCase() === proxyAuthorization +} - var match = null - if (!options.rtl) { - match = version.match(safeRe[t.COERCE]) - } else { - // Find the right-most coercible string that does not share - // a terminus with a more left-ward coercible string. - // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' - // - // Walk through the string checking with a /g regexp - // Manually set the index so as to pick up overlapping matches. - // Stop when we get a match that ends at the string end, since no - // coercible string can be more right-ward without the same terminus. - var next - while ((next = safeRe[t.COERCERTL].exec(version)) && - (!match || match.index + match[0].length !== version.length) - ) { - if (!match || - next.index + next[0].length !== match.index + match[0].length) { - match = next - } - safeRe[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length +function hasHostHeader (headers) { + for (const key in headers) { + if (key.length === 4 && key.toLowerCase() === 'host') { + return true } - // leave it in a clean state - safeRe[t.COERCERTL].lastIndex = -1 - } - - if (match === null) { - return null } + return false +} - return parse(match[2] + - '.' + (match[3] || '0') + - '.' + (match[4] || '0'), options) +function throwProxyAuthError () { + throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') } +module.exports = ProxyAgent + /***/ }), -/***/ 770: +/***/ 50: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -module.exports = __nccwpck_require__(218); - - -/***/ }), +"use strict"; -/***/ 218: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; +const Dispatcher = __nccwpck_require__(883) +const RetryHandler = __nccwpck_require__(7816) +const { kOriginless, kUrl } = __nccwpck_require__(6443) +class RetryAgent extends Dispatcher { + #agent = null + #options = null + constructor (agent, options = {}) { + super(options) + this.#agent = agent + this.#options = options + this[kUrl] = agent[kUrl] + this[kOriginless] = agent[kOriginless] + } -var net = __nccwpck_require__(9278); -var tls = __nccwpck_require__(4756); -var http = __nccwpck_require__(8611); -var https = __nccwpck_require__(5692); -var events = __nccwpck_require__(4434); -var assert = __nccwpck_require__(2613); -var util = __nccwpck_require__(9023); + dispatch (opts, handler) { + const retry = new RetryHandler({ + ...opts, + retryOptions: this.#options + }, { + dispatch: this.#agent.dispatch.bind(this.#agent), + handler + }) + return this.#agent.dispatch(opts, retry) + } + // WebSocket and EventSource read their receive limits from the dispatcher + // they are given, so report the wrapped agent's settings rather than none. + get webSocketOptions () { + return this.#agent.webSocketOptions + } -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; + get eventSourceOptions () { + return this.#agent.eventSourceOptions + } + close () { + return this.#agent.close() + } -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; + destroy () { + return this.#agent.destroy() + } } -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} +module.exports = RetryAgent -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} +/***/ }), +/***/ 5520: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; +"use strict"; - self.on('free', function onFree(socket, host, port, localAddress) { - var options = toOptions(host, port, localAddress); - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === options.host && pending.port === options.port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } - } - socket.destroy(); - self.removeSocket(socket); - }); -} -util.inherits(TunnelingAgent, events.EventEmitter); -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { - var self = this; - var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kGetDispatcher, + kHasDispatcher, + kRemoveClient, + kRetireClient, + kDrainQueue +} = __nccwpck_require__(2128) +const Client = __nccwpck_require__(3701) +const { + InvalidArgumentError +} = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) +const { kUrl, kQueued } = __nccwpck_require__(6443) +const buildConnector = __nccwpck_require__(9136) - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push(options); - return; - } +const kOptions = Symbol('options') +const kConnections = Symbol('connections') +const kFactory = Symbol('factory') +const kIndex = Symbol('index') - // If we are under maxSockets create a new one. - self.createSocket(options, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); +function defaultFactory (origin, opts) { + return new Client(origin, opts) +} - function onFree() { - self.emit('free', socket, options); +class RoundRobinPool extends PoolBase { + constructor (origin, { + connections, + factory = defaultFactory, + connect, + connectTimeout, + tls, + maxCachedSessions, + socketPath, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + allowH2, + clientTtl, + ...options + } = {}) { + if (connections != null && (!Number.isFinite(connections) || connections < 0)) { + throw new InvalidArgumentError('invalid connections') } - function onCloseOrRemove(err) { - self.removeSocket(socket); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') } - }); -}; - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false, - headers: { - host: options.host + ':' + options.port + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') } - }); - if (options.localAddress) { - connectOptions.localAddress = options.localAddress; - } - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); - } - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; - } + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(typeof autoSelectFamily === 'boolean' ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) + } - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); - } + super(options) - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); + this[kConnections] = connections || null + this[kUrl] = util.parseOrigin(origin) + this[kOptions] = { ...util.deepClone(options), connect, allowH2, clientTtl, socketPath } + this[kFactory] = factory + this[kIndex] = -1 - if (res.statusCode !== 200) { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - socket.destroy(); - var error = new Error('tunneling socket could not be established, ' + - 'statusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; - } - if (head.length > 0) { - debug('got illegal response body from proxy'); - socket.destroy(); - var error = new Error('got illegal response body from proxy'); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; - } - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - return cb(socket); - } + this.on('connect', (origin, targets) => { + if (clientTtl != null && clientTtl > 0) { + for (const target of targets) { + Object.assign(target, { ttl: Date.now() }) + } + } + }) - function onError(cause) { - connectReq.removeAllListeners(); + this.on('connectionError', (origin, targets, error) => { + // Retire (close) the client rather than only dropping it from + // kClients: otherwise its drain listener keeps pulling requests from + // the pool queue onto a client that pool.destroy() can't reach. + for (const target of targets) { + if (this[kClients].includes(target)) { + this[kRetireClient](target) + } + } - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); + // The retired client no longer drains the pool queue, so hand any + // queued requests to another (possibly new) client. + if (this[kQueued] > 0) { + this[kDrainQueue](origin, targets.slice(1)) + } + }) } -}; -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; - } - this.sockets.splice(pos, 1); + [kGetDispatcher] () { + const clientTtlOption = this[kOptions].clientTtl - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); - } -}; + // If we have no clients yet, create one + if (this[kClients].length === 0) { + const dispatcher = this[kFactory](this[kUrl], this[kOptions]) + this[kAddClient](dispatcher) + return dispatcher + } -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - var hostHeader = options.request.getHeader('host'); - var tlsOptions = mergeOptions({}, self.options, { - socket: socket, - servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host - }); + // Round-robin through existing clients + let checked = 0 + while (checked < this[kClients].length) { + this[kIndex] = (this[kIndex] + 1) % this[kClients].length + const client = this[kClients][this[kIndex]] - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, tlsOptions); - self.sockets[self.sockets.indexOf(socket)] = secureSocket; - cb(secureSocket); - }); -} + // Check if client is stale (TTL expired) + if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && ((Date.now() - client.ttl) > clientTtlOption)) { + this[kRemoveClient](client) + this[kIndex]-- + continue + } + // Return client if it's not draining + if (!client[kNeedDrain]) { + return client + } -function toOptions(host, port, localAddress) { - if (typeof host === 'string') { // since v0.10 - return { - host: host, - port: port, - localAddress: localAddress - }; + checked++ + } + + // All clients are busy, create a new one if we haven't reached the limit + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + const dispatcher = this[kFactory](this[kUrl], this[kOptions]) + this[kAddClient](dispatcher) + return dispatcher + } } - return host; // for v0.11 or later -} -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; + [kHasDispatcher] () { + const clientTtlOption = this[kOptions].clientTtl + for (let i = 0; i < this[kClients].length; i++) { + const client = this[kClients][i] + + if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && ((Date.now() - client.ttl) > clientTtlOption)) { + this[kRemoveClient](client) + if (i <= this[kIndex]) { + this[kIndex]-- } + i-- + } else if (!client[kNeedDrain]) { + return true } } - } - return target; -} - -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + const dispatcher = this[kFactory](this[kUrl], this[kOptions]) + this[kAddClient](dispatcher) + return true } - console.error.apply(console, args); + + return false } -} else { - debug = function() {}; } -exports.debug = debug; // for test + +module.exports = RoundRobinPool /***/ }), -/***/ 6752: +/***/ 7223: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const Client = __nccwpck_require__(3701) -const Dispatcher = __nccwpck_require__(883) +const { URL } = __nccwpck_require__(3136) + +let tls // include tls conditionally since it is not always available +const DispatcherBase = __nccwpck_require__(1841) +const { ConnectTimeoutError, InvalidArgumentError } = __nccwpck_require__(8707) +const { Socks5Client, STATES } = __nccwpck_require__(8082) +const { kBusy, kConnected, kDispatch, kClose, kDestroy } = __nccwpck_require__(6443) const Pool = __nccwpck_require__(628) -const BalancedPool = __nccwpck_require__(837) -const Agent = __nccwpck_require__(7405) -const ProxyAgent = __nccwpck_require__(6672) -const EnvHttpProxyAgent = __nccwpck_require__(3137) -const RetryAgent = __nccwpck_require__(50) -const errors = __nccwpck_require__(8707) -const util = __nccwpck_require__(3440) -const { InvalidArgumentError } = errors -const api = __nccwpck_require__(6615) const buildConnector = __nccwpck_require__(9136) -const MockClient = __nccwpck_require__(7365) -const MockAgent = __nccwpck_require__(7501) -const MockPool = __nccwpck_require__(4004) -const mockErrors = __nccwpck_require__(2429) -const RetryHandler = __nccwpck_require__(7816) -const { getGlobalDispatcher, setGlobalDispatcher } = __nccwpck_require__(2581) -const DecoratorHandler = __nccwpck_require__(8155) -const RedirectHandler = __nccwpck_require__(8754) -const createRedirectInterceptor = __nccwpck_require__(5092) +const { setupConnectTimeout } = __nccwpck_require__(3440) +const { debuglog } = __nccwpck_require__(7975) -Object.assign(Dispatcher.prototype, api) +const debug = debuglog('undici:socks5-proxy') -module.exports.Dispatcher = Dispatcher -module.exports.Client = Client -module.exports.Pool = Pool -module.exports.BalancedPool = BalancedPool -module.exports.Agent = Agent -module.exports.ProxyAgent = ProxyAgent -module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent -module.exports.RetryAgent = RetryAgent -module.exports.RetryHandler = RetryHandler - -module.exports.DecoratorHandler = DecoratorHandler -module.exports.RedirectHandler = RedirectHandler -module.exports.createRedirectInterceptor = createRedirectInterceptor -module.exports.interceptors = { - redirect: __nccwpck_require__(1514), - retry: __nccwpck_require__(2026), - dump: __nccwpck_require__(8060), - dns: __nccwpck_require__(379) -} +const DEFAULT_SOCKS5_CONNECT_TIMEOUT = 5000 -module.exports.buildConnector = buildConnector -module.exports.errors = errors -module.exports.util = { - parseHeaders: util.parseHeaders, - headerNameToString: util.headerNameToString +const kProxyUrl = Symbol('proxy url') +const kProxyHeaders = Symbol('proxy headers') +const kProxyAuth = Symbol('proxy auth') +const kProxyProtocol = Symbol('proxy protocol') +const kPools = Symbol('pools') +const kConnector = Symbol('connector') +const kConnectTimeout = Symbol('connect timeout') +const kRequestTls = Symbol('request tls settings') +const kRequestTlsTimeout = Symbol('request tls timeout') + +function createConnectTimeoutError (hostname, port, timeout) { + return new ConnectTimeoutError( + `Connect Timeout Error (attempted address: ${hostname}:${port}, timeout: ${timeout}ms)` + ) } -function makeDispatcher (fn) { - return (url, opts, handler) => { - if (typeof opts === 'function') { - handler = opts - opts = null - } +// Static flag to ensure warning is only emitted once per process +let experimentalWarningEmitted = false - if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { - throw new InvalidArgumentError('invalid url') - } +/** + * SOCKS5 proxy agent for dispatching requests through a SOCKS5 proxy + */ +class Socks5ProxyAgent extends DispatcherBase { + constructor (proxyUrl, options = {}) { + super(options) - if (opts != null && typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') + // Emit experimental warning only once + if (!experimentalWarningEmitted) { + process.emitWarning( + 'SOCKS5 proxy support is experimental and subject to change', + 'ExperimentalWarning' + ) + experimentalWarningEmitted = true } - if (opts && opts.path != null) { - if (typeof opts.path !== 'string') { - throw new InvalidArgumentError('invalid opts.path') - } - - let path = opts.path - if (!opts.path.startsWith('/')) { - path = `/${path}` - } + if (!proxyUrl) { + throw new InvalidArgumentError('Proxy URL is mandatory') + } - url = new URL(util.parseOrigin(url).origin + path) - } else { - if (!opts) { - opts = typeof url === 'object' ? url : {} - } + // Parse proxy URL + const url = typeof proxyUrl === 'string' ? new URL(proxyUrl) : proxyUrl - url = util.parseURL(url) + if (url.protocol !== 'socks5:' && url.protocol !== 'socks:') { + throw new InvalidArgumentError('Proxy URL must use socks5:// or socks:// protocol') } - const { agent, dispatcher = getGlobalDispatcher() } = opts + this[kProxyUrl] = url + this[kProxyHeaders] = options.headers || {} + this[kProxyProtocol] = options.proxyTls ? 'https:' : 'http:' - if (agent) { - throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') + const connectTimeout = options.connectTimeout ?? DEFAULT_SOCKS5_CONNECT_TIMEOUT + if (!Number.isFinite(connectTimeout) || connectTimeout < 0) { + throw new InvalidArgumentError('invalid connectTimeout') } + this[kConnectTimeout] = connectTimeout - return fn.call(dispatcher, { - ...opts, - origin: url.origin, - path: url.search ? `${url.pathname}${url.search}` : url.pathname, - method: opts.method || (opts.body ? 'PUT' : 'GET') - }, handler) - } -} + const { timeout, ...requestTls } = options.requestTls || {} + const requestTlsTimeout = timeout ?? connectTimeout + if (!Number.isFinite(requestTlsTimeout) || requestTlsTimeout < 0) { + throw new InvalidArgumentError('invalid requestTls.timeout') + } + this[kRequestTls] = requestTls + this[kRequestTlsTimeout] = requestTlsTimeout -module.exports.setGlobalDispatcher = setGlobalDispatcher -module.exports.getGlobalDispatcher = getGlobalDispatcher + // Extract auth from URL or options + this[kProxyAuth] = { + username: options.username || (url.username ? decodeURIComponent(url.username) : null), + password: options.password || (url.password ? decodeURIComponent(url.password) : null) + } -const fetchImpl = (__nccwpck_require__(4398).fetch) -module.exports.fetch = async function fetch (init, options = undefined) { - try { - return await fetchImpl(init, options) - } catch (err) { - if (err && typeof err === 'object') { - Error.captureStackTrace(err) + // Create connector for proxy connection + const proxyTlsTimeout = options.proxyTls?.timeout ?? connectTimeout + if (!Number.isFinite(proxyTlsTimeout) || proxyTlsTimeout < 0) { + throw new InvalidArgumentError('invalid proxyTls.timeout') } + this[kConnector] = options.connect || buildConnector({ + ...options.proxyTls, + timeout: proxyTlsTimeout, + servername: options.proxyTls?.servername || url.hostname + }) - throw err + // Pools for the actual HTTP connections (with SOCKS5 tunnel connect function), keyed by origin + this[kPools] = new Map() } -} -module.exports.Headers = __nccwpck_require__(660).Headers -module.exports.Response = __nccwpck_require__(9051).Response -module.exports.Request = __nccwpck_require__(9967).Request -module.exports.FormData = __nccwpck_require__(5910).FormData -module.exports.File = globalThis.File ?? (__nccwpck_require__(4573).File) -module.exports.FileReader = __nccwpck_require__(8355).FileReader -const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1059) + /** + * Create a SOCKS5 connection to the proxy + */ + async createSocks5Connection (targetHost, targetPort) { + const proxyHost = this[kProxyUrl].hostname + const proxyPort = parseInt(this[kProxyUrl].port) || 1080 -module.exports.setGlobalOrigin = setGlobalOrigin -module.exports.getGlobalOrigin = getGlobalOrigin + debug('creating SOCKS5 connection to', proxyHost, proxyPort) -const { CacheStorage } = __nccwpck_require__(3245) -const { kConstruct } = __nccwpck_require__(109) + // Connect to the SOCKS5 proxy + const socketReady = Promise.withResolvers() -// Cache & CacheStorage are tightly coupled with fetch. Even if it may run -// in an older version of Node, it doesn't have any use without fetch. -module.exports.caches = new CacheStorage(kConstruct) + this[kConnector]({ + hostname: proxyHost, + host: proxyHost, + port: proxyPort, + protocol: this[kProxyProtocol] + }, (err, socket) => { + if (err) { + socketReady.reject(err) + } else { + socketReady.resolve(socket) + } + }) -const { deleteCookie, getCookies, getSetCookies, setCookie } = __nccwpck_require__(9061) + const socket = await socketReady.promise -module.exports.deleteCookie = deleteCookie -module.exports.getCookies = getCookies -module.exports.getSetCookies = getSetCookies -module.exports.setCookie = setCookie + // Create SOCKS5 client + const socks5Client = new Socks5Client(socket, this[kProxyAuth]) -const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(1900) + // Handle SOCKS5 errors + socks5Client.on('error', (err) => { + debug('SOCKS5 error:', err) + socket.destroy() + }) -module.exports.parseMIMEType = parseMIMEType -module.exports.serializeAMimeType = serializeAMimeType + // Perform SOCKS5 handshake + await socks5Client.handshake() -const { CloseEvent, ErrorEvent, MessageEvent } = __nccwpck_require__(5188) -module.exports.WebSocket = __nccwpck_require__(3726).WebSocket -module.exports.CloseEvent = CloseEvent -module.exports.ErrorEvent = ErrorEvent -module.exports.MessageEvent = MessageEvent - -module.exports.request = makeDispatcher(api.request) -module.exports.stream = makeDispatcher(api.stream) -module.exports.pipeline = makeDispatcher(api.pipeline) -module.exports.connect = makeDispatcher(api.connect) -module.exports.upgrade = makeDispatcher(api.upgrade) - -module.exports.MockClient = MockClient -module.exports.MockPool = MockPool -module.exports.MockAgent = MockAgent -module.exports.mockErrors = mockErrors + // Wait for authentication (if required) + const authenticationReady = Promise.withResolvers() + const authenticationTimeout = this[kConnectTimeout] === 0 + ? null + : setTimeout(() => { + cleanupAuthenticationListeners() + socks5Client.destroy() + authenticationReady.reject( + createConnectTimeoutError(proxyHost, proxyPort, this[kConnectTimeout]) + ) + }, this[kConnectTimeout]) -const { EventSource } = __nccwpck_require__(1238) + const cleanupAuthenticationListeners = () => { + clearTimeout(authenticationTimeout) + socks5Client.removeListener('authenticated', onAuthenticated) + socks5Client.removeListener('error', onAuthenticationError) + } -module.exports.EventSource = EventSource + const onAuthenticated = () => { + cleanupAuthenticationListeners() + authenticationReady.resolve() + } + const onAuthenticationError = (err) => { + cleanupAuthenticationListeners() + authenticationReady.reject(err) + } -/***/ }), + // Check if already authenticated (for NO_AUTH method) + if (socks5Client.state === STATES.AUTHENTICATED) { + clearTimeout(authenticationTimeout) + authenticationReady.resolve() + } else { + socks5Client.once('authenticated', onAuthenticated) + socks5Client.once('error', onAuthenticationError) + } -/***/ 158: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + await authenticationReady.promise -const { addAbortListener } = __nccwpck_require__(3440) -const { RequestAbortedError } = __nccwpck_require__(8707) + // Send CONNECT command + await socks5Client.connect(targetHost, targetPort) -const kListener = Symbol('kListener') -const kSignal = Symbol('kSignal') + // Wait for connection + const connectionReady = Promise.withResolvers() + const connectionTimeout = this[kConnectTimeout] === 0 + ? null + : setTimeout(() => { + cleanupConnectionListeners() + socks5Client.destroy() + connectionReady.reject( + createConnectTimeoutError(targetHost, targetPort, this[kConnectTimeout]) + ) + }, this[kConnectTimeout]) -function abort (self) { - if (self.abort) { - self.abort(self[kSignal]?.reason) - } else { - self.reason = self[kSignal]?.reason ?? new RequestAbortedError() - } - removeSignal(self) -} + const cleanupConnectionListeners = () => { + clearTimeout(connectionTimeout) + socks5Client.removeListener('connected', onConnected) + socks5Client.removeListener('error', onConnectionError) + } -function addSignal (self, signal) { - self.reason = null + const onConnected = (info) => { + debug('SOCKS5 tunnel established to', targetHost, targetPort, 'via', info) + cleanupConnectionListeners() + connectionReady.resolve() + } - self[kSignal] = null - self[kListener] = null + const onConnectionError = (err) => { + cleanupConnectionListeners() + connectionReady.reject(err) + } - if (!signal) { - return - } + socks5Client.once('connected', onConnected) + socks5Client.once('error', onConnectionError) - if (signal.aborted) { - abort(self) - return - } + await connectionReady.promise - self[kSignal] = signal - self[kListener] = () => { - abort(self) + return socket } - addAbortListener(self[kSignal], self[kListener]) -} + /** + * Dispatch a request through the SOCKS5 proxy + */ + [kDispatch] (opts, handler) { + const { origin } = opts -function removeSignal (self) { - if (!self[kSignal]) { - return - } + debug('dispatching request to', origin, 'via SOCKS5') - if ('removeEventListener' in self[kSignal]) { - self[kSignal].removeEventListener('abort', self[kListener]) - } else { - self[kSignal].removeListener('abort', self[kListener]) - } + try { + const originKey = String(origin) + let pool = this[kPools].get(originKey) + // Create a Pool per origin so requests are not routed to the wrong host + if (!pool || pool.destroyed || pool.closed) { + pool = new Pool(origin, { + pipelining: opts.pipelining, + connections: opts.connections, + connect: async (connectOpts, callback) => { + try { + const url = new URL(origin) + const targetHost = url.hostname + const targetPort = parseInt(url.port) || (url.protocol === 'https:' ? 443 : 80) - self[kSignal] = null - self[kListener] = null -} + debug('establishing SOCKS5 connection to', targetHost, targetPort) -module.exports = { - addSignal, - removeSignal -} + // Create SOCKS5 tunnel + const socket = await this.createSocks5Connection(targetHost, targetPort) + // Handle TLS if needed + let finalSocket = socket + if (url.protocol === 'https:') { + if (!tls) { + tls = __nccwpck_require__(1692) + } + debug('upgrading to TLS') + finalSocket = tls.connect({ + ...this[kRequestTls], + socket, + servername: this[kRequestTls]?.servername || targetHost + }) + + const tlsReady = Promise.withResolvers() + + const cleanupTlsListeners = () => { + queueMicrotask(clearTlsTimeout) + finalSocket.removeListener('secureConnect', onSecureConnect) + finalSocket.removeListener('error', onTlsError) + } -/***/ }), + const onSecureConnect = () => { + cleanupTlsListeners() + tlsReady.resolve() + } -/***/ 2279: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const onTlsError = (err) => { + cleanupTlsListeners() + tlsReady.reject(err) + } -"use strict"; + const clearTlsTimeout = setupConnectTimeout(new WeakRef(finalSocket), { + timeout: this[kRequestTlsTimeout], + hostname: targetHost, + port: targetPort + }) + finalSocket.once('secureConnect', onSecureConnect) + finalSocket.once('error', onTlsError) + await tlsReady.promise + } -const assert = __nccwpck_require__(4589) -const { AsyncResource } = __nccwpck_require__(6698) -const { InvalidArgumentError, SocketError } = __nccwpck_require__(8707) -const util = __nccwpck_require__(3440) -const { addSignal, removeSignal } = __nccwpck_require__(158) + callback(null, finalSocket) + } catch (err) { + debug('SOCKS5 connection error:', err) + callback(err) + } + } + }) + this[kPools].set(originKey, pool) -class ConnectHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') + const closePoolIfUnused = () => { + if (this[kPools].get(originKey) !== pool || pool[kConnected] > 0 || pool[kBusy]) { + return + } + + this[kPools].delete(originKey) + if (!pool.destroyed) { + pool.close() + } + } + + pool.on('disconnect', closePoolIfUnused) + pool.on('connectionError', closePoolIfUnused) + } + + // Dispatch the request through the per-origin pool + return pool[kDispatch](opts, handler) + } catch (err) { + debug('dispatch error:', err) + if (typeof handler.onResponseError === 'function') { + handler.onResponseError(null, err) + return false + } else if (typeof handler.onError === 'function') { + handler.onError(err) + return false + } else { + throw err + } } + } - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') + async [kClose] () { + const closePromises = [] + for (const pool of this[kPools].values()) { + closePromises.push(pool.close()) + } + this[kPools].clear() + await Promise.all(closePromises) + } + + async [kDestroy] (err) { + const destroyPromises = [] + for (const pool of this[kPools].values()) { + destroyPromises.push(pool.destroy(err)) } + this[kPools].clear() + await Promise.all(destroyPromises) + } +} - const { signal, opaque, responseHeaders } = opts +module.exports = Socks5ProxyAgent - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } - super('UNDICI_CONNECT') +/***/ }), - this.opaque = opaque || null - this.responseHeaders = responseHeaders || null - this.callback = callback - this.abort = null +/***/ 276: +/***/ ((module) => { - addSignal(this, signal) - } +"use strict"; - onConnect (abort, context) { - if (this.reason) { - abort(this.reason) - return - } - assert(this.callback) +const textDecoder = new TextDecoder() - this.abort = abort - this.context = context +/** + * @see https://encoding.spec.whatwg.org/#utf-8-decode + * @param {Uint8Array} buffer + */ +function utf8DecodeBytes (buffer) { + if (buffer.length === 0) { + return '' } - onHeaders () { - throw new SocketError('bad connect', null) + // 1. Let buffer be the result of peeking three bytes from + // ioQueue, converted to a byte sequence. + + // 2. If buffer is 0xEF 0xBB 0xBF, then read three + // bytes from ioQueue. (Do nothing with those bytes.) + if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { + buffer = buffer.subarray(3) } - onUpgrade (statusCode, rawHeaders, socket) { - const { callback, opaque, context } = this + // 3. Process a queue with an instance of UTF-8’s + // decoder, ioQueue, output, and "replacement". + const output = textDecoder.decode(buffer) - removeSignal(this) + // 4. Return output. + return output +} - this.callback = null +module.exports = { + utf8DecodeBytes +} - let headers = rawHeaders - // Indicates is an HTTP2Session - if (headers != null) { - headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - } - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - socket, - opaque, - context - }) - } +/***/ }), - onError (err) { - const { callback, opaque } = this +/***/ 2581: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - removeSignal(this) +"use strict"; - if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } - } + +// We include a version number for the Dispatcher API. In case of breaking changes, +// this version number must be increased to avoid conflicts. +const globalDispatcher = Symbol.for('undici.globalDispatcher.2') +const legacyGlobalDispatcher = Symbol.for('undici.globalDispatcher.1') +const { InvalidArgumentError } = __nccwpck_require__(8707) +const Agent = __nccwpck_require__(7405) +const Dispatcher1Wrapper = __nccwpck_require__(3650) + +// Fallback storage for when globalThis is not extensible (e.g. frozen) +let fallbackDispatcher + +if (getGlobalDispatcher() === undefined) { + setGlobalDispatcher(new Agent()) } -function connect (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - connect.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) +function setGlobalDispatcher (agent) { + if (!agent || typeof agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument agent must implement Agent') + } + + try { + Object.defineProperty(globalThis, globalDispatcher, { + value: agent, + writable: true, + enumerable: false, + configurable: false }) + } catch (err) { + // globalThis is not extensible (e.g. Object.freeze(globalThis)) + // Use fallback storage instead + if (err instanceof TypeError) { + fallbackDispatcher = agent + return + } + throw err } try { - const connectHandler = new ConnectHandler(opts, callback) - this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) + const legacyAgent = agent instanceof Dispatcher1Wrapper ? agent : new Dispatcher1Wrapper(agent) + + Object.defineProperty(globalThis, legacyGlobalDispatcher, { + value: legacyAgent, + writable: true, + enumerable: false, + configurable: false + }) } catch (err) { - if (typeof callback !== 'function') { + // globalThis is not extensible; fallback storage is already set + if (!(err instanceof TypeError)) { throw err } - const opaque = opts?.opaque - queueMicrotask(() => callback(err, { opaque })) } } -module.exports = connect +function getGlobalDispatcher () { + return globalThis[globalDispatcher] ?? fallbackDispatcher +} + +// These are the globals that can be installed by undici.install(). +// Not exported by index.js to avoid use outside of this module. +const installedExports = /** @type {const} */ ( + [ + 'fetch', + 'Headers', + 'Response', + 'Request', + 'FormData', + 'WebSocket', + 'CloseEvent', + 'ErrorEvent', + 'MessageEvent', + 'EventSource' + ] +) + +module.exports = { + setGlobalDispatcher, + getGlobalDispatcher, + installedExports +} /***/ }), -/***/ 6862: +/***/ 9976: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { - Readable, - Duplex, - PassThrough -} = __nccwpck_require__(7075) -const { - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError -} = __nccwpck_require__(8707) const util = __nccwpck_require__(3440) -const { AsyncResource } = __nccwpck_require__(6698) -const { addSignal, removeSignal } = __nccwpck_require__(158) -const assert = __nccwpck_require__(4589) +const { kRedirectCacheControl } = __nccwpck_require__(6443) +const { + parseCacheControlHeader, + hasInvalidCacheControlDirective, + parseVaryHeader, + hasVaryStar, + isInvalidOrWildcardVaryHeader, + isEtagUsable +} = __nccwpck_require__(7659) +const { parseHttpDate } = __nccwpck_require__(5453) -const kResume = Symbol('resume') +function noop () {} -class PipelineRequest extends Readable { - constructor () { - super({ autoDestroy: true }) +class CacheController { + #blocked = false + #downstreamPaused = false - this[kResume] = null + constructor (target) { + this.target = target } - _read () { - const { [kResume]: resume } = this + block () { + this.#blocked = true + } - if (resume) { - this[kResume] = null - resume() + release () { + this.#blocked = false + if (!this.#downstreamPaused) { + this.target.resume() } } - _destroy (err, callback) { - this._read() - - callback(err) + pause () { + this.#downstreamPaused = true + this.target.pause() } -} -class PipelineResponse extends Readable { - constructor (resume) { - super({ autoDestroy: true }) - this[kResume] = resume + resume () { + this.#downstreamPaused = false + if (!this.#blocked) { + this.target.resume() + } } - _read () { - this[kResume]() + abort (reason) { + this.target.abort(reason) } - _destroy (err, callback) { - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError() - } + get paused () { return this.#downstreamPaused } + get aborted () { return this.target.aborted } + get reason () { return this.target.reason } + get rawHeaders () { return this.target.rawHeaders } + set rawHeaders (value) { this.target.rawHeaders = value } + get rawTrailers () { return this.target.rawTrailers } + set rawTrailers (value) { this.target.rawTrailers = value } +} - callback(err) +/** + * @param {string | URL} a + * @param {string | URL} b + * @returns {boolean} + */ +function sameOrigin (a, b) { + try { + return new URL(String(a)).origin === new URL(String(b)).origin + } catch { + return String(a) === String(b) } } -class PipelineHandler extends AsyncResource { - constructor (opts, handler) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } +// Status codes that we can use some heuristics on to cache +const HEURISTICALLY_CACHEABLE_STATUS_CODES = [ + 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501 +] - if (typeof handler !== 'function') { - throw new InvalidArgumentError('invalid handler') - } +// Status codes which semantic is not handled by the cache +// https://datatracker.ietf.org/doc/html/rfc9111#section-3 +// This list should not grow beyond 206 unless the RFC is updated +// by a newer one including more. Please introduce another list if +// implementing caching of responses with the 'must-understand' directive. +const NOT_UNDERSTOOD_STATUS_CODES = [ + 206 +] - const { signal, method, opaque, onInfo, responseHeaders } = opts +const MAX_RESPONSE_AGE = 2147483647000 - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } +// Retention for revalidation-only entries (zero freshness lifetime but a +// validator present); each successful revalidation re-stores the entry. +const REVALIDATION_ONLY_RETENTION = 86400000 // 24 hours - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') +function trimOWS (value) { + return value.replace(/^[\t ]+|[\t ]+$/g, '') +} + +function arrayIncludes (array, value) { + for (let i = 0; i < array.length; i++) { + if (array[i] === value) { + return true } + } - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') + return false +} + +function appendConnectionHeaderTokens (headersToRemove, connectionHeader) { + const values = Array.isArray(connectionHeader) ? connectionHeader : [connectionHeader] + + for (let i = 0; i < values.length; i++) { + const tokens = values[i].split(',') + for (let j = 0; j < tokens.length; j++) { + headersToRemove.push(trimOWS(tokens[j]).toLowerCase()) } + } +} - super('UNDICI_PIPELINE') +function getSameOriginPath (cacheKey, location) { + if (typeof location !== 'string') { + return undefined + } - this.opaque = opaque || null - this.responseHeaders = responseHeaders || null - this.handler = handler - this.abort = null - this.context = null - this.onInfo = onInfo || null + let originUrl + let requestUrl + let locationUrl + try { + originUrl = new URL(cacheKey.origin) + requestUrl = new URL(cacheKey.path, originUrl) + locationUrl = new URL(location, requestUrl) + } catch { + return undefined + } - this.req = new PipelineRequest().on('error', util.nop) + if (locationUrl.origin !== originUrl.origin) { + return undefined + } - this.ret = new Duplex({ - readableObjectMode: opts.objectMode, - autoDestroy: true, - read: () => { - const { body } = this + return locationUrl.pathname + locationUrl.search +} - if (body?.resume) { - body.resume() - } - }, - write: (chunk, encoding, callback) => { - const { req } = this +function deleteCachedUri (store, cacheKey, path) { + deleteCachedValue(store, { + ...cacheKey, + path + }) - if (req.push(chunk, encoding) || req._readableState.destroyed) { - callback() - } else { - req[kResume] = callback - } - }, - destroy: (err, callback) => { - const { body, req, res, ret, abort } = this + for (let i = 0; i < util.safeHTTPMethods.length; i++) { + const method = util.safeHTTPMethods[i] + if (method !== cacheKey.method) { + deleteCachedValue(store, { + ...cacheKey, + method, + path + }) + } + } +} - if (!err && !ret._readableState.endEmitted) { - err = new RequestAbortedError() - } +function deleteLocationTargets (store, cacheKey, headerValue) { + if (headerValue === undefined) { + return + } + + const values = Array.isArray(headerValue) ? headerValue : [headerValue] + for (let i = 0; i < values.length; i++) { + const path = getSameOriginPath(cacheKey, values[i]) + if (path !== undefined) { + deleteCachedUri(store, cacheKey, path) + } + } +} + +function invalidateUnsafeRequest (store, cacheKey, resHeaders) { + deleteCachedUri(store, cacheKey, cacheKey.path) + deleteLocationTargets(store, cacheKey, resHeaders.location) + deleteLocationTargets(store, cacheKey, resHeaders['content-location']) +} +/** + * @typedef {import('../../types/dispatcher.d.ts').default.DispatchHandler} DispatchHandler + * + * @implements {DispatchHandler} + */ +class CacheHandler { + /** + * @type {import('../../types/cache-interceptor.d.ts').default.CacheKey} + */ + #cacheKey + + /** + * @type {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions['type']} + */ + #cacheType - if (abort && err) { - abort() - } + /** + * @type {number | undefined} + */ + #cacheByDefault - util.destroy(body, err) - util.destroy(req, err) - util.destroy(res, err) + /** + * @type {import('../../types/cache-interceptor.d.ts').default.CacheStore} + */ + #store - removeSignal(this) + /** + * @type {import('../../types/dispatcher.d.ts').default.DispatchHandler} + */ + #handler - callback(err) - } - }).on('prefinish', () => { - const { req } = this + /** + * @type {CacheController | undefined} + */ + #downstreamController - // Node < 15 does not call _final in same tick. - req.push(null) - }) + /** + * @type {import('node:stream').Writable | undefined} + */ + #writeStream - this.res = null + /** + * The URLs visited while following redirects, shared by reference from the + * redirect handler through the request context. Carries the suppressed hops' + * cache-control under {@link kRedirectCacheControl}. + * @type {URL[] | undefined} + */ + #history - addSignal(this, signal) + /** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} opts + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey + * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler + */ + constructor ({ store, type, cacheByDefault }, cacheKey, handler) { + this.#store = store + this.#cacheType = type + this.#cacheByDefault = cacheByDefault + this.#cacheKey = cacheKey + this.#handler = handler } - onConnect (abort, context) { - const { ret, res } = this + onRequestStart (controller, context) { + this.#writeStream?.destroy() + this.#writeStream = undefined + this.#downstreamController = new CacheController(controller) + // The redirect handler threads the list of visited URLs through the + // handler-chain context. Keep a reference to it (it is mutated as redirects + // are followed) so onResponseStart can tell which request actually produced + // the response. Unlike the request options object, this reference is not + // broken by an interceptor that copies the options between the cache and + // the redirect. + this.#history = context?.history + this.#handler.onRequestStart?.(this.#downstreamController, context) + } - if (this.reason) { - abort(this.reason) - return - } + onBodySent (chunk) { + this.#handler.onBodySent?.(chunk) + } - assert(!res, 'pipeline cannot be retried') - assert(!ret.destroyed) + onRequestSent () { + this.#handler.onRequestSent?.() + } - this.abort = abort - this.context = context + onRequestUpgrade (_controller, statusCode, headers, socket) { + this.#handler.onRequestUpgrade?.(this.#downstreamController, statusCode, headers, socket) } - onHeaders (statusCode, rawHeaders, resume) { - const { opaque, handler, context } = this + /** + * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @param {number} statusCode + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders + * @param {string} statusMessage + */ + onResponseStart ( + controller, + statusCode, + resHeaders, + statusMessage + ) { + const downstreamOnHeaders = () => + this.#handler.onResponseStart?.( + this.#downstreamController, + statusCode, + resHeaders, + statusMessage + ) + const handler = this - if (statusCode < 200) { - if (this.onInfo) { - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - this.onInfo({ statusCode, headers }) + if ( + !arrayIncludes(util.safeHTTPMethods, this.#cacheKey.method) && + statusCode >= 200 && + statusCode <= 399 + ) { + // Successful response to an unsafe method, delete it from cache + // https://www.rfc-editor.org/rfc/rfc9111.html#name-invalidating-stored-response + invalidateUnsafeRequest(this.#store, this.#cacheKey, resHeaders) + return downstreamOnHeaders() + } + + // A cross-origin redirect can change the origin that actually produced the + // final response. Keying that response on the original (trusted) origin + // would let a redirect target control an entry for a URL the application + // trusts. The final request is the last URL in the redirect history; only + // cache when its origin still matches the cache key origin. + if (this.#history && this.#history.length > 0) { + const finalUrl = this.#history[this.#history.length - 1] + if (!sameOrigin(finalUrl.origin, this.#cacheKey.origin)) { + return downstreamOnHeaders() + } + } + + // A redirect hop that is not forwarded can still carry a restrictive + // storage policy (for example `no-store`, or `private` for a shared cache). + // Honor it, otherwise a redirect that must not be stored could be laundered + // into a cacheable final response under the original key. + const redirectCacheControl = this.#history?.[kRedirectCacheControl] + if (redirectCacheControl) { + for (const hopCacheControl of redirectCacheControl) { + const hopDirectives = hopCacheControl ? parseCacheControlHeader(hopCacheControl) : {} + if ( + hopDirectives['no-store'] === true || + (this.#cacheType === 'shared' && hopDirectives.private === true) + ) { + return downstreamOnHeaders() + } } - return } - this.res = new PipelineResponse(resume) + const cacheControlHeader = resHeaders['cache-control'] + const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {} - let body - try { - this.handler = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - body = this.runInAsyncScope(handler, null, { - statusCode, - headers, - opaque, - body: this.res, - context - }) - } catch (err) { - this.res.on('error', util.nop) - throw err + if (revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives)) { + deleteCachedValue(this.#store, this.#cacheKey) + return downstreamOnHeaders() } - if (!body || typeof body.on !== 'function') { - throw new InvalidReturnValueError('expected Readable') + const heuristicallyCacheable = resHeaders['last-modified'] && arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode) + if ( + !cacheControlHeader && + !resHeaders['expires'] && + !heuristicallyCacheable && + !this.#cacheByDefault + ) { + if (statusCode === 304 && resHeaders.vary && isInvalidOrWildcardVaryHeader(resHeaders.vary)) { + deleteCachedValue(this.#store, this.#cacheKey) + } + + // Don't have anything to tell us this response is cachable and we're not + // caching by default + return downstreamOnHeaders() } - body - .on('data', (chunk) => { - const { ret, body } = this + if (!canCacheResponse(this.#cacheType, this.#cacheKey.method, statusCode, resHeaders, cacheControlDirectives, this.#cacheKey.headers)) { + if (statusCode === 304 && (cacheControlHeader || revalidationResponseDisallowsCachedReuse(this.#cacheType, resHeaders, cacheControlDirectives))) { + deleteCachedValue(this.#store, this.#cacheKey) + } - if (!ret.push(chunk) && body.pause) { - body.pause() - } - }) - .on('error', (err) => { - const { ret } = this + return downstreamOnHeaders() + } - util.destroy(ret, err) - }) - .on('end', () => { - const { ret } = this + const now = Date.now() + const resAge = Object.hasOwn(resHeaders, 'age') ? getAge(resHeaders.age) : undefined + if (resAge !== undefined && resAge >= MAX_RESPONSE_AGE) { + // Response considered stale + deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey) + return downstreamOnHeaders() + } - ret.push(null) - }) - .on('close', () => { - const { ret } = this + const resDate = Object.hasOwn(resHeaders, 'date') ? getDate(resHeaders.date) : undefined + if (resDate === null) { + deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey) + return downstreamOnHeaders() + } - if (!ret._readableState.ended) { - util.destroy(ret, new RequestAbortedError()) - } - }) + const apparentAge = resDate ? Math.max(0, now - resDate.getTime()) : 0 + const currentAge = Math.max(apparentAge, resAge ?? 0) - this.body = body - } + const hasValidator = + (typeof resHeaders.etag === 'string' && isEtagUsable(resHeaders.etag)) || + typeof resHeaders['last-modified'] === 'string' - onData (chunk) { - const { res } = this - return res.push(chunk) - } + const staleAt = + determineStaleAt(this.#cacheType, now, resAge, resHeaders, resDate, cacheControlDirectives, hasValidator) ?? + this.#cacheByDefault + // Zero freshness lifetime but a validator: stale from the start, yet still + // storable since each reuse is preceded by a revalidation request. + // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.4 + const revalidationOnly = staleAt === 0 && hasValidator + if (staleAt === undefined || (currentAge >= staleAt && !revalidationOnly)) { + if (cacheControlHeader || staleAt !== undefined) { + deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey) + } - onComplete (trailers) { - const { res } = this - res.push(null) - } + return downstreamOnHeaders() + } - onError (err) { - const { ret } = this - this.handler = null - util.destroy(ret, err) - } -} + const baseTime = now - currentAge + const absoluteStaleAt = staleAt + baseTime + if (now >= absoluteStaleAt && !revalidationOnly) { + // Response is already stale + deleteCachedValueIfNotModified(statusCode, this.#store, this.#cacheKey) + return downstreamOnHeaders() + } -function pipeline (opts, handler) { - try { - const pipelineHandler = new PipelineHandler(opts, handler) - this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) - return pipelineHandler.ret - } catch (err) { - return new PassThrough().destroy(err) - } -} + let varyDirectives + if (this.#cacheKey.headers && resHeaders.vary) { + varyDirectives = parseVaryHeader(resHeaders.vary, this.#cacheKey.headers) + if (!varyDirectives) { + // Parse error + return downstreamOnHeaders() + } + } -module.exports = pipeline + const cachedAt = baseTime + const deleteAt = determineDeleteAt(baseTime, now, cacheControlDirectives, absoluteStaleAt) + const strippedHeaders = stripNecessaryHeaders(resHeaders, cacheControlDirectives) + /** + * @type {import('../../types/cache-interceptor.d.ts').default.CacheValue} + */ + const value = { + statusCode, + statusMessage, + headers: strippedHeaders, + vary: varyDirectives, + cacheControlDirectives, + cachedAt, + staleAt: absoluteStaleAt, + deleteAt + } + + // Not modified, re-use the cached value + // https://www.rfc-editor.org/rfc/rfc9111.html#name-handling-304-not-modified + if (statusCode === 304) { + let done = false + const finish304 = () => { + if (done) { + return + } + done = true + this.#downstreamController.release() + } -/***/ }), + const handle304 = (cachedValue) => { + if (!cachedValue) { + // Do not create a new cache entry, as a 304 won't have a body - so cannot be cached. + downstreamOnHeaders() + finish304() + return + } -/***/ 4043: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Re-use the cached value: statuscode, statusmessage, headers and body + value.statusCode = cachedValue.statusCode + value.statusMessage = cachedValue.statusMessage + value.etag = cachedValue.etag + value.vary = varyDirectives ?? cachedValue.vary + value.headers = { ...cachedValue.headers, ...strippedHeaders } -"use strict"; + downstreamOnHeaders() + this.#writeStream = this.#store.createWriteStream(this.#cacheKey, value) -const assert = __nccwpck_require__(4589) -const { Readable } = __nccwpck_require__(9927) -const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8707) -const util = __nccwpck_require__(3440) -const { getResolveErrorBodyCallback } = __nccwpck_require__(7655) -const { AsyncResource } = __nccwpck_require__(6698) + if (!this.#writeStream || !cachedValue?.body) { + finish304() + return + } -class RequestHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } + if (typeof cachedValue.body.values === 'function') { + const bodyIterator = cachedValue.body.values() - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts + const streamCachedBody = () => { + if (done) { + return + } + for (const chunk of bodyIterator) { + const full = this.#writeStream?.write(chunk) === false + this.#handler.onResponseData?.(this.#downstreamController, chunk) + // when stream is full stop writing until we get a 'drain' event + if (full) { + return + } + } + finish304() + } - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + this.#writeStream + .on('error', function () { + handler.#writeStream = undefined + handler.#store.delete(handler.#cacheKey) + // Keep replaying downstream without the store + streamCachedBody() + }) + .on('drain', () => { + streamCachedBody() + }) + .on('close', function () { + if (handler.#writeStream === this) { + handler.#writeStream = undefined + // Keep replaying downstream without the store + streamCachedBody() + } + }) - if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { - throw new InvalidArgumentError('invalid highWaterMark') - } + streamCachedBody() + } else if (typeof cachedValue.body.on === 'function') { + // Readable stream body (e.g. from async/remote cache stores) + cachedValue.body + .on('data', (chunk) => { + this.#writeStream?.write(chunk) + this.#handler.onResponseData?.(this.#downstreamController, chunk) + }) + .on('end', () => { + this.#writeStream?.end() + finish304() + }) + .on('error', () => { + this.#writeStream = undefined + this.#store.delete(this.#cacheKey) + finish304() + }) - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + this.#writeStream + .on('error', function () { + handler.#writeStream = undefined + handler.#store.delete(handler.#cacheKey) + }) + .on('close', function () { + if (handler.#writeStream === this) { + handler.#writeStream = undefined + } + }) + } else { + finish304() + } } - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') + /** + * @type {import('../../types/cache-interceptor.d.ts').default.CacheValue} + */ + const result = this.#store.get(this.#cacheKey) + // A 304 ends before the cached body is replayed. Keep the origin + // response paused until replay is complete. + this.#downstreamController.block() + controller.pause() + if (result && typeof result.then === 'function') { + result.then(handle304, () => handle304(undefined)).catch((err) => { + controller.abort(err) + }) + } else { + handle304(result) } - - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') + } else { + if (typeof resHeaders.etag === 'string' && isEtagUsable(resHeaders.etag)) { + value.etag = resHeaders.etag } - super('UNDICI_REQUEST') - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err) - } - throw err - } + this.#writeStream = this.#store.createWriteStream(this.#cacheKey, value) - this.method = method - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.callback = callback - this.res = null - this.abort = null - this.body = body - this.trailers = {} - this.context = null - this.onInfo = onInfo || null - this.throwOnError = throwOnError - this.highWaterMark = highWaterMark - this.signal = signal - this.reason = null - this.removeAbortListener = null + if (!this.#writeStream) { + return downstreamOnHeaders() + } - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err) - }) - } + this.#writeStream + .on('drain', () => controller.resume()) + .on('error', function () { + // TODO (fix): Make error somehow observable? + handler.#writeStream = undefined - if (this.signal) { - if (this.signal.aborted) { - this.reason = this.signal.reason ?? new RequestAbortedError() - } else { - this.removeAbortListener = util.addAbortListener(this.signal, () => { - this.reason = this.signal.reason ?? new RequestAbortedError() - if (this.res) { - util.destroy(this.res.on('error', util.nop), this.reason) - } else if (this.abort) { - this.abort(this.reason) + // Delete the value in case the cache store is holding onto state from + // the call to createWriteStream + handler.#store.delete(handler.#cacheKey) + }) + .on('close', function () { + if (handler.#writeStream === this) { + handler.#writeStream = undefined } - if (this.removeAbortListener) { - this.res?.off('close', this.removeAbortListener) - this.removeAbortListener() - this.removeAbortListener = null - } + // TODO (fix): Should we resume even if was paused downstream? + controller.resume() }) - } + + downstreamOnHeaders() } } - onConnect (abort, context) { - if (this.reason) { - abort(this.reason) - return - } - - assert(this.callback) - - this.abort = abort - this.context = context + onResponseData (controller, chunk) { + if (this.#writeStream?.write(chunk) === false) { + controller.pause() + } + + this.#handler.onResponseData?.(this.#downstreamController, chunk) + } + + onResponseEnd (controller, trailers) { + this.#writeStream?.end() + this.#handler.onResponseEnd?.(this.#downstreamController, trailers) + } + + onResponseError (controller, err) { + this.#writeStream?.destroy(err) + this.#writeStream = undefined + this.#handler.onResponseError?.(this.#downstreamController, err) + } +} + +/** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheStore} store + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey + */ +function deleteCachedValue (store, cacheKey) { + try { + store.delete(cacheKey)?.catch?.(noop) + } catch { + // Fail silently + } +} + +function deleteCachedValueIfNotModified (statusCode, store, cacheKey) { + if (statusCode === 304) { + deleteCachedValue(store, cacheKey) + } +} + +/** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives + * @returns {boolean} + */ +function revalidationResponseDisallowsCachedReuse (cacheType, resHeaders, cacheControlDirectives) { + return cacheControlDirectives['no-store'] === true || + (cacheType === 'shared' && ( + cacheControlDirectives.private === true || + Object.hasOwn(resHeaders, 'set-cookie') + )) || + (resHeaders.vary ? isInvalidOrWildcardVaryHeader(resHeaders.vary) : false) +} + +/** + * @see https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen + * + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType + * @param {string} method + * @param {number} statusCode + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} [reqHeaders] + */ +function canCacheResponse (cacheType, method, statusCode, resHeaders, cacheControlDirectives, reqHeaders) { + if (!arrayIncludes(util.safeHTTPMethods, method)) { + return false + } + // Status code must be final and understood. + if (statusCode < 200 || arrayIncludes(NOT_UNDERSTOOD_STATUS_CODES, statusCode)) { + return false + } + // Responses with neither status codes that are heuristically cacheable, nor "explicit enough" caching + // directives, are not cacheable. "Explicit enough": see https://www.rfc-editor.org/rfc/rfc9111.html#section-3 + if (!arrayIncludes(HEURISTICALLY_CACHEABLE_STATUS_CODES, statusCode) && !resHeaders['expires'] && + !cacheControlDirectives.public && + cacheControlDirectives['max-age'] === undefined && + // RFC 9111: a private response directive, if the cache is not shared + !(cacheControlDirectives.private && cacheType === 'private') && + !(cacheControlDirectives['s-maxage'] !== undefined && cacheType === 'shared') + ) { + return false + } + + if (cacheControlDirectives['no-store']) { + return false } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this + if (cacheType === 'shared' && ( + cacheControlDirectives.private === true || + Object.hasOwn(resHeaders, 'set-cookie') + )) { + return false + } - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + // https://www.rfc-editor.org/rfc/rfc9111.html#section-4.1-5 + if (resHeaders.vary && hasVaryStar(resHeaders.vary)) { + return false + } - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }) - } - return + // https://www.rfc-editor.org/rfc/rfc9111.html#name-storing-responses-to-authen + if (reqHeaders != null && Object.hasOwn(reqHeaders, 'authorization')) { + if ( + !cacheControlDirectives.public && + !cacheControlDirectives['s-maxage'] && + !cacheControlDirectives['must-revalidate'] + ) { + return false } - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers - const contentType = parsedHeaders['content-type'] - const contentLength = parsedHeaders['content-length'] - const res = new Readable({ - resume, - abort, - contentType, - contentLength: this.method !== 'HEAD' && contentLength - ? Number(contentLength) - : null, - highWaterMark - }) + if (typeof reqHeaders.authorization !== 'string') { + return false + } - if (this.removeAbortListener) { - res.on('close', this.removeAbortListener) + if ( + Array.isArray(cacheControlDirectives['no-cache']) && + arrayIncludes(cacheControlDirectives['no-cache'], 'authorization') + ) { + return false } - this.callback = null - this.res = res - if (callback !== null) { - if (this.throwOnError && statusCode >= 400) { - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body: res, contentType, statusCode, statusMessage, headers } - ) - } else { - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - trailers: this.trailers, - opaque, - body: res, - context - }) - } + if ( + Array.isArray(cacheControlDirectives['private']) && + arrayIncludes(cacheControlDirectives['private'], 'authorization') + ) { + return false } } - onData (chunk) { - return this.res.push(chunk) - } + return true +} - onComplete (trailers) { - util.parseHeaders(trailers, this.trailers) - this.res.push(null) - } +/** + * @param {string | string[]} dateHeader + * @returns {Date | null | undefined} + */ +function getDate (dateHeader) { + let dateValue = dateHeader + if (Array.isArray(dateValue)) { + if (dateValue.length !== 1) { + return null + } - onError (err) { - const { res, callback, body, opaque } = this + dateValue = dateValue[0] + } - if (callback) { - // TODO: Does this need queueMicrotask? - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } + if (typeof dateValue !== 'string') { + return null + } - if (res) { - this.res = null - // Ensure all queued handlers are invoked before destroying res. - queueMicrotask(() => { - util.destroy(res, err) - }) - } + return parseHttpDate(dateValue) +} - if (body) { - this.body = null - util.destroy(body, err) +/** + * @param {string | string[]} ageHeader + * @returns {number | undefined} + */ +function getAge (ageHeader) { + let ageValue = ageHeader + if (Array.isArray(ageValue)) { + if (ageValue.length !== 1) { + return MAX_RESPONSE_AGE } - if (this.removeAbortListener) { - res?.off('close', this.removeAbortListener) - this.removeAbortListener() - this.removeAbortListener = null - } + ageValue = ageValue[0] } -} -function request (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - request.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + if (typeof ageValue !== 'string' || !/^[\t ]*[0-9]+[\t ]*$/.test(ageValue)) { + return MAX_RESPONSE_AGE } - try { - this.dispatch(opts, new RequestHandler(opts, callback)) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts?.opaque - queueMicrotask(() => callback(err, { opaque })) + const age = BigInt(ageValue.replace(/^[\t ]+|[\t ]+$/g, '')) + if (age >= BigInt(MAX_RESPONSE_AGE / 1000)) { + return MAX_RESPONSE_AGE } + + return Number(age) * 1000 } -module.exports = request -module.exports.RequestHandler = RequestHandler +/** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType + * @param {number} now + * @param {number | undefined} age + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders + * @param {Date | undefined} responseDate + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives + * @param {boolean} hasValidator whether the response has a validator (etag or + * last-modified) that revalidation requests can be made with + * + * @returns {number | undefined} time that the value is stale at in seconds or undefined if it shouldn't be cached + */ +function determineStaleAt (cacheType, now, age, resHeaders, responseDate, cacheControlDirectives, hasValidator) { + if (cacheType === 'shared') { + // Prioritize s-maxage since we're a shared cache + // s-maxage > max-age > Expire + // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.10-3 + if (hasInvalidCacheControlDirective(cacheControlDirectives, 's-maxage')) { + return 0 + } + const sMaxAge = cacheControlDirectives['s-maxage'] + if (sMaxAge !== undefined) { + if (sMaxAge > 0) { + return sMaxAge * 1000 + } -/***/ }), + // Immediately stale, but storable if we can revalidate it before reuse. + return 0 + } + } -/***/ 3560: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (hasInvalidCacheControlDirective(cacheControlDirectives, 'max-age')) { + return 0 + } -"use strict"; + const maxAge = cacheControlDirectives['max-age'] + if (maxAge !== undefined) { + if (maxAge > 0) { + return maxAge * 1000 + } + // Immediately stale, but storable if we can revalidate it before reuse. + return 0 + } -const assert = __nccwpck_require__(4589) -const { finished, PassThrough } = __nccwpck_require__(7075) -const { InvalidArgumentError, InvalidReturnValueError } = __nccwpck_require__(8707) -const util = __nccwpck_require__(3440) -const { getResolveErrorBodyCallback } = __nccwpck_require__(7655) -const { AsyncResource } = __nccwpck_require__(6698) -const { addSignal, removeSignal } = __nccwpck_require__(158) + if (Object.hasOwn(resHeaders, 'expires')) { + // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.3 + if (typeof resHeaders.expires !== 'string') { + return 0 + } -class StreamHandler extends AsyncResource { - constructor (opts, factory, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') + const expiresDate = parseHttpDate(resHeaders.expires) + if (!expiresDate) { + return 0 } - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts + if (now >= expiresDate.getTime()) { + return 0 + } - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') + if (responseDate) { + if (responseDate >= expiresDate) { + return 0 } - if (typeof factory !== 'function') { - throw new InvalidArgumentError('invalid factory') + const freshnessLifetime = expiresDate.getTime() - responseDate.getTime() + if (age !== undefined && age >= freshnessLifetime) { + return 0 } - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + return freshnessLifetime + } - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } + return expiresDate.getTime() - now + } - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') + if (typeof resHeaders['last-modified'] === 'string') { + // https://www.rfc-editor.org/rfc/rfc9111.html#name-calculating-heuristic-fresh + const lastModified = parseHttpDate(resHeaders['last-modified']) + if (lastModified) { + if (lastModified.getTime() >= now) { + return undefined } - super('UNDICI_STREAM') - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err) - } - throw err + const responseAge = now - lastModified.getTime() + + return responseAge * 0.1 } + } - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.factory = factory - this.callback = callback - this.res = null - this.abort = null - this.context = null - this.trailers = null - this.body = body - this.onInfo = onInfo || null - this.throwOnError = throwOnError || false + if (cacheControlDirectives.immutable) { + // https://www.rfc-editor.org/rfc/rfc8246.html#section-2.2 + return 31536000000 + } - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err) - }) - } + if (cacheControlDirectives['no-cache'] === true && hasValidator) { + // No freshness source, but a validator lets us revalidate before reuse. + // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.4 + return 0 + } - addSignal(this, signal) + return undefined +} + +/** + * @param {number} baseTime + * @param {number} cachedAt + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives + * @param {number} staleAt + */ +function determineDeleteAt (baseTime, cachedAt, cacheControlDirectives, staleAt) { + let staleWhileRevalidate = -Infinity + let staleIfError = -Infinity + let immutable = -Infinity + + if (cacheControlDirectives['stale-while-revalidate']) { + staleWhileRevalidate = staleAt + (cacheControlDirectives['stale-while-revalidate'] * 1000) } - onConnect (abort, context) { - if (this.reason) { - abort(this.reason) - return + if (cacheControlDirectives['stale-if-error']) { + staleIfError = staleAt + (cacheControlDirectives['stale-if-error'] * 1000) + } + + if (cacheControlDirectives.immutable && staleWhileRevalidate === -Infinity && staleIfError === -Infinity) { + immutable = cachedAt + 31536000000 + } + + // When no stale directives or immutable flag, add a revalidation buffer + // equal to the freshness lifetime so the entry survives past staleAt long + // enough to be revalidated instead of silently disappearing. + // + // Response Date headers only have second precision, so baseTime can trail the + // actual cache insertion time by up to ~1s. Pad the buffer by that bounded + // skew so short-lived entries do not disappear exactly when they should be + // revalidated. + if (staleWhileRevalidate === -Infinity && staleIfError === -Infinity && immutable === -Infinity) { + const freshnessLifetime = staleAt - baseTime + if (freshnessLifetime <= 0) { + // Revalidation-only entry: no freshness lifetime to size the buffer on, + // so retain it for a bounded window instead. + return cachedAt + REVALIDATION_ONLY_RETENTION } + const datePrecisionPadding = Math.min(Math.max(cachedAt - baseTime, 0), 1000) + return staleAt + freshnessLifetime + datePrecisionPadding + } - assert(this.callback) + return Math.max(staleAt, staleWhileRevalidate, staleIfError, immutable) +} - this.abort = abort - this.context = context +/** + * Strips headers required to be removed in cached responses + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} resHeaders + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} cacheControlDirectives + * @returns {Record} + */ +function stripNecessaryHeaders (resHeaders, cacheControlDirectives) { + const headersToRemove = [ + 'connection', + 'proxy-authenticate', + 'proxy-authentication-info', + 'proxy-authorization', + 'proxy-connection', + 'te', + 'transfer-encoding', + 'upgrade', + // We'll add age back when serving it + 'age' + ] + + if (resHeaders['connection']) { + appendConnectionHeaderTokens(headersToRemove, resHeaders['connection']) } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { factory, opaque, context, callback, responseHeaders } = this + if (Array.isArray(cacheControlDirectives['no-cache'])) { + headersToRemove.push(...cacheControlDirectives['no-cache']) + } - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + if (Array.isArray(cacheControlDirectives['private'])) { + headersToRemove.push(...cacheControlDirectives['private']) + } - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }) - } - return + let strippedHeaders + for (const headerName of headersToRemove) { + if (Object.hasOwn(resHeaders, headerName)) { + strippedHeaders ??= { ...resHeaders } + delete strippedHeaders[headerName] } + } - this.factory = null + return strippedHeaders ?? resHeaders +} - let res +module.exports = CacheHandler - if (this.throwOnError && statusCode >= 400) { - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers - const contentType = parsedHeaders['content-type'] - res = new PassThrough() - this.callback = null - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body: res, contentType, statusCode, statusMessage, headers } - ) - } else { - if (factory === null) { - return - } +/***/ }), - res = this.runInAsyncScope(factory, null, { - statusCode, - headers, - opaque, - context - }) +/***/ 7133: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if ( - !res || - typeof res.write !== 'function' || - typeof res.end !== 'function' || - typeof res.on !== 'function' - ) { - throw new InvalidReturnValueError('expected Writable') - } +"use strict"; - // TODO: Avoid finished. It registers an unnecessary amount of listeners. - finished(res, { readable: false }, (err) => { - const { callback, res, opaque, trailers, abort } = this - this.res = null - if (err || !res.readable) { - util.destroy(res, err) - } +const assert = __nccwpck_require__(4589) - this.callback = null - this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) +/** + * This takes care of revalidation requests we send to the origin. If we get + * a response indicating that what we have is cached (via a HTTP 304), we can + * continue using the cached value. Otherwise, we'll receive the new response + * here, which we then just pass on to the next handler (most likely a + * CacheHandler). Note that this assumes the proper headers were already + * included in the request to tell the origin that we want to revalidate the + * response (i.e. if-modified-since or if-none-match). + * + * @see https://www.rfc-editor.org/rfc/rfc9111.html#name-validation + * + * @implements {import('../../types/dispatcher.d.ts').default.DispatchHandler} + */ +class CacheRevalidationHandler { + #successful = false - if (err) { - abort() - } - }) - } + /** + * @type {((success: boolean, context?: any, statusCode?: number, headers?: import('../../types/header.d.ts').IncomingHttpHeaders) => void) | null} + */ + #callback - res.on('drain', resume) + /** + * @type {(import('../../types/dispatcher.d.ts').default.DispatchHandler)} + */ + #handler - this.res = res + #context - const needDrain = res.writableNeedDrain !== undefined - ? res.writableNeedDrain - : res._writableState?.needDrain + /** + * @type {boolean} + */ + #allowErrorStatusCodes + + /** + * @param {(success: boolean, context?: any, statusCode?: number, headers?: import('../../types/header.d.ts').IncomingHttpHeaders) => void} callback Function to call if the cached value is valid + * @param {import('../../types/dispatcher.d.ts').default.DispatchHandlers} handler + * @param {boolean} allowErrorStatusCodes + */ + constructor (callback, handler, allowErrorStatusCodes) { + if (typeof callback !== 'function') { + throw new TypeError('callback must be a function') + } - return needDrain !== true + this.#callback = callback + this.#handler = handler + this.#allowErrorStatusCodes = allowErrorStatusCodes } - onData (chunk) { - const { res } = this + onRequestStart (_, context) { + this.#successful = false + this.#context = context + } - return res ? res.write(chunk) : true + onRequestUpgrade (controller, statusCode, headers, socket) { + this.#handler.onRequestUpgrade?.(controller, statusCode, headers, socket) } - onComplete (trailers) { - const { res } = this + onResponseStart ( + controller, + statusCode, + headers, + statusMessage + ) { + assert(this.#callback != null) - removeSignal(this) + // https://www.rfc-editor.org/rfc/rfc9111.html#name-handling-a-validation-respo + // https://datatracker.ietf.org/doc/html/rfc5861#section-4 + this.#successful = statusCode === 304 || + (this.#allowErrorStatusCodes && statusCode >= 500 && statusCode <= 504) + this.#callback(this.#successful, this.#context, statusCode, headers) + this.#callback = null - if (!res) { - return + if (this.#successful) { + return true } - this.trailers = util.parseHeaders(trailers) - - res.end() + this.#handler.onRequestStart?.(controller, this.#context) + this.#handler.onResponseStart?.( + controller, + statusCode, + headers, + statusMessage + ) } - onError (err) { - const { res, callback, opaque, body } = this - - removeSignal(this) + onResponseData (controller, chunk) { + if (this.#successful) { + return + } - this.factory = null + return this.#handler.onResponseData?.(controller, chunk) + } - if (res) { - this.res = null - util.destroy(res, err) - } else if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) + onResponseEnd (controller, trailers) { + if (this.#successful) { + return } - if (body) { - this.body = null - util.destroy(body, err) - } + this.#handler.onResponseEnd?.(controller, trailers) } -} -function stream (opts, factory, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - stream.call(this, opts, factory, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) - } + onResponseError (controller, err) { + if (this.#successful) { + return + } - try { - this.dispatch(opts, new StreamHandler(opts, factory, callback)) - } catch (err) { - if (typeof callback !== 'function') { + if (this.#callback) { + // Serve the stale cached response on a connection error, per stale-if-error: + // RFC 5861 counts an unreachable origin (a would-be 5xx) as an error. + // https://datatracker.ietf.org/doc/html/rfc5861#section-4 + if (this.#allowErrorStatusCodes) { + this.#successful = true + this.#callback(true, this.#context) + this.#callback = null + return + } + + this.#callback(false) + this.#callback = null + } + + if (typeof this.#handler.onResponseError === 'function') { + this.#handler.onResponseError(controller, err) + } else { throw err } - const opaque = opts?.opaque - queueMicrotask(() => callback(err, { opaque })) } } -module.exports = stream +module.exports = CacheRevalidationHandler /***/ }), -/***/ 1882: +/***/ 8155: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { InvalidArgumentError, SocketError } = __nccwpck_require__(8707) -const { AsyncResource } = __nccwpck_require__(6698) -const util = __nccwpck_require__(3440) -const { addSignal, removeSignal } = __nccwpck_require__(158) const assert = __nccwpck_require__(4589) -class UpgradeHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - - const { signal, opaque, responseHeaders } = opts +/** + * @deprecated + */ +module.exports = class DecoratorHandler { + #handler + #onCompleteCalled = false + #onErrorCalled = false + #onResponseStartCalled = false - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + constructor (handler) { + if (typeof handler !== 'object' || handler === null) { + throw new TypeError('handler must be an object') } - - super('UNDICI_UPGRADE') - - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.callback = callback - this.abort = null - this.context = null - - addSignal(this, signal) + this.#handler = handler } - onConnect (abort, context) { - if (this.reason) { - abort(this.reason) - return - } + onRequestStart (...args) { + this.#handler.onRequestStart?.(...args) + } - assert(this.callback) + onRequestUpgrade (...args) { + assert(!this.#onCompleteCalled) + assert(!this.#onErrorCalled) - this.abort = abort - this.context = null + return this.#handler.onRequestUpgrade?.(...args) } - onHeaders () { - throw new SocketError('bad upgrade', null) - } + onResponseStart (...args) { + assert(!this.#onCompleteCalled) + assert(!this.#onErrorCalled) + assert(!this.#onResponseStartCalled) - onUpgrade (statusCode, rawHeaders, socket) { - assert(statusCode === 101) + this.#onResponseStartCalled = true - const { callback, opaque, context } = this + return this.#handler.onResponseStart?.(...args) + } - removeSignal(this) + onResponseData (...args) { + assert(!this.#onCompleteCalled) + assert(!this.#onErrorCalled) - this.callback = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - this.runInAsyncScope(callback, null, null, { - headers, - socket, - opaque, - context - }) + return this.#handler.onResponseData?.(...args) } - onError (err) { - const { callback, opaque } = this + onResponseEnd (...args) { + assert(!this.#onCompleteCalled) + assert(!this.#onErrorCalled) - removeSignal(this) + this.#onCompleteCalled = true + return this.#handler.onResponseEnd?.(...args) + } - if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } + onResponseError (...args) { + this.#onErrorCalled = true + return this.#handler.onResponseError?.(...args) } -} -function upgrade (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - upgrade.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + /** + * @deprecated + */ + onBodySent (...args) { + return this.#handler.onBodySent?.(...args) } - try { - const upgradeHandler = new UpgradeHandler(opts, callback) - this.dispatch({ - ...opts, - method: opts.method || 'GET', - upgrade: opts.protocol || 'Websocket' - }, upgradeHandler) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts?.opaque - queueMicrotask(() => callback(err, { opaque })) + onRequestSent (...args) { + return this.#handler.onRequestSent?.(...args) } } -module.exports = upgrade - /***/ }), -/***/ 6615: +/***/ 3599: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports.request = __nccwpck_require__(4043) -module.exports.stream = __nccwpck_require__(3560) -module.exports.pipeline = __nccwpck_require__(6862) -module.exports.upgrade = __nccwpck_require__(1882) -module.exports.connect = __nccwpck_require__(2279) +const { RequestAbortedError } = __nccwpck_require__(8707) +/** + * @typedef {import('../../types/dispatcher.d.ts').default.DispatchHandler} DispatchHandler + */ -/***/ }), +const DEFAULT_MAX_BUFFER_SIZE = 5 * 1024 * 1024 -/***/ 9927: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** + * @typedef {Object} WaitingHandler + * @property {DispatchHandler} handler + * @property {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @property {Buffer[]} bufferedChunks + * @property {number} bufferedBytes + * @property {object | null} pendingTrailers + * @property {boolean} done + * @property {boolean} [pendingStart] onRequestStart deferred until the primary request's context is known + */ -"use strict"; -// Ported from https://github.com/nodejs/undici/pull/907 +/** + * Handler that forwards response events to multiple waiting handlers. + * Used for request deduplication. + * + * @implements {DispatchHandler} + */ +class DeduplicationHandler { + /** + * @type {DispatchHandler} + */ + #primaryHandler + /** + * Whether the primary request has started (onRequestStart received). Until + * then the request context is unknown and cannot be given to waiting handlers. + * @type {boolean} + */ + #requestStarted = false + /** + * The primary request context, replayed to waiting handlers so they observe + * the same redirect history as the primary. + * @type {any} + */ + #context = null -const assert = __nccwpck_require__(4589) -const { Readable } = __nccwpck_require__(7075) -const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = __nccwpck_require__(8707) -const util = __nccwpck_require__(3440) -const { ReadableStreamFrom } = __nccwpck_require__(3440) + /** + * @type {WaitingHandler[]} + */ + #waitingHandlers = [] -const kConsume = Symbol('kConsume') -const kReading = Symbol('kReading') -const kBody = Symbol('kBody') -const kAbort = Symbol('kAbort') -const kContentType = Symbol('kContentType') -const kContentLength = Symbol('kContentLength') + /** + * @type {number} + */ + #maxBufferSize = DEFAULT_MAX_BUFFER_SIZE -const noop = () => {} + /** + * @type {number} + */ + #statusCode = 0 -class BodyReadable extends Readable { - constructor ({ - resume, - abort, - contentType = '', - contentLength, - highWaterMark = 64 * 1024 // Same as nodejs fs streams. - }) { - super({ - autoDestroy: true, - read: resume, - highWaterMark - }) + /** + * @type {Record} + */ + #headers = {} - this._readableState.dataEmitted = false + /** + * @type {string} + */ + #statusMessage = '' - this[kAbort] = abort - this[kConsume] = null - this[kBody] = null - this[kContentType] = contentType - this[kContentLength] = contentLength + /** + * @type {boolean} + */ + #aborted = false - // Is stream being consumed through Readable API? - // This is an optimization so that we avoid checking - // for 'data' and 'readable' listeners in the hot path - // inside push(). - this[kReading] = false - } + /** + * @type {boolean} + */ + #responseStarted = false - destroy (err) { - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError() - } + /** + * @type {boolean} + */ + #responseDataStarted = false - if (err) { - this[kAbort]() - } + /** + * @type {boolean} + */ + #completed = false - return super.destroy(err) - } + /** + * @type {import('../../types/dispatcher.d.ts').default.DispatchController | null} + */ + #controller = null - _destroy (err, callback) { - // Workaround for Node "bug". If the stream is destroyed in same - // tick as it is created, then a user who is waiting for a - // promise (i.e micro tick) for installing a 'error' listener will - // never get a chance and will always encounter an unhandled exception. - if (!this[kReading]) { - setImmediate(() => { - callback(err) - }) - } else { - callback(err) - } + /** + * @type {(() => void) | null} + */ + #onComplete = null + + /** + * @param {DispatchHandler} primaryHandler The primary handler + * @param {() => void} onComplete Callback when request completes + * @param {number} [maxBufferSize] Maximum paused buffer size per waiting handler + */ + constructor (primaryHandler, onComplete, maxBufferSize = DEFAULT_MAX_BUFFER_SIZE) { + this.#primaryHandler = primaryHandler + this.#onComplete = onComplete + this.#maxBufferSize = maxBufferSize } - on (ev, ...args) { - if (ev === 'data' || ev === 'readable') { - this[kReading] = true + /** + * Add a waiting handler that will receive response events. + * Returns false if deduplication can no longer safely attach this handler. + * + * @param {DispatchHandler} handler + * @returns {boolean} + */ + addWaitingHandler (handler) { + if (this.#completed || this.#responseDataStarted) { + return false } - return super.on(ev, ...args) - } - addListener (ev, ...args) { - return this.on(ev, ...args) - } + const waitingHandler = this.#createWaitingHandler(handler) + const waitingController = waitingHandler.controller - off (ev, ...args) { - const ret = super.off(ev, ...args) - if (ev === 'data' || ev === 'readable') { - this[kReading] = ( - this.listenerCount('data') > 0 || - this.listenerCount('readable') > 0 - ) - } - return ret - } + try { + if (this.#requestStarted) { + // The primary request has started, so its context (including the + // redirect history) is known and can be delivered immediately. + handler.onRequestStart?.(waitingController, this.#context) - removeListener (ev, ...args) { - return this.off(ev, ...args) - } + if (waitingController.aborted) { + waitingHandler.done = true + return true + } - push (chunk) { - if (this[kConsume] && chunk !== null) { - consumePush(this[kConsume], chunk) - return this[kReading] ? super.push(chunk) : true + if (this.#responseStarted) { + handler.onResponseStart?.( + waitingController, + this.#statusCode, + this.#headers, + this.#statusMessage + ) + } + } else { + // The primary request has not started yet. Defer onRequestStart until + // its context is known, so the waiting handler observes the same + // redirect history as the primary (a cache handler relies on it to + // reject cross-origin redirect responses). + waitingHandler.pendingStart = true + } + } catch { + // Ignore errors from waiting handlers + waitingHandler.done = true + return true } - return super.push(chunk) - } - // https://fetch.spec.whatwg.org/#dom-body-text - async text () { - return consume(this, 'text') - } + if (!waitingController.aborted) { + this.#waitingHandlers.push(waitingHandler) + } - // https://fetch.spec.whatwg.org/#dom-body-json - async json () { - return consume(this, 'json') + return true } - // https://fetch.spec.whatwg.org/#dom-body-blob - async blob () { - return consume(this, 'blob') + /** + * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @param {any} context + */ + onRequestStart (controller, context) { + this.#controller = controller + if (!this.#requestStarted) { + this.#requestStarted = true + this.#context = context + // Deliver the now-known context to handlers that joined before the + // primary request started. + for (const waitingHandler of this.#waitingHandlers) { + if (waitingHandler.pendingStart && !waitingHandler.done && !waitingHandler.controller.aborted) { + waitingHandler.pendingStart = false + try { + waitingHandler.handler.onRequestStart?.(waitingHandler.controller, context) + } catch { + // Ignore errors from waiting handlers + waitingHandler.done = true + } + } + } + this.#pruneDoneWaitingHandlers() + } + this.#primaryHandler.onRequestStart?.(controller, context) } - // https://fetch.spec.whatwg.org/#dom-body-bytes - async bytes () { - return consume(this, 'bytes') + /** + * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @param {number} statusCode + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} headers + * @param {Socket} socket + */ + onRequestUpgrade (controller, statusCode, headers, socket) { + this.#primaryHandler.onRequestUpgrade?.(controller, statusCode, headers, socket) } - // https://fetch.spec.whatwg.org/#dom-body-arraybuffer - async arrayBuffer () { - return consume(this, 'arrayBuffer') - } + /** + * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @param {number} statusCode + * @param {Record} headers + * @param {string} statusMessage + */ + onResponseStart (controller, statusCode, headers, statusMessage) { + this.#responseStarted = true + this.#statusCode = statusCode + this.#headers = headers + this.#statusMessage = statusMessage - // https://fetch.spec.whatwg.org/#dom-body-formdata - async formData () { - // TODO: Implement. - throw new NotSupportedError() - } + this.#primaryHandler.onResponseStart?.(controller, statusCode, headers, statusMessage) - // https://fetch.spec.whatwg.org/#dom-body-bodyused - get bodyUsed () { - return util.isDisturbed(this) - } + for (const waitingHandler of this.#waitingHandlers) { + const { handler, controller: waitingController } = waitingHandler - // https://fetch.spec.whatwg.org/#dom-body-body - get body () { - if (!this[kBody]) { - this[kBody] = ReadableStreamFrom(this) - if (this[kConsume]) { - // TODO: Is this the best way to force a lock? - this[kBody].getReader() // Ensure stream is locked. - assert(this[kBody].locked) + if (waitingHandler.done || waitingController.aborted) { + waitingHandler.done = true + continue } - } - return this[kBody] - } - async dump (opts) { - let limit = Number.isFinite(opts?.limit) ? opts.limit : 128 * 1024 - const signal = opts?.signal + try { + handler.onResponseStart?.( + waitingController, + statusCode, + headers, + statusMessage + ) + } catch { + // Ignore errors from waiting handlers + } - if (signal != null && (typeof signal !== 'object' || !('aborted' in signal))) { - throw new InvalidArgumentError('signal must be an AbortSignal') + if (waitingController.aborted) { + waitingHandler.done = true + } } - signal?.throwIfAborted() + this.#pruneDoneWaitingHandlers() + } - if (this._readableState.closeEmitted) { - return null + /** + * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @param {Buffer} chunk + */ + onResponseData (controller, chunk) { + if (this.#aborted || this.#completed) { + return } - return await new Promise((resolve, reject) => { - if (this[kContentLength] > limit) { - this.destroy(new AbortError()) - } - - const onAbort = () => { - this.destroy(signal.reason ?? new AbortError()) - } - signal?.addEventListener('abort', onAbort) - - this - .on('close', function () { - signal?.removeEventListener('abort', onAbort) - if (signal?.aborted) { - reject(signal.reason ?? new AbortError()) - } else { - resolve(null) - } - }) - .on('error', noop) - .on('data', function (chunk) { - limit -= chunk.length - if (limit <= 0) { - this.destroy() - } - }) - .resume() - }) - } -} + this.#responseDataStarted = true -// https://streams.spec.whatwg.org/#readablestream-locked -function isLocked (self) { - // Consume is an implicit lock. - return (self[kBody] && self[kBody].locked === true) || self[kConsume] -} + this.#primaryHandler.onResponseData?.(controller, chunk) -// https://fetch.spec.whatwg.org/#body-unusable -function isUnusable (self) { - return util.isDisturbed(self) || isLocked(self) -} + for (const waitingHandler of this.#waitingHandlers) { + const { handler, controller: waitingController } = waitingHandler -async function consume (stream, type) { - assert(!stream[kConsume]) + if (waitingHandler.done || waitingController.aborted) { + waitingHandler.done = true + continue + } - return new Promise((resolve, reject) => { - if (isUnusable(stream)) { - const rState = stream._readableState - if (rState.destroyed && rState.closeEmitted === false) { - stream - .on('error', err => { - reject(err) - }) - .on('close', () => { - reject(new TypeError('unusable')) - }) - } else { - reject(rState.errored ?? new TypeError('unusable')) + if (waitingController.paused) { + this.#bufferWaitingChunk(waitingHandler, chunk) + continue } - } else { - queueMicrotask(() => { - stream[kConsume] = { - type, - stream, - resolve, - reject, - length: 0, - body: [] - } - stream - .on('error', function (err) { - consumeFinish(this[kConsume], err) - }) - .on('close', function () { - if (this[kConsume].body !== null) { - consumeFinish(this[kConsume], new RequestAbortedError()) - } - }) + try { + handler.onResponseData?.(waitingController, chunk) + } catch { + // Ignore errors from waiting handlers + } - consumeStart(stream[kConsume]) - }) + if (waitingController.aborted) { + waitingHandler.done = true + waitingHandler.bufferedChunks = [] + waitingHandler.bufferedBytes = 0 + } } - }) -} -function consumeStart (consume) { - if (consume.body === null) { - return + this.#pruneDoneWaitingHandlers() } - const { _readableState: state } = consume.stream - - if (state.bufferIndex) { - const start = state.bufferIndex - const end = state.buffer.length - for (let n = start; n < end; n++) { - consumePush(consume, state.buffer[n]) - } - } else { - for (const chunk of state.buffer) { - consumePush(consume, chunk) + /** + * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @param {object} trailers + */ + onResponseEnd (controller, trailers) { + if (this.#aborted || this.#completed) { + return } - } - if (state.endEmitted) { - consumeEnd(this[kConsume]) - } else { - consume.stream.on('end', function () { - consumeEnd(this[kConsume]) - }) - } + this.#completed = true + // Remove the completed request before callbacks can redispatch into this + // interceptor. Cleanup must not depend on downstream handlers succeeding. + this.#cleanup() - consume.stream.resume() + try { + this.#primaryHandler.onResponseEnd?.(controller, trailers) + } catch (err) { + // Completion callbacks may throw to initiate a retry. The transport's + // error callback would be ignored now that this handler is completed. + this.#primaryHandler.onResponseError?.(controller, err) + } finally { + for (const waitingHandler of this.#waitingHandlers) { + if (waitingHandler.done || waitingHandler.controller.aborted) { + waitingHandler.done = true + continue + } - while (consume.stream.read() != null) { - // Loop - } -} + this.#flushWaitingHandler(waitingHandler) -/** - * @param {Buffer[]} chunks - * @param {number} length - */ -function chunksDecode (chunks, length) { - if (chunks.length === 0 || length === 0) { - return '' - } - const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks, length) - const bufferLength = buffer.length + if (waitingHandler.done || waitingHandler.controller.aborted) { + waitingHandler.done = true + continue + } - // Skip BOM. - const start = - bufferLength > 2 && - buffer[0] === 0xef && - buffer[1] === 0xbb && - buffer[2] === 0xbf - ? 3 - : 0 - return buffer.utf8Slice(start, bufferLength) -} + if (waitingHandler.controller.paused) { + waitingHandler.pendingTrailers = trailers + continue + } -/** - * @param {Buffer[]} chunks - * @param {number} length - * @returns {Uint8Array} - */ -function chunksConcat (chunks, length) { - if (chunks.length === 0 || length === 0) { - return new Uint8Array(0) - } - if (chunks.length === 1) { - // fast-path - return new Uint8Array(chunks[0]) - } - const buffer = new Uint8Array(Buffer.allocUnsafeSlow(length).buffer) + this.#endWaitingHandler(waitingHandler, trailers) + } - let offset = 0 - for (let i = 0; i < chunks.length; ++i) { - const chunk = chunks[i] - buffer.set(chunk, offset) - offset += chunk.length + this.#pruneDoneWaitingHandlers() + } } - return buffer -} + /** + * @param {import('../../types/dispatcher.d.ts').default.DispatchController} controller + * @param {Error} err + */ + onResponseError (controller, err) { + if (this.#completed) { + return + } -function consumeEnd (consume) { - const { type, body, resolve, stream, length } = consume + this.#aborted = true + this.#completed = true + this.#cleanup() - try { - if (type === 'text') { - resolve(chunksDecode(body, length)) - } else if (type === 'json') { - resolve(JSON.parse(chunksDecode(body, length))) - } else if (type === 'arrayBuffer') { - resolve(chunksConcat(body, length).buffer) - } else if (type === 'blob') { - resolve(new Blob(body, { type: stream[kContentType] })) - } else if (type === 'bytes') { - resolve(chunksConcat(body, length)) + try { + this.#primaryHandler.onResponseError?.(controller, err) + } finally { + for (const waitingHandler of this.#waitingHandlers) { + this.#errorWaitingHandler(waitingHandler, err) + } + + this.#waitingHandlers = [] } + } - consumeFinish(consume) - } catch (err) { - stream.destroy(err) + #cleanup () { + const onComplete = this.#onComplete + this.#onComplete = null + onComplete?.() } -} -function consumePush (consume, chunk) { - consume.length += chunk.length - consume.body.push(chunk) -} + /** + * @param {DispatchHandler} handler + * @returns {WaitingHandler} + */ + #createWaitingHandler (handler) { + /** @type {WaitingHandler} */ + const waitingHandler = { + handler, + controller: null, + bufferedChunks: [], + bufferedBytes: 0, + pendingTrailers: null, + done: false, + pendingStart: false + } + + const state = { + aborted: false, + paused: false, + reason: null + } + + waitingHandler.controller = { + resume: () => { + if (state.aborted) { + return + } -function consumeFinish (consume, err) { - if (consume.body === null) { - return - } + state.paused = false + this.#flushWaitingHandler(waitingHandler) - if (err) { - consume.reject(err) - } else { - consume.resolve() - } + if ( + this.#completed && + waitingHandler.pendingTrailers && + waitingHandler.bufferedChunks.length === 0 && + !state.paused && + !state.aborted + ) { + this.#endWaitingHandler(waitingHandler, waitingHandler.pendingTrailers) + } - consume.type = null - consume.stream = null - consume.resolve = null - consume.reject = null - consume.length = 0 - consume.body = null -} + this.#pruneDoneWaitingHandlers() + }, + pause: () => { + if (!state.aborted) { + state.paused = true + } + }, + get paused () { return state.paused }, + get aborted () { return state.aborted }, + get reason () { return state.reason }, + abort: (reason) => { + if (state.aborted) { + return + } -module.exports = { Readable: BodyReadable, chunksDecode } + state.aborted = true + state.reason = reason ?? null + waitingHandler.done = true + waitingHandler.pendingTrailers = null + waitingHandler.bufferedChunks = [] + waitingHandler.bufferedBytes = 0 + try { + handler.onResponseError?.(waitingHandler.controller, state.reason ?? new RequestAbortedError()) + } catch { + // Ignore errors from waiting handlers + } + } + } -/***/ }), + return waitingHandler + } -/***/ 7655: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * @param {WaitingHandler} waitingHandler + * @param {Buffer} chunk + */ + #bufferWaitingChunk (waitingHandler, chunk) { + if (waitingHandler.done || waitingHandler.controller.aborted) { + waitingHandler.done = true + waitingHandler.bufferedChunks = [] + waitingHandler.bufferedBytes = 0 + return + } -const assert = __nccwpck_require__(4589) -const { - ResponseStatusCodeError -} = __nccwpck_require__(8707) + const bufferedChunk = Buffer.from(chunk) + waitingHandler.bufferedChunks.push(bufferedChunk) + waitingHandler.bufferedBytes += bufferedChunk.length -const { chunksDecode } = __nccwpck_require__(9927) -const CHUNK_LIMIT = 128 * 1024 + if (waitingHandler.bufferedBytes > this.#maxBufferSize) { + const err = new RequestAbortedError(`Deduplicated waiting handler exceeded maxBufferSize (${this.#maxBufferSize} bytes) while paused`) + waitingHandler.controller.abort(err) + } + } -async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { - assert(body) + /** + * @param {WaitingHandler} waitingHandler + */ + #flushWaitingHandler (waitingHandler) { + const { handler, controller } = waitingHandler + + while ( + !waitingHandler.done && + !controller.aborted && + !controller.paused && + waitingHandler.bufferedChunks.length > 0 + ) { + const bufferedChunk = waitingHandler.bufferedChunks.shift() + waitingHandler.bufferedBytes -= bufferedChunk.length - let chunks = [] - let length = 0 + try { + handler.onResponseData?.(controller, bufferedChunk) + } catch { + // Ignore errors from waiting handlers + } - try { - for await (const chunk of body) { - chunks.push(chunk) - length += chunk.length - if (length > CHUNK_LIMIT) { - chunks = [] - length = 0 + if (controller.aborted) { + waitingHandler.done = true + waitingHandler.pendingTrailers = null + waitingHandler.bufferedChunks = [] + waitingHandler.bufferedBytes = 0 break } } - } catch { - chunks = [] - length = 0 - // Do nothing.... } - const message = `Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}` + /** + * @param {WaitingHandler} waitingHandler + * @param {object} trailers + */ + #endWaitingHandler (waitingHandler, trailers) { + waitingHandler.done = true + waitingHandler.pendingTrailers = null - if (statusCode === 204 || !contentType || !length) { - queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers))) - return + try { + waitingHandler.handler.onResponseEnd?.(waitingHandler.controller, trailers) + } catch (err) { + // This is a response failure, not a consumer abort. Aborting the waiting + // controller here would prevent downstream handlers from retrying. + try { + waitingHandler.handler.onResponseError?.(waitingHandler.controller, err) + } catch { + // An error callback must not prevent other waiting handlers completing. + } + } } - const stackTraceLimit = Error.stackTraceLimit - Error.stackTraceLimit = 0 - let payload + /** + * @param {WaitingHandler} waitingHandler + * @param {Error} err + */ + #errorWaitingHandler (waitingHandler, err) { + if (waitingHandler.done) { + return + } + + waitingHandler.done = true + waitingHandler.pendingTrailers = null + waitingHandler.bufferedChunks = [] + waitingHandler.bufferedBytes = 0 - try { - if (isContentTypeApplicationJson(contentType)) { - payload = JSON.parse(chunksDecode(chunks, length)) - } else if (isContentTypeText(contentType)) { - payload = chunksDecode(chunks, length) + // A response failure is not a consumer abort: retry handlers must be able + // to retry it just as they would a failure of the primary request. + try { + waitingHandler.handler.onResponseError?.(waitingHandler.controller, err) + } catch { + // Ignore errors from waiting handlers } - } catch { - // process in a callback to avoid throwing in the microtask queue - } finally { - Error.stackTraceLimit = stackTraceLimit } - queueMicrotask(() => callback(new ResponseStatusCodeError(message, statusCode, headers, payload))) -} - -const isContentTypeApplicationJson = (contentType) => { - return ( - contentType.length > 15 && - contentType[11] === '/' && - contentType[0] === 'a' && - contentType[1] === 'p' && - contentType[2] === 'p' && - contentType[3] === 'l' && - contentType[4] === 'i' && - contentType[5] === 'c' && - contentType[6] === 'a' && - contentType[7] === 't' && - contentType[8] === 'i' && - contentType[9] === 'o' && - contentType[10] === 'n' && - contentType[12] === 'j' && - contentType[13] === 's' && - contentType[14] === 'o' && - contentType[15] === 'n' - ) -} -const isContentTypeText = (contentType) => { - return ( - contentType.length > 4 && - contentType[4] === '/' && - contentType[0] === 't' && - contentType[1] === 'e' && - contentType[2] === 'x' && - contentType[3] === 't' - ) + #pruneDoneWaitingHandlers () { + this.#waitingHandlers = this.#waitingHandlers.filter(waitingHandler => waitingHandler.done === false) + } } -module.exports = { - getResolveErrorBodyCallback, - isContentTypeApplicationJson, - isContentTypeText -} +module.exports = DeduplicationHandler /***/ }), -/***/ 9136: +/***/ 8754: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const net = __nccwpck_require__(7030) -const assert = __nccwpck_require__(4589) const util = __nccwpck_require__(3440) -const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8707) -const timers = __nccwpck_require__(6603) +const assert = __nccwpck_require__(4589) +const { InvalidArgumentError, MaxRedirectsError } = __nccwpck_require__(8707) +const { kRequestOrigin, kRedirectCacheControl } = __nccwpck_require__(6443) -function noop () {} +const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] -let tls // include tls conditionally since it is not always available +const noop = () => {} -// TODO: session re-use does not wait for the first -// connection to resolve the session and might therefore -// resolve the same servername multiple times even when -// re-use is enabled. +class RedirectHandler { + static buildDispatch (dispatcher, maxRedirections) { + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } -let SessionCache -// FIXME: remove workaround when the Node bug is fixed -// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 -if (global.FinalizationRegistry && !(process.env.NODE_V8_COVERAGE || process.env.UNDICI_NO_FG)) { - SessionCache = class WeakSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions - this._sessionCache = new Map() - this._sessionRegistry = new global.FinalizationRegistry((key) => { - if (this._sessionCache.size < this._maxCachedSessions) { - return - } + const dispatch = dispatcher.dispatch.bind(dispatcher) + return (opts, originalHandler) => dispatch(opts, new RedirectHandler(dispatch, maxRedirections, opts, originalHandler)) + } - const ref = this._sessionCache.get(key) - if (ref !== undefined && ref.deref() === undefined) { - this._sessionCache.delete(key) - } - }) + constructor (dispatch, maxRedirections, opts, handler) { + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') } - get (sessionKey) { - const ref = this._sessionCache.get(sessionKey) - return ref ? ref.deref() : null + if (opts.throwOnMaxRedirect != null && typeof opts.throwOnMaxRedirect !== 'boolean') { + throw new InvalidArgumentError('throwOnMaxRedirect must be a boolean') } - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return - } + this.dispatch = dispatch + this.location = null + const { maxRedirections: _, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect, ...cleanOpts } = opts + this.opts = cleanOpts // opts must be a copy, exclude maxRedirections + this.opts.body = util.wrapRequestBody(this.opts.body) + this.stripHeadersOnRedirect = normalizeStripHeaders(stripHeadersOnRedirect, 'stripHeadersOnRedirect') + this.stripHeadersOnCrossOriginRedirect = normalizeStripHeaders(stripHeadersOnCrossOriginRedirect, 'stripHeadersOnCrossOriginRedirect') + this.maxRedirections = maxRedirections + this.handler = handler + this.history = [] + // `cache-control` of each intermediate (suppressed) redirect hop. An outer + // cache uses it to preserve a hop's storage policy (e.g. `no-store`) that + // would otherwise be lost because the hop's response is not forwarded. It + // travels as a non-enumerable property of the history array so it reaches + // the cache without becoming part of the public request/response context. + Object.defineProperty(this.history, kRedirectCacheControl, { + value: [], + enumerable: false + }) + } - this._sessionCache.set(sessionKey, new WeakRef(session)) - this._sessionRegistry.register(session, sessionKey) - } + onRequestStart (controller, context) { + this.handler.onRequestStart?.(controller, { ...context, history: this.history }) } -} else { - SessionCache = class SimpleSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions - this._sessionCache = new Map() + + onBodySent (chunk) { + this.handler.onBodySent?.(chunk) + } + + onRequestSent () { + this.handler.onRequestSent?.() + } + + onRequestUpgrade (controller, statusCode, headers, socket) { + this.handler.onRequestUpgrade?.(controller, statusCode, headers, socket) + } + + onResponseStart (controller, statusCode, headers, statusMessage) { + if (statusCode < 200) { + this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage) + return } - get (sessionKey) { - return this._sessionCache.get(sessionKey) + let removeContentHeaders = statusCode === 303 + + // https://tools.ietf.org/html/rfc7231#section-6.4.2 + // https://fetch.spec.whatwg.org/#http-redirect-fetch + // In case of HTTP 301 or 302 with POST, change the method to GET + // QUERY is safe (RFC 10008) and should not change method like GET. + if ((statusCode === 301 || statusCode === 302) && this.opts.method === 'POST') { + this.opts.method = 'GET' + if (util.isStream(this.opts.body)) { + util.destroy(this.opts.body.on('error', noop)) + } + this.opts.body = null + removeContentHeaders = true } - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + // In case of HTTP 303, always replace method to be either HEAD or GET + if (statusCode === 303 && this.opts.method !== 'HEAD') { + this.opts.method = 'GET' + if (util.isStream(this.opts.body)) { + util.destroy(this.opts.body.on('error', noop)) } + this.opts.body = null + } + + this.location = util.isDisturbed(this.opts.body) || redirectableStatusCodes.indexOf(statusCode) === -1 + ? null + : headers.location || null - if (this._sessionCache.size >= this._maxCachedSessions) { - // remove the oldest session - const { value: oldestKey } = this._sessionCache.keys().next() - this._sessionCache.delete(oldestKey) + // Only a redirect that would otherwise be followed counts against the + // limit. The final response after exactly maxRedirections redirects, or a + // 3xx without a Location header, is delivered as usual. + if (this.location && this.history.length >= this.maxRedirections) { + if (this.opts.throwOnMaxRedirect) { + throw new MaxRedirectsError() } + this.location = null + } + + const requestOrigin = this.opts[kRequestOrigin] === undefined + ? this.opts.origin + : this.opts[kRequestOrigin] - this._sessionCache.set(sessionKey, session) + if (requestOrigin) { + this.history.push(new URL(this.opts.path, requestOrigin)) } - } -} -function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) { - if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { - throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') - } + if (!this.location) { + this.handler.onResponseStart?.(controller, statusCode, headers, statusMessage) + return + } - const options = { path: socketPath, ...opts } - const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) - timeout = timeout == null ? 10e3 : timeout - allowH2 = allowH2 != null ? allowH2 : false - return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { - let socket - if (protocol === 'https:') { - if (!tls) { - tls = __nccwpck_require__(1692) + // This hop's response is suppressed (only its Location is used). Record its + // cache-control so an outer cache can honor a restrictive policy that would + // otherwise be lost when the final response is stored. + this.history[kRedirectCacheControl].push(headers['cache-control']) + + const baseUrl = requestOrigin + ? new URL(this.opts.path, requestOrigin) + : undefined + const { origin, pathname, search } = util.parseURL(new URL(this.location, baseUrl)) + const path = search ? `${pathname}${search}` : pathname + + // Check for redirect loops by seeing if we've already visited this URL in our history + // This catches the case where Client/Pool try to handle cross-origin redirects but fail + // and keep redirecting to the same URL in an infinite loop + const redirectUrlString = `${origin}${path}` + for (const historyUrl of this.history) { + if (historyUrl.toString() === redirectUrlString) { + throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`) } - servername = servername || options.servername || util.getServerName(host) || null + } - const sessionKey = servername || hostname - assert(sessionKey) + // Remove headers referring to the original URL. + // By default it is Host only. A 303 or a 301/302 POST-to-GET redirect also removes all Content-* headers. + // https://tools.ietf.org/html/rfc7231#section-6.4 + this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, requestOrigin !== origin, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect) + this.opts.path = path + this.opts.origin = origin + this.opts[kRequestOrigin] = origin + this.opts.query = null + } - const session = customSession || sessionCache.get(sessionKey) || null + onResponseData (controller, chunk) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 - port = port || 443 + TLDR: undici always ignores 3xx response bodies. - socket = tls.connect({ - highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... - ...options, - servername, - session, - localAddress, - // TODO(HTTP/2): Add support for h2c - ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], - socket: httpSocket, // upgrade socket connection - port, - host: hostname - }) + Redirection is used to serve the requested resource from another URL, so it assumes that + no body is generated (and thus can be ignored). Even though generating a body is not prohibited. - socket - .on('session', function (session) { - // TODO (fix): Can a session become invalid once established? Don't think so? - sessionCache.set(sessionKey, session) - }) + For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually + (which means it's optional and not mandated) contain just an hyperlink to the value of + the Location response header, so the body can be ignored safely. + + For status 300, which is "Multiple Choices", the spec mentions both generating a Location + response header AND a response body with the other possible location to follow. + Since the spec explicitly chooses not to specify a format for such body and leave it to + servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. + */ } else { - assert(!httpSocket, 'httpSocket can only be sent on TLS update') + this.handler.onResponseData?.(controller, chunk) + } + } - port = port || 80 + onResponseEnd (controller, trailers) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 - socket = net.connect({ - highWaterMark: 64 * 1024, // Same as nodejs fs streams. - ...options, - localAddress, - port, - host: hostname - }) - } + TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections + and neither are useful if present. - // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket - if (options.keepAlive == null || options.keepAlive) { - const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay - socket.setKeepAlive(true, keepAliveInitialDelay) + See comment on onData method above for more detailed information. + */ + this.dispatch(this.opts, this) + } else { + this.handler.onResponseEnd(controller, trailers) } + } - const clearConnectTimeout = setupConnectTimeout(new WeakRef(socket), { timeout, hostname, port }) - - socket - .setNoDelay(true) - .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { - queueMicrotask(clearConnectTimeout) + onResponseError (controller, error) { + this.handler.onResponseError?.(controller, error) + } +} - if (callback) { - const cb = callback - callback = null - cb(null, this) - } - }) - .on('error', function (err) { - queueMicrotask(clearConnectTimeout) +// https://tools.ietf.org/html/rfc7231#section-6.4.4 +function shouldRemoveHeader (header, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) { + const name = util.headerNameToString(header) + if (name === 'host') { + return true + } + if (stripHeaders?.has(name) || (unknownOrigin && stripHeadersOnCrossOrigin?.has(name))) { + return true + } + if (removeContent && name.startsWith('content-')) { + return true + } + if (unknownOrigin) { + return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization' + } + return false +} - if (callback) { - const cb = callback - callback = null - cb(err) - } - }) +// https://tools.ietf.org/html/rfc7231#section-6.4 +function normalizeStripHeaders (headers, optionName) { + if (headers == null) { + return null + } - return socket + if (!Array.isArray(headers)) { + throw new InvalidArgumentError(`${optionName} must be an array`) } -} -/** - * @param {WeakRef} socketWeakRef - * @param {object} opts - * @param {number} opts.timeout - * @param {string} opts.hostname - * @param {number} opts.port - * @returns {() => void} - */ -const setupConnectTimeout = process.platform === 'win32' - ? (socketWeakRef, opts) => { - if (!opts.timeout) { - return noop - } + const normalized = new Set() + for (const header of headers) { + if (typeof header !== 'string') { + throw new InvalidArgumentError(`${optionName} must contain header names`) + } - let s1 = null - let s2 = null - const fastTimer = timers.setFastTimeout(() => { - // setImmediate is added to make sure that we prioritize socket error events over timeouts - s1 = setImmediate(() => { - // Windows needs an extra setImmediate probably due to implementation differences in the socket logic - s2 = setImmediate(() => onConnectTimeout(socketWeakRef.deref(), opts)) - }) - }, opts.timeout) - return () => { - timers.clearFastTimeout(fastTimer) - clearImmediate(s1) - clearImmediate(s2) + normalized.add(util.headerNameToString(header)) + } + return normalized +} + +function cleanRequestHeaders (headers, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin) { + const ret = [] + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) { + ret.push(headers[i], headers[i + 1]) } } - : (socketWeakRef, opts) => { - if (!opts.timeout) { - return noop - } + } else if (headers && typeof headers === 'object') { + const entries = util.hasSafeIterator(headers) ? headers : Object.entries(headers) - let s1 = null - const fastTimer = timers.setFastTimeout(() => { - // setImmediate is added to make sure that we prioritize socket error events over timeouts - s1 = setImmediate(() => { - onConnectTimeout(socketWeakRef.deref(), opts) - }) - }, opts.timeout) - return () => { - timers.clearFastTimeout(fastTimer) - clearImmediate(s1) + for (const [key, value] of entries) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin, stripHeaders, stripHeadersOnCrossOrigin)) { + ret.push(key, value) } } + } else { + assert(headers == null, 'headers must be an object or an array') + } + return ret +} -/** - * @param {net.Socket} socket - * @param {object} opts - * @param {number} opts.timeout - * @param {string} opts.hostname - * @param {number} opts.port - */ -function onConnectTimeout (socket, opts) { - // The socket could be already garbage collected - if (socket == null) { +module.exports = RedirectHandler + + +/***/ }), + +/***/ 7816: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + +const assert = __nccwpck_require__(4589) + +const { kRetryHandlerDefaultRetry } = __nccwpck_require__(6443) +const { RequestRetryError, RequestAbortedError } = __nccwpck_require__(8707) +const { + hasSafeIterator, + isDisturbed, + parseRangeHeader, + wrapRequestBody +} = __nccwpck_require__(3440) + +function calculateRetryAfterHeader (retryAfter) { + const retryTime = new Date(retryAfter).getTime() + return isNaN(retryTime) ? null : retryTime - Date.now() +} + +function validatePartialResponseContentLength (headers, range, statusCode, retryCount) { + const contentLength = headers['content-length'] + if (contentLength == null) { return } - let message = 'Connect Timeout Error' - if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) { - message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')},` - } else { - message += ` (attempted address: ${opts.hostname}:${opts.port},` + if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) { + return } - message += ` timeout: ${opts.timeout}ms)` - - util.destroy(socket, new ConnectTimeoutError(message)) + const length = Number(contentLength) + const expectedLength = range.end - range.start + 1 + if (!Number.isFinite(length) || length !== expectedLength) { + throw new RequestRetryError('Content-Length mismatch', statusCode, { + headers, + data: { count: retryCount } + }) + } } -module.exports = buildConnector +// A stable controller handed to the downstream handler for the lifetime of the +// request. Each transparent retry/resume is a *separate* dispatch with its +// *own* connection controller. Without a stable proxy the downstream body keeps +// flow-controlling the original (now-dead) controller while data flows on the +// new one: backpressure pauses the new connection's controller, but the +// consumer's resume() targets the old one, so the resumed body stalls forever. +// The proxy always forwards to the controller of the currently active connection. +// An abort is additionally reported to the handler so it can cancel a pending +// retry backoff instead of letting the request hang until the backoff elapses. +// The notification is a private callback the handler hands over on construction, +// so nothing outside the handler can trigger it. +class RetryController { + #onAbort + #paused = false + #target = null + constructor (onAbort) { + this.#onAbort = onAbort + } -/***/ }), + set target (target) { + this.#target = target + if (this.#paused) { + target?.pause() + } + } -/***/ 735: -/***/ ((module) => { + get target () { return this.#target } -"use strict"; + pause () { + this.#paused = true + this.#target?.pause() + } + resume () { + this.#paused = false + this.#target?.resume() + } -/** @type {Record} */ -const headerNameLowerCasedRecord = {} + abort (reason) { + this.#target?.abort(reason) + this.#onAbort(reason) + } -// https://developer.mozilla.org/docs/Web/HTTP/Headers -const wellknownHeaderNames = [ - 'Accept', - 'Accept-Encoding', - 'Accept-Language', - 'Accept-Ranges', - 'Access-Control-Allow-Credentials', - 'Access-Control-Allow-Headers', - 'Access-Control-Allow-Methods', - 'Access-Control-Allow-Origin', - 'Access-Control-Expose-Headers', - 'Access-Control-Max-Age', - 'Access-Control-Request-Headers', - 'Access-Control-Request-Method', - 'Age', - 'Allow', - 'Alt-Svc', - 'Alt-Used', - 'Authorization', - 'Cache-Control', - 'Clear-Site-Data', - 'Connection', - 'Content-Disposition', - 'Content-Encoding', - 'Content-Language', - 'Content-Length', - 'Content-Location', - 'Content-Range', - 'Content-Security-Policy', - 'Content-Security-Policy-Report-Only', - 'Content-Type', - 'Cookie', - 'Cross-Origin-Embedder-Policy', - 'Cross-Origin-Opener-Policy', - 'Cross-Origin-Resource-Policy', - 'Date', - 'Device-Memory', - 'Downlink', - 'ECT', - 'ETag', - 'Expect', - 'Expect-CT', - 'Expires', - 'Forwarded', - 'From', - 'Host', - 'If-Match', - 'If-Modified-Since', - 'If-None-Match', - 'If-Range', - 'If-Unmodified-Since', - 'Keep-Alive', - 'Last-Modified', - 'Link', - 'Location', - 'Max-Forwards', - 'Origin', - 'Permissions-Policy', - 'Pragma', - 'Proxy-Authenticate', - 'Proxy-Authorization', - 'RTT', - 'Range', - 'Referer', - 'Referrer-Policy', - 'Refresh', - 'Retry-After', - 'Sec-WebSocket-Accept', - 'Sec-WebSocket-Extensions', - 'Sec-WebSocket-Key', - 'Sec-WebSocket-Protocol', - 'Sec-WebSocket-Version', - 'Server', - 'Server-Timing', - 'Service-Worker-Allowed', - 'Service-Worker-Navigation-Preload', - 'Set-Cookie', - 'SourceMap', - 'Strict-Transport-Security', - 'Supports-Loading-Mode', - 'TE', - 'Timing-Allow-Origin', - 'Trailer', - 'Transfer-Encoding', - 'Upgrade', - 'Upgrade-Insecure-Requests', - 'User-Agent', - 'Vary', - 'Via', - 'WWW-Authenticate', - 'X-Content-Type-Options', - 'X-DNS-Prefetch-Control', - 'X-Frame-Options', - 'X-Permitted-Cross-Domain-Policies', - 'X-Powered-By', - 'X-Requested-With', - 'X-XSS-Protection' -] + get paused () { return this.#paused || (this.#target?.paused ?? false) } + get aborted () { return this.#target?.aborted ?? false } + get reason () { return this.#target?.reason ?? null } + get rawHeaders () { return this.#target?.rawHeaders ?? null } + set rawHeaders (value) { + if (this.#target) { + this.#target.rawHeaders = value + } + } -for (let i = 0; i < wellknownHeaderNames.length; ++i) { - const key = wellknownHeaderNames[i] - const lowerCasedKey = key.toLowerCase() - headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] = - lowerCasedKey + get rawTrailers () { return this.#target?.rawTrailers ?? null } + set rawTrailers (value) { + if (this.#target) { + this.#target.rawTrailers = value + } + } } -// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. -Object.setPrototypeOf(headerNameLowerCasedRecord, null) +class RetryHandler { + constructor (opts, { dispatch, handler }) { + const { retryOptions, ...dispatchOpts } = opts + const { + // Retry scoped + retry: retryFn, + maxRetries, + maxTimeout, + minTimeout, + timeoutFactor, + // Response scoped + methods, + errorCodes, + retryAfter, + statusCodes, + throwOnError + } = retryOptions ?? {} + + this.error = null + this.dispatch = dispatch + this.handler = handler + this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) } + this.retryOpts = { + throwOnError: throwOnError ?? true, + retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], + retryAfter: retryAfter ?? true, + maxTimeout: maxTimeout ?? 30 * 1000, // 30s, + minTimeout: minTimeout ?? 500, // .5s + timeoutFactor: timeoutFactor ?? 2, + maxRetries: maxRetries ?? 5, + // What errors we should retry + methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'QUERY'], + // Indicates which errors to retry + statusCodes: statusCodes ?? [500, 502, 503, 504, 429], + // List of errors to retry + errorCodes: errorCodes ?? [ + 'ECONNRESET', + 'ECONNREFUSED', + 'ENOTFOUND', + 'ENETDOWN', + 'ENETUNREACH', + 'EHOSTDOWN', + 'EHOSTUNREACH', + 'EPIPE', + 'UND_ERR_SOCKET' + ] + } + + this.retryCount = 0 + this.retryCountCheckpoint = 0 + this.headersSent = false + this.start = 0 + this.end = null + this.etag = null + this.statusCode = null + this.headers = null + this.controllerProxy = new RetryController(reason => this.#onAbort(reason)) + // A retry decision is in flight (the policy may be holding a backoff + // timer). While pending, a consumer abort cancels the wait. + this.retryPending = false + // Backoff timer returned by the retry policy, so #onAbort can cancel it. + // Null for custom policies that do not return their timer. + this.retryTimer = null + // A response can complete while its controller is paused if the peer closes + // the connection. Hold its body until the retry policy decides whether to + // discard it for a retry or forward it as the final response. + this.pendingResponseData = null + this.pendingResponseTrailers = null + this.pendingResponseEnded = false + // Set once an abort during the backoff delivered the terminal error + // downstream; late policy callbacks and connection errors are then moot. + this.aborted = false + } -module.exports = { - wellknownHeaderNames, - headerNameLowerCasedRecord -} + onResponseStartWithRetry (controller, statusCode, headers, statusMessage, err) { + if (this.retryOpts.throwOnError) { + // Preserve old behavior for status codes that are not eligible for retry + if (this.retryOpts.statusCodes.includes(statusCode) === false) { + if (this.headersSent) { + // The downstream handler already received the response from an + // earlier attempt. Forwarding this response would replace the + // downstream body and leave the original body pending forever. + this.handler.onResponseError?.(this.controllerProxy, err) + } else { + this.headersSent = true + this.checkpointResponseEnd(headers) + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage) + } + } else { + this.error = err + } + return + } -/***/ }), + if (isDisturbed(this.opts.body)) { + this.headersSent = true + this.checkpointResponseEnd(headers) + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage) + return + } -/***/ 2414: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + function shouldRetry (passedErr) { + if (this.aborted) { + // Aborted while the policy was deciding; the decision is moot. + return + } + this.retryPending = false + this.retryTimer = null + + const pendingData = this.pendingResponseData + const pendingTrailers = this.pendingResponseTrailers + const pendingEnd = this.pendingResponseEnded + this.pendingResponseData = null + this.pendingResponseTrailers = null + this.pendingResponseEnded = false + + if (passedErr) { + if (this.headersSent) { + // The downstream handler already received the response from an + // earlier attempt. Forwarding this response would replace the + // downstream body and leave the original body pending forever. + this.handler.onResponseError?.(this.controllerProxy, passedErr) + } else { + this.headersSent = true + this.checkpointResponseEnd(headers) + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage) + controller.resume() + + if (pendingEnd) { + for (const chunk of pendingData) { + this.onResponseData(controller, chunk) + } + this.onResponseEnd(controller, pendingTrailers) + } + return + } + controller.resume() + return + } -"use strict"; + this.error = err + controller.resume() + if (pendingEnd) { + this.onResponseEnd(controller, pendingTrailers) + } + } + + // The pause()/resume() pair (here and in shouldRetry) acts on THIS + // connection's controller -- never the downstream proxy. We hold this exact + // connection while the retry policy decides (possibly after a timeout) and + // must resume the same one. Routing this through controllerProxy would risk + // resuming a different connection if a later dispatch re-points the proxy in + // between, leaving this one paused forever -- the very stall the proxy exists + // to prevent. + controller.pause() + // The default policy returns its backoff timer so an abort can cancel it; + // a custom policy may return anything (or nothing), which is ignored. + this.retryPending = true + this.pendingResponseData = [] + this.pendingResponseTrailers = null + this.pendingResponseEnded = false + this.retryTimer = this.retryOpts.retry( + err, + { + state: { counter: this.retryCount }, + opts: { retryOptions: this.retryOpts, ...this.opts } + }, + shouldRetry.bind(this) + ) ?? null + } -const diagnosticsChannel = __nccwpck_require__(3053) -const util = __nccwpck_require__(7975) + checkpointResponseEnd (headers) { + if (this.end == null && this.opts.method !== 'HEAD') { + const contentLength = headers['content-length'] + this.end = contentLength != null ? Number(contentLength) - 1 : null -const undiciDebugLog = util.debuglog('undici') -const fetchDebuglog = util.debuglog('fetch') -const websocketDebuglog = util.debuglog('websocket') -let isClientSet = false -const channels = { - // Client - beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), - connected: diagnosticsChannel.channel('undici:client:connected'), - connectError: diagnosticsChannel.channel('undici:client:connectError'), - sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), - // Request - create: diagnosticsChannel.channel('undici:request:create'), - bodySent: diagnosticsChannel.channel('undici:request:bodySent'), - headers: diagnosticsChannel.channel('undici:request:headers'), - trailers: diagnosticsChannel.channel('undici:request:trailers'), - error: diagnosticsChannel.channel('undici:request:error'), - // WebSocket - open: diagnosticsChannel.channel('undici:websocket:open'), - close: diagnosticsChannel.channel('undici:websocket:close'), - socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), - ping: diagnosticsChannel.channel('undici:websocket:ping'), - pong: diagnosticsChannel.channel('undici:websocket:pong') -} + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ) -if (undiciDebugLog.enabled || fetchDebuglog.enabled) { - const debuglog = fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog + this.resume = this.end != null + } + } - // Track all Client events - diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt - debuglog( - 'connecting to %s using %s%s', - `${host}${port ? `:${port}` : ''}`, - protocol, - version - ) - }) + onRequestStart (controller, context) { + // request.js creates a fresh RequestController per dispatch and passes that + // same instance to every later callback of the dispatch. onRequestStart is + // the first callback (it is where the controller is created), so re-pointing + // the proxy here is enough to keep it on the active connection across every + // transparent retry/resume. + this.controllerProxy.target = controller + if (!this.headersSent) { + this.handler.onRequestStart?.(this.controllerProxy, context) + } + } - diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt - debuglog( - 'connected to %s using %s%s', - `${host}${port ? `:${port}` : ''}`, - protocol, - version - ) - }) + onBodySent (chunk) { + this.handler.onBodySent?.(chunk) + } - diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { - const { - connectParams: { version, protocol, port, host }, - error - } = evt - debuglog( - 'connection to %s using %s%s errored - %s', - `${host}${port ? `:${port}` : ''}`, - protocol, - version, - error.message - ) - }) + onRequestSent () { + this.handler.onRequestSent?.() + } - diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { - const { - request: { method, path, origin } - } = evt - debuglog('sending request to %s %s/%s', method, origin, path) - }) + onRequestUpgrade (_controller, statusCode, headers, socket) { + this.handler.onRequestUpgrade?.(this.controllerProxy, statusCode, headers, socket) + } - // Track Request events - diagnosticsChannel.channel('undici:request:headers').subscribe(evt => { + static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { + const { statusCode, code, headers } = err + const { method, retryOptions } = opts const { - request: { method, path, origin }, - response: { statusCode } - } = evt - debuglog( - 'received response to %s %s/%s - HTTP %d', - method, - origin, - path, - statusCode - ) - }) + maxRetries, + minTimeout, + maxTimeout, + timeoutFactor, + statusCodes, + errorCodes, + methods, + retryAfter + } = retryOptions + const { counter } = state - diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => { - const { - request: { method, path, origin } - } = evt - debuglog('trailers received from %s %s/%s', method, origin, path) - }) + // Any code that is not a Undici's originated and allowed to retry + if (code && code !== 'UND_ERR_REQ_RETRY' && !errorCodes.includes(code)) { + cb(err) + return + } - diagnosticsChannel.channel('undici:request:error').subscribe(evt => { - const { - request: { method, path, origin }, - error - } = evt - debuglog( - 'request to %s %s/%s errored - %s', - method, - origin, - path, - error.message - ) - }) + // If a set of method are provided and the current method is not in the list + if (Array.isArray(methods) && !methods.includes(method)) { + cb(err) + return + } - isClientSet = true -} + // If a set of status code are provided and the current status code is not in the list + if ( + statusCode != null && + Array.isArray(statusCodes) && + !statusCodes.includes(statusCode) + ) { + cb(err) + return + } -if (websocketDebuglog.enabled) { - if (!isClientSet) { - const debuglog = undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog - diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt - debuglog( - 'connecting to %s%s using %s%s', - host, - port ? `:${port}` : '', - protocol, - version - ) - }) + // If we reached the max number of retries + if (counter > maxRetries) { + cb(err) + return + } - diagnosticsChannel.channel('undici:client:connected').subscribe(evt => { - const { - connectParams: { version, protocol, port, host } - } = evt - debuglog( - 'connected to %s%s using %s%s', - host, - port ? `:${port}` : '', - protocol, - version - ) - }) + let retryAfterHeader = retryAfter === false ? undefined : headers?.['retry-after'] + if (retryAfterHeader) { + retryAfterHeader = Number(retryAfterHeader) + retryAfterHeader = Number.isNaN(retryAfterHeader) + ? calculateRetryAfterHeader(headers['retry-after']) + : retryAfterHeader * 1e3 // Retry-After is in seconds + } - diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => { - const { - connectParams: { version, protocol, port, host }, - error - } = evt - debuglog( - 'connection to %s%s using %s%s errored - %s', - host, - port ? `:${port}` : '', - protocol, - version, - error.message - ) - }) + const retryTimeout = + retryAfterHeader === 0 + ? 0 + : retryAfterHeader > 0 + ? Math.min(retryAfterHeader, maxTimeout) + : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout) - diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => { - const { - request: { method, path, origin } - } = evt - debuglog('sending request to %s %s/%s', method, origin, path) - }) + // Return the backoff timer so the handler can cancel it when the + // consumer aborts while the retry decision is pending. + return setTimeout(() => cb(null), retryTimeout) } - // Track all WebSocket events - diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => { - const { - address: { address, port } - } = evt - websocketDebuglog('connection opened %s%s', address, port ? `:${port}` : '') - }) + onResponseStart (controller, statusCode, headers, statusMessage) { + if (statusCode < 200) { + this.handler.onResponseStart?.(this.controllerProxy, statusCode, headers, statusMessage) + return + } - diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => { - const { websocket, code, reason } = evt - websocketDebuglog( - 'closed connection to %s - %s %s', - websocket.url, - code, - reason - ) - }) + this.error = null + this.retryCount += 1 + this.statusCode = statusCode + this.headers = headers - diagnosticsChannel.channel('undici:websocket:socket_error').subscribe(err => { - websocketDebuglog('connection errored - %s', err.message) - }) + // Checkpoint for resume from where we left it + if (this.headersSent) { + // Only Partial Content 206 supposed to provide Content-Range, + // any other status code that partially consumed the payload + // should not be retried because it would result in downstream + // wrongly concatenate multiple responses. + if (statusCode !== 206 && (this.start > 0 || statusCode !== 200)) { + throw new RequestRetryError('server does not support the range header and the payload was partially consumed', statusCode, { + headers, + data: { count: this.retryCount } + }) + } - diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => { - websocketDebuglog('ping received') - }) + const contentRange = parseRangeHeader(headers['content-range']) + // If no content range + if (!contentRange) { + // We always throw here as we want to indicate that we entred unexpected path + throw new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + data: { count: this.retryCount } + }) + } - diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => { - websocketDebuglog('pong received') - }) -} + // Let's start with a weak etag check + if (this.etag != null && this.etag !== headers.etag) { + // We always throw here as we want to indicate that we entred unexpected path + throw new RequestRetryError('ETag mismatch', statusCode, { + headers, + data: { count: this.retryCount } + }) + } -module.exports = { - channels -} + validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount) + const { start, size, end = size ? size - 1 : null } = contentRange -/***/ }), + if (this.start !== start || (this.end != null && this.end !== end)) { + throw new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + data: { count: this.retryCount } + }) + } -/***/ 8707: -/***/ ((module) => { + return + } -"use strict"; + if (statusCode >= 300) { + const err = new RequestRetryError('Request failed', statusCode, { + headers, + data: { + count: this.retryCount + } + }) + this.onResponseStartWithRetry(controller, statusCode, headers, statusMessage, err) + return + } -const kUndiciError = Symbol.for('undici.error.UND_ERR') -class UndiciError extends Error { - constructor (message) { - super(message) - this.name = 'UndiciError' - this.code = 'UND_ERR' - } + if (this.end == null) { + if (statusCode === 206) { + // First time we receive 206 + const range = parseRangeHeader(headers['content-range']) - static [Symbol.hasInstance] (instance) { - return instance && instance[kUndiciError] === true - } + if (range == null || range.end == null) { + this.headersSent = true + this.handler.onResponseStart?.( + this.controllerProxy, + statusCode, + headers, + statusMessage + ) + return + } - [kUndiciError] = true -} + validatePartialResponseContentLength(headers, range, statusCode, this.retryCount) -const kConnectTimeoutError = Symbol.for('undici.error.UND_ERR_CONNECT_TIMEOUT') -class ConnectTimeoutError extends UndiciError { - constructor (message) { - super(message) - this.name = 'ConnectTimeoutError' - this.message = message || 'Connect Timeout Error' - this.code = 'UND_ERR_CONNECT_TIMEOUT' - } + const { start, size, end = size ? size - 1 : null } = range + assert( + start != null && Number.isFinite(start), + 'content-range mismatch' + ) + assert(end != null && Number.isFinite(end), 'invalid content-length') - static [Symbol.hasInstance] (instance) { - return instance && instance[kConnectTimeoutError] === true - } + this.start = start + this.end = end + } - [kConnectTimeoutError] = true -} + // We make our best to checkpoint the body for further range headers + if (this.end == null && this.opts.method !== 'HEAD') { + const contentLength = headers['content-length'] + this.end = contentLength != null ? Number(contentLength) - 1 : null + } -const kHeadersTimeoutError = Symbol.for('undici.error.UND_ERR_HEADERS_TIMEOUT') -class HeadersTimeoutError extends UndiciError { - constructor (message) { - super(message) - this.name = 'HeadersTimeoutError' - this.message = message || 'Headers Timeout Error' - this.code = 'UND_ERR_HEADERS_TIMEOUT' - } + assert(Number.isFinite(this.start)) + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ) - static [Symbol.hasInstance] (instance) { - return instance && instance[kHeadersTimeoutError] === true - } + this.resume = true + this.etag = headers.etag != null ? headers.etag : null - [kHeadersTimeoutError] = true -} + // Weak etags are not useful for comparison nor cache + // for instance not safe to assume if the response is byte-per-byte + // equal + if ( + this.etag != null && + this.etag[0] === 'W' && + this.etag[1] === '/' + ) { + this.etag = null + } -const kHeadersOverflowError = Symbol.for('undici.error.UND_ERR_HEADERS_OVERFLOW') -class HeadersOverflowError extends UndiciError { - constructor (message) { - super(message) - this.name = 'HeadersOverflowError' - this.message = message || 'Headers Overflow Error' - this.code = 'UND_ERR_HEADERS_OVERFLOW' + this.headersSent = true + this.handler.onResponseStart?.( + this.controllerProxy, + statusCode, + headers, + statusMessage + ) + } else { + throw new RequestRetryError('Request failed', statusCode, { + headers, + data: { count: this.retryCount } + }) + } } - static [Symbol.hasInstance] (instance) { - return instance && instance[kHeadersOverflowError] === true - } + onResponseData (_controller, chunk) { + if (this.pendingResponseData !== null) { + this.pendingResponseData.push(chunk) + return + } - [kHeadersOverflowError] = true -} + if (this.error) { + return + } -const kBodyTimeoutError = Symbol.for('undici.error.UND_ERR_BODY_TIMEOUT') -class BodyTimeoutError extends UndiciError { - constructor (message) { - super(message) - this.name = 'BodyTimeoutError' - this.message = message || 'Body Timeout Error' - this.code = 'UND_ERR_BODY_TIMEOUT' - } + this.start += chunk.length - static [Symbol.hasInstance] (instance) { - return instance && instance[kBodyTimeoutError] === true + this.handler.onResponseData?.(this.controllerProxy, chunk) } - [kBodyTimeoutError] = true -} + onResponseEnd (_controller, trailers) { + if (this.pendingResponseData !== null) { + this.pendingResponseTrailers = trailers + this.pendingResponseEnded = true + return + } -const kResponseStatusCodeError = Symbol.for('undici.error.UND_ERR_RESPONSE_STATUS_CODE') -class ResponseStatusCodeError extends UndiciError { - constructor (message, statusCode, headers, body) { - super(message) - this.name = 'ResponseStatusCodeError' - this.message = message || 'Response Status Code Error' - this.code = 'UND_ERR_RESPONSE_STATUS_CODE' - this.body = body - this.status = statusCode - this.statusCode = statusCode - this.headers = headers - } + if (this.error && this.retryOpts.throwOnError) { + throw this.error + } - static [Symbol.hasInstance] (instance) { - return instance && instance[kResponseStatusCodeError] === true + if (!this.error) { + // Verify that the received body length matches the expected range + // when we have a finite end position (from Content-Length or Content-Range) + if (this.end != null && Number.isFinite(this.end)) { + if (this.start !== this.end + 1) { + throw new RequestRetryError('Content-Range mismatch', this.statusCode, { + headers: this.headers, + data: { count: this.retryCount } + }) + } + } + this.retryCount = 0 + return this.handler.onResponseEnd?.(this.controllerProxy, trailers) + } + + this.retry() } - [kResponseStatusCodeError] = true -} + retry () { + if (this.start !== 0) { + this.opts = { + ...this.opts, + headers: buildResumeHeaders(this.opts.headers, `bytes=${this.start}-${this.end ?? ''}`, this.etag) + } + } -const kInvalidArgumentError = Symbol.for('undici.error.UND_ERR_INVALID_ARG') -class InvalidArgumentError extends UndiciError { - constructor (message) { - super(message) - this.name = 'InvalidArgumentError' - this.message = message || 'Invalid Argument Error' - this.code = 'UND_ERR_INVALID_ARG' + try { + this.retryCountCheckpoint = this.retryCount + this.dispatch(this.opts, this) + } catch (err) { + this.handler.onResponseError?.(this.controllerProxy, err) + } } - static [Symbol.hasInstance] (instance) { - return instance && instance[kInvalidArgumentError] === true - } + onResponseError (controller, err) { + if (this.aborted) { + // #onAbort already delivered the terminal error downstream; the late + // error of the torn-down connection must not be forwarded twice. + return + } - [kInvalidArgumentError] = true -} + // controller is THIS failed connection (not the proxy): we inspect whether + // the consumer aborted it to decide retry-vs-propagate. + if (controller?.aborted || isDisturbed(this.opts.body) || (this.headersSent && !this.resume)) { + this.handler.onResponseError?.(this.controllerProxy, err) + return + } -const kInvalidReturnValueError = Symbol.for('undici.error.UND_ERR_INVALID_RETURN_VALUE') -class InvalidReturnValueError extends UndiciError { - constructor (message) { - super(message) - this.name = 'InvalidReturnValueError' - this.message = message || 'Invalid Return Value Error' - this.code = 'UND_ERR_INVALID_RETURN_VALUE' - } + function shouldRetry (returnedErr) { + if (this.aborted) { + // Aborted while the policy was deciding; the decision is moot. + return + } + this.retryPending = false + this.retryTimer = null - static [Symbol.hasInstance] (instance) { - return instance && instance[kInvalidReturnValueError] === true - } + if (!returnedErr) { + this.retry() + return + } - [kInvalidReturnValueError] = true -} + this.handler?.onResponseError?.(this.controllerProxy, returnedErr) + } -const kAbortError = Symbol.for('undici.error.UND_ERR_ABORT') -class AbortError extends UndiciError { - constructor (message) { - super(message) - this.name = 'AbortError' - this.message = message || 'The operation was aborted' - this.code = 'UND_ERR_ABORT' - } + // We reconcile in case of a mix between network errors + // and server error response + if (this.retryCount - this.retryCountCheckpoint > 0) { + // We count the difference between the last checkpoint and the current retry count + this.retryCount = + this.retryCountCheckpoint + + (this.retryCount - this.retryCountCheckpoint) + } else { + this.retryCount += 1 + } - static [Symbol.hasInstance] (instance) { - return instance && instance[kAbortError] === true + this.retryPending = true + this.retryTimer = this.retryOpts.retry( + err, + { + state: { counter: this.retryCount }, + opts: { retryOptions: this.retryOpts, ...this.opts } + }, + shouldRetry.bind(this) + ) ?? null } - [kAbortError] = true -} - -const kRequestAbortedError = Symbol.for('undici.error.UND_ERR_ABORTED') -class RequestAbortedError extends AbortError { - constructor (message) { - super(message) - this.name = 'AbortError' - this.message = message || 'Request aborted' - this.code = 'UND_ERR_ABORTED' - } + #onAbort (reason) { + // A consumer abort lands on the controller proxy. If the retry policy is + // still deciding (typically holding a backoff timer), cancel the wait and + // surface the abort immediately instead of letting the request hang until + // the backoff elapses. + if (!this.retryPending) { + return + } - static [Symbol.hasInstance] (instance) { - return instance && instance[kRequestAbortedError] === true + this.aborted = true + this.retryPending = false + clearTimeout(this.retryTimer) + this.retryTimer = null + this.pendingResponseData = null + this.pendingResponseTrailers = null + this.pendingResponseEnded = false + this.handler.onResponseError?.(this.controllerProxy, reason ?? new RequestAbortedError()) } +} - [kRequestAbortedError] = true +function isReplacedHeader (key, etag) { + const name = key.toLowerCase() + return name === 'range' || (etag != null && name === 'if-match') } -const kInformationalError = Symbol.for('undici.error.UND_ERR_INFO') -class InformationalError extends UndiciError { - constructor (message) { - super(message) - this.name = 'InformationalError' - this.message = message || 'Request information' - this.code = 'UND_ERR_INFO' +function buildResumeHeaders (headers, range, etag) { + if (Array.isArray(headers) || (headers && typeof headers === 'object' && hasSafeIterator(headers))) { + const ret = [] + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (!isReplacedHeader(headers[i], etag)) { + ret.push(headers[i], headers[i + 1]) + } + } + } else { + for (const [key, value] of headers) { + if (!isReplacedHeader(key, etag)) { + ret.push(key, value) + } + } + } + ret.push('range', range) + // Weak etag check - weak etags will make comparison algorithms never match + if (etag != null) { + ret.push('if-match', etag) + } + return ret } - static [Symbol.hasInstance] (instance) { - return instance && instance[kInformationalError] === true + const ret = {} + for (const key in headers) { + if (Object.hasOwn(headers, key) && !isReplacedHeader(key, etag)) { + ret[key] = headers[key] + } } - - [kInformationalError] = true + ret.range = range + if (etag != null) { + ret['if-match'] = etag + } + return ret } -const kRequestContentLengthMismatchError = Symbol.for('undici.error.UND_ERR_REQ_CONTENT_LENGTH_MISMATCH') -class RequestContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message) - this.name = 'RequestContentLengthMismatchError' - this.message = message || 'Request body length does not match content-length header' - this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' - } +module.exports = RetryHandler - static [Symbol.hasInstance] (instance) { - return instance && instance[kRequestContentLengthMismatchError] === true - } - [kRequestContentLengthMismatchError] = true -} +/***/ }), -const kResponseContentLengthMismatchError = Symbol.for('undici.error.UND_ERR_RES_CONTENT_LENGTH_MISMATCH') -class ResponseContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message) - this.name = 'ResponseContentLengthMismatchError' - this.message = message || 'Response body length does not match content-length header' - this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' - } +/***/ 5542: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - static [Symbol.hasInstance] (instance) { - return instance && instance[kResponseContentLengthMismatchError] === true - } +"use strict"; - [kResponseContentLengthMismatchError] = true -} -const kClientDestroyedError = Symbol.for('undici.error.UND_ERR_DESTROYED') -class ClientDestroyedError extends UndiciError { - constructor (message) { - super(message) - this.name = 'ClientDestroyedError' - this.message = message || 'The client is destroyed' - this.code = 'UND_ERR_DESTROYED' +const assert = __nccwpck_require__(4589) +const { Readable } = __nccwpck_require__(7075) +const util = __nccwpck_require__(3440) +const CacheHandler = __nccwpck_require__(9976) +const MemoryCacheStore = __nccwpck_require__(4889) +const CacheRevalidationHandler = __nccwpck_require__(7133) +const { + assertCacheStore, + assertCacheMethods, + getInterceptorOrigin, + makeCacheKey, + normalizeHeaders, + parseCacheControlHeader, + isInvalidOrWildcardVaryHeader, + parseVaryHeader +} = __nccwpck_require__(7659) +const { AbortError } = __nccwpck_require__(8707) +const { parseHttpDate } = __nccwpck_require__(5453) + +/** + * @param {(string | RegExp)[] | undefined} origins + * @param {string} name + */ +function assertCacheOrigins (origins, name) { + if (origins === undefined) return + if (!Array.isArray(origins)) { + throw new TypeError(`expected ${name} to be an array or undefined, got ${typeof origins}`) } - - static [Symbol.hasInstance] (instance) { - return instance && instance[kClientDestroyedError] === true + for (let i = 0; i < origins.length; i++) { + const origin = origins[i] + if (typeof origin !== 'string' && !(origin instanceof RegExp)) { + throw new TypeError(`expected ${name}[${i}] to be a string or RegExp, got ${typeof origin}`) + } } - - [kClientDestroyedError] = true } -const kClientClosedError = Symbol.for('undici.error.UND_ERR_CLOSED') -class ClientClosedError extends UndiciError { - constructor (message) { - super(message) - this.name = 'ClientClosedError' - this.message = message || 'The client is closed' - this.code = 'UND_ERR_CLOSED' - } - - static [Symbol.hasInstance] (instance) { - return instance && instance[kClientClosedError] === true - } +const nop = () => {} - [kClientClosedError] = true +function trimOWS (value) { + return value.replace(/^[\t ]+|[\t ]+$/g, '') } -const kSocketError = Symbol.for('undici.error.UND_ERR_SOCKET') -class SocketError extends UndiciError { - constructor (message, socket) { - super(message) - this.name = 'SocketError' - this.message = message || 'Socket error' - this.code = 'UND_ERR_SOCKET' - this.socket = socket - } - - static [Symbol.hasInstance] (instance) { - return instance && instance[kSocketError] === true +function arrayIncludes (array, value) { + for (let i = 0; i < array.length; i++) { + if (array[i] === value) { + return true + } } - [kSocketError] = true + return false } -const kNotSupportedError = Symbol.for('undici.error.UND_ERR_NOT_SUPPORTED') -class NotSupportedError extends UndiciError { - constructor (message) { - super(message) - this.name = 'NotSupportedError' - this.message = message || 'Not supported error' - this.code = 'UND_ERR_NOT_SUPPORTED' +function hasPragmaNoCache (headers) { + const pragma = headers?.pragma + if (!pragma) { + return false } - static [Symbol.hasInstance] (instance) { - return instance && instance[kNotSupportedError] === true + const values = Array.isArray(pragma) ? pragma : [pragma] + for (let i = 0; i < values.length; i++) { + const value = values[i] + if (typeof value !== 'string') { + continue + } + + const directives = value.split(',') + for (let j = 0; j < directives.length; j++) { + if (trimOWS(directives[j]).toLowerCase() === 'no-cache') { + return true + } + } } - [kNotSupportedError] = true + return false } -const kBalancedPoolMissingUpstreamError = Symbol.for('undici.error.UND_ERR_BPL_MISSING_UPSTREAM') -class BalancedPoolMissingUpstreamError extends UndiciError { - constructor (message) { - super(message) - this.name = 'MissingUpstreamError' - this.message = message || 'No upstream has been added to the BalancedPool' - this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' - } +/** + * @typedef {(options: import('../../types/dispatcher.d.ts').default.DispatchOptions, handler: import('../../types/dispatcher.d.ts').default.DispatchHandler) => void} DispatchFn + */ - static [Symbol.hasInstance] (instance) { - return instance && instance[kBalancedPoolMissingUpstreamError] === true +/** + * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} cacheControlDirectives + * @param {import('../../types/dispatcher.d.ts').default.RequestOptions} opts + * @returns {boolean} + */ +function needsRevalidation (result, cacheControlDirectives, { headers = {} }) { + // Always revalidate requests with the no-cache request directive. + if (cacheControlDirectives?.['no-cache']) { + return true } - [kBalancedPoolMissingUpstreamError] = true -} - -const kHTTPParserError = Symbol.for('undici.error.UND_ERR_HTTP_PARSER') -class HTTPParserError extends Error { - constructor (message, code, data) { - super(message) - this.name = 'HTTPParserError' - this.code = code ? `HPE_${code}` : undefined - this.data = data ? data.toString() : undefined + // Always revalidate requests with unqualified no-cache response directive. + if (result.cacheControlDirectives?.['no-cache'] && !Array.isArray(result.cacheControlDirectives['no-cache'])) { + return true } - static [Symbol.hasInstance] (instance) { - return instance && instance[kHTTPParserError] === true + // Always revalidate requests with conditional headers. + if (headers['if-modified-since'] || headers['if-none-match']) { + return true } - [kHTTPParserError] = true + return false } -const kResponseExceededMaxSizeError = Symbol.for('undici.error.UND_ERR_RES_EXCEEDED_MAX_SIZE') -class ResponseExceededMaxSizeError extends UndiciError { - constructor (message) { - super(message) - this.name = 'ResponseExceededMaxSizeError' - this.message = message || 'Response content exceeded max size' - this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' - } - - static [Symbol.hasInstance] (instance) { - return instance && instance[kResponseExceededMaxSizeError] === true - } - - [kResponseExceededMaxSizeError] = true +/** + * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType + * @returns {boolean} + */ +function staleResponseRequiresRevalidation (result, cacheType) { + return result.cacheControlDirectives?.['must-revalidate'] === true || + (cacheType === 'shared' && ( + result.cacheControlDirectives?.['proxy-revalidate'] === true || + // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.2.10 + // s-maxage implies proxy-revalidate for shared caches. + result.cacheControlDirectives?.['s-maxage'] !== undefined + )) } -const kRequestRetryError = Symbol.for('undici.error.UND_ERR_REQ_RETRY') -class RequestRetryError extends UndiciError { - constructor (message, code, { headers, data }) { - super(message) - this.name = 'RequestRetryError' - this.message = message || 'Request retry error' - this.code = 'UND_ERR_REQ_RETRY' - this.statusCode = code - this.data = data - this.headers = headers +/** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType + * @param {import('../../types/header.d.ts').IncomingHttpHeaders} headers + * @returns {boolean} + */ +function revalidationResponseDisallowsCachedReuse (cacheType, headers) { + if ( + (headers.vary && isInvalidOrWildcardVaryHeader(headers.vary)) || + (cacheType === 'shared' && Object.hasOwn(headers, 'set-cookie')) + ) { + return true } - static [Symbol.hasInstance] (instance) { - return instance && instance[kRequestRetryError] === true + const cacheControl = headers['cache-control'] + if (!cacheControl) { + return false } - [kRequestRetryError] = true + const cacheControlDirectives = parseCacheControlHeader(cacheControl) + return cacheControlDirectives['no-store'] === true || + (cacheType === 'shared' && cacheControlDirectives.private === true) } -const kResponseError = Symbol.for('undici.error.UND_ERR_RESPONSE') -class ResponseError extends UndiciError { - constructor (message, code, { headers, data }) { - super(message) - this.name = 'ResponseError' - this.message = message || 'Response error' - this.code = 'UND_ERR_RESPONSE' - this.statusCode = code - this.data = data - this.headers = headers +function revalidationResponseUpdatesCacheControl (headers) { + return headers['cache-control'] !== undefined +} + +/** + * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result + * @param {Record | undefined} varyDirectives + * @returns {boolean} + */ +function revalidationResponseAddsVary (result, varyDirectives) { + if (!varyDirectives) { + return false } - static [Symbol.hasInstance] (instance) { - return instance && instance[kResponseError] === true + for (const key in varyDirectives) { + if (result.vary == null || !Object.hasOwn(result.vary, key)) { + return true + } } - [kResponseError] = true + return false } -const kSecureProxyConnectionError = Symbol.for('undici.error.UND_ERR_PRX_TLS') -class SecureProxyConnectionError extends UndiciError { - constructor (cause, message, options) { - super(message, { cause, ...(options ?? {}) }) - this.name = 'SecureProxyConnectionError' - this.message = message || 'Secure Proxy Connection failed' - this.code = 'UND_ERR_PRX_TLS' - this.cause = cause +function deleteCachedValue (store, cacheKey) { + try { + store.delete(cacheKey)?.catch?.(nop) + } catch { + // Fail silently } +} - static [Symbol.hasInstance] (instance) { - return instance && instance[kSecureProxyConnectionError] === true +function getUsableLastModified (headers) { + const lastModified = headers?.['last-modified'] + if (typeof lastModified === 'string' && parseHttpDate(lastModified)) { + return lastModified } - - [kSecureProxyConnectionError] = true } -const kMessageSizeExceededError = Symbol.for('undici.error.UND_ERR_WS_MESSAGE_SIZE_EXCEEDED') -class MessageSizeExceededError extends UndiciError { - constructor (message) { - super(message) - this.name = 'MessageSizeExceededError' - this.message = message || 'Max decompressed message size exceeded' - this.code = 'UND_ERR_WS_MESSAGE_SIZE_EXCEEDED' +function makeRevalidationHeaders (opts, result) { + const headers = { + ...opts.headers, + 'if-modified-since': getUsableLastModified(result.headers) ?? new Date(result.cachedAt).toUTCString() } - static [Symbol.hasInstance] (instance) { - return instance && instance[kMessageSizeExceededError] === true + if (result.etag) { + headers['if-none-match'] = result.etag } - get [kMessageSizeExceededError] () { - return true + if (result.vary) { + for (const key in result.vary) { + if (result.vary[key] != null) { + headers[key] = result.vary[key] + } + } } -} -module.exports = { - AbortError, - HTTPParserError, - UndiciError, - HeadersTimeoutError, - HeadersOverflowError, - BodyTimeoutError, - RequestContentLengthMismatchError, - ConnectTimeoutError, - ResponseStatusCodeError, - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError, - ClientDestroyedError, - ClientClosedError, - InformationalError, - SocketError, - NotSupportedError, - ResponseContentLengthMismatchError, - BalancedPoolMissingUpstreamError, - ResponseExceededMaxSizeError, - RequestRetryError, - ResponseError, - SecureProxyConnectionError, - MessageSizeExceededError + return headers } +/** + * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} cacheControlDirectives + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType + * @returns {boolean} + */ +function isStale (result, cacheControlDirectives, cacheType) { + const now = Date.now() + // A zero freshness lifetime (e.g. max-age=0 with a validator) is never fresh, + // even when reused within the same millisecond or after a clock step back. + // https://www.rfc-editor.org/rfc/rfc9111.html#section-4.2 + if (now > result.staleAt || result.staleAt <= result.cachedAt) { + // Response is stale + if (!staleResponseRequiresRevalidation(result, cacheType) && cacheControlDirectives?.['max-stale']) { + // There's a threshold where we can serve stale responses, let's see if + // we're in it + // https://www.rfc-editor.org/rfc/rfc9111.html#name-max-stale + const gracePeriod = result.staleAt + (cacheControlDirectives['max-stale'] * 1000) + return now > gracePeriod + } -/***/ }), - -/***/ 4655: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const { - InvalidArgumentError, - NotSupportedError -} = __nccwpck_require__(8707) -const assert = __nccwpck_require__(4589) -const { - isValidHTTPToken, - isValidHeaderValue, - isStream, - destroy, - isBuffer, - isFormDataLike, - isIterable, - isBlobLike, - buildURL, - validateHandler, - getServerName, - normalizedMethodRecords -} = __nccwpck_require__(3440) -const { channels } = __nccwpck_require__(2414) -const { headerNameLowerCasedRecord } = __nccwpck_require__(735) + return true + } -// Verifies that a given path is valid does not contain control chars \x00 to \x20 -const invalidPathRegex = /[^\u0021-\u00ff]/ + if (cacheControlDirectives?.['min-fresh']) { + // https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.1.3 -const kHandler = Symbol('handler') + // At this point, staleAt is always > now + const timeLeftTillStale = result.staleAt - now + const threshold = cacheControlDirectives['min-fresh'] * 1000 -class Request { - constructor (origin, { - path, - method, - body, - headers, - query, - idempotent, - blocking, - upgrade, - headersTimeout, - bodyTimeout, - reset, - throwOnError, - expectContinue, - servername - }, handler) { - if (typeof path !== 'string') { - throw new InvalidArgumentError('path must be a string') - } else if ( - path[0] !== '/' && - !(path.startsWith('http://') || path.startsWith('https://')) && - method !== 'CONNECT' - ) { - throw new InvalidArgumentError('path must be an absolute URL or start with a slash') - } else if (invalidPathRegex.test(path)) { - throw new InvalidArgumentError('invalid request path') - } + return timeLeftTillStale <= threshold + } - if (typeof method !== 'string') { - throw new InvalidArgumentError('method must be a string') - } else if (normalizedMethodRecords[method] === undefined && !isValidHTTPToken(method)) { - throw new InvalidArgumentError('invalid request method') - } + return false +} - if (upgrade && typeof upgrade !== 'string') { - throw new InvalidArgumentError('upgrade must be a string') - } +/** + * Check if we're within the stale-while-revalidate window for a stale response + * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions['type']} cacheType + * @returns {boolean} + */ +function withinStaleWhileRevalidateWindow (result, cacheType) { + const staleWhileRevalidate = result.cacheControlDirectives?.['stale-while-revalidate'] + if (!staleWhileRevalidate || staleResponseRequiresRevalidation(result, cacheType)) { + return false + } - if (upgrade && !isValidHeaderValue(upgrade)) { - throw new InvalidArgumentError('invalid upgrade header') - } + const now = Date.now() + const staleWhileRevalidateExpiry = result.staleAt + (staleWhileRevalidate * 1000) + return now <= staleWhileRevalidateExpiry +} - if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('invalid headersTimeout') +/** + * @param {DispatchFn} dispatch + * @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} globalOpts + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey + * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler + * @param {import('../../types/dispatcher.d.ts').default.RequestOptions} opts + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} reqCacheControl + */ +function handleUncachedResponse ( + dispatch, + globalOpts, + cacheKey, + handler, + opts, + reqCacheControl +) { + if (reqCacheControl?.['only-if-cached']) { + let aborted = false + + const controller = { + paused: false, + rawHeaders: [], + rawTrailers: [], + pause () { + this.paused = true + }, + resume () { + this.paused = false + }, + abort: (reason) => { + aborted = true + handler.onResponseError?.(controller, reason ?? new AbortError()) + } } - if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('invalid bodyTimeout') - } + try { + handler.onRequestStart?.(controller, null) - if (reset != null && typeof reset !== 'boolean') { - throw new InvalidArgumentError('invalid reset') - } + if (aborted) { + return + } - if (expectContinue != null && typeof expectContinue !== 'boolean') { - throw new InvalidArgumentError('invalid expectContinue') - } + handler.onResponseStart?.(controller, 504, {}, 'Gateway Timeout') + if (aborted) { + return + } - this.headersTimeout = headersTimeout + handler.onResponseEnd?.(controller, {}) + } catch (err) { + if (typeof handler.onResponseError === 'function') { + handler.onResponseError(controller, err) + } + } - this.bodyTimeout = bodyTimeout + return true + } - this.throwOnError = throwOnError === true + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)) +} - this.method = method +/** + * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler + * @param {import('../../types/dispatcher.d.ts').default.RequestOptions} opts + * @param {import('../../types/cache-interceptor.d.ts').default.GetResult} result + * @param {number} age + * @param {any} context + * @param {boolean} isStale + */ +function sendCachedValue (handler, opts, result, age, context, isStale) { + // TODO (perf): Readable.from path can be optimized... + const stream = util.isStream(result.body) + ? result.body + : Readable.from(result.body ?? []) - this.abort = null + assert(!stream.destroyed, 'stream should not be destroyed') + assert(!stream.readableDidRead, 'stream should not be readableDidRead') - if (body == null) { - this.body = null - } else if (isStream(body)) { - this.body = body + let aborted = false + let abortReason = null - const rState = this.body._readableState - if (!rState || !rState.autoDestroy) { - this.endHandler = function autoDestroy () { - destroy(this) - } - this.body.on('end', this.endHandler) + const controller = { + rawHeaders: [], + rawTrailers: [], + resume () { + stream.resume() + }, + pause () { + stream.pause() + }, + get paused () { + return stream.isPaused() + }, + get aborted () { + return aborted + }, + get reason () { + return abortReason + }, + abort (reason) { + if (aborted) { + return } + aborted = true + abortReason = reason ?? new AbortError() + stream.destroy(abortReason) + } + } - this.errorHandler = err => { - if (this.abort) { - this.abort(err) + stream + .on('error', function (err) { + if (!this.readableEnded) { + if (typeof handler.onResponseError === 'function') { + handler.onResponseError(controller, err) } else { - this.error = err + throw err } } - this.body.on('error', this.errorHandler) - } else if (isBuffer(body)) { - this.body = body.byteLength ? body : null - } else if (ArrayBuffer.isView(body)) { - this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null - } else if (body instanceof ArrayBuffer) { - this.body = body.byteLength ? Buffer.from(body) : null - } else if (typeof body === 'string') { - this.body = body.length ? Buffer.from(body) : null - } else if (isFormDataLike(body) || isIterable(body) || isBlobLike(body)) { - this.body = body - } else { - throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') - } + }) + .on('close', function () { + if (!this.errored) { + handler.onResponseEnd?.(controller, {}) + } + }) - this.completed = false + handler.onRequestStart?.(controller, context) - this.aborted = false + if (stream.destroyed) { + return + } - this.upgrade = upgrade || null + // Add the age header + // https://www.rfc-editor.org/rfc/rfc9111.html#name-age + const headers = { ...result.headers, age: String(age) } - this.path = query ? buildURL(path, query) : path + if (isStale) { + // Add warning header + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning + headers.warning = '110 - "response is stale"' + } - this.origin = origin + controller.rawHeaders = util.toRawHeaders(headers) - this.idempotent = idempotent == null - ? method === 'HEAD' || method === 'GET' - : idempotent + handler.onResponseStart?.(controller, result.statusCode, headers, result.statusMessage) - this.blocking = blocking == null ? false : blocking + if (opts.method === 'HEAD') { + stream.destroy() + } else { + stream.on('data', function (chunk) { + handler.onResponseData?.(controller, chunk) + }) + } +} - this.reset = reset == null ? null : reset +/** + * @param {DispatchFn} dispatch + * @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} globalOpts + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey + * @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler + * @param {import('../../types/dispatcher.d.ts').default.RequestOptions} opts + * @param {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives | undefined} reqCacheControl + * @param {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined} result + */ +function handleResult ( + dispatch, + globalOpts, + cacheKey, + handler, + opts, + reqCacheControl, + result +) { + if (!result) { + return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl) + } - this.host = null + // Shared stores may outlive the Undici version that wrote them. Do not + // re-serve a Set-Cookie header from an existing shared-cache entry. + if (globalOpts.type === 'shared' && Object.hasOwn(result.headers, 'set-cookie')) { + if (util.isStream(result.body)) { + result.body.on('error', nop).destroy() + } - this.contentLength = null + deleteCachedValue(globalOpts.store, cacheKey) + return handleUncachedResponse(dispatch, globalOpts, cacheKey, handler, opts, reqCacheControl) + } - this.contentType = null + const now = Date.now() + if (now > result.deleteAt) { + // Response is expired, cache store shouldn't have given this to us + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)) + } - this.headers = [] + const age = Math.round((now - result.cachedAt) / 1000) + const requestMaxAgeExpired = reqCacheControl?.['max-age'] !== undefined && age >= reqCacheControl['max-age'] - // Only for H2 - this.expectContinue = expectContinue != null ? expectContinue : false + const stale = requestMaxAgeExpired || isStale(result, reqCacheControl, globalOpts.type) + const revalidate = requestMaxAgeExpired || needsRevalidation(result, reqCacheControl, opts) - if (Array.isArray(headers)) { - if (headers.length % 2 !== 0) { - throw new InvalidArgumentError('headers array must be even') - } - for (let i = 0; i < headers.length; i += 2) { - processHeader(this, headers[i], headers[i + 1]) - } - } else if (headers && typeof headers === 'object') { - if (headers[Symbol.iterator]) { - for (const header of headers) { - if (!Array.isArray(header) || header.length !== 2) { - throw new InvalidArgumentError('headers must be in key-value pair format') - } - processHeader(this, header[0], header[1]) - } - } else { - const keys = Object.keys(headers) - for (let i = 0; i < keys.length; ++i) { - processHeader(this, keys[i], headers[keys[i]]) - } - } - } else if (headers != null) { - throw new InvalidArgumentError('headers must be an object or an array') + // Check if the response is stale + if (stale || revalidate) { + if (util.isStream(opts.body) && util.bodyLength(opts.body) !== 0) { + // If body is a stream we can't revalidate... + // TODO (fix): This could be less strict... + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)) } - validateHandler(handler, method, upgrade) + // RFC 5861: If we're within stale-while-revalidate window, serve stale immediately + // and revalidate in background, unless immediate revalidation is necessary + if (!revalidate && withinStaleWhileRevalidateWindow(result, globalOpts.type)) { + // Serve stale response immediately + sendCachedValue(handler, opts, result, age, null, true) - this.servername = servername || getServerName(this.host) + // Start background revalidation (fire-and-forget) + queueMicrotask(() => { + const headers = makeRevalidationHeaders(opts, result) - this[kHandler] = handler + // Background revalidation - update cache if we get new data + dispatch( + { + ...opts, + headers + }, + new CacheHandler(globalOpts, cacheKey, { + // Silent handler that just updates the cache + onRequestStart () {}, + onRequestUpgrade () {}, + onResponseStart () {}, + onResponseData () {}, + onResponseEnd () {}, + onResponseError () {} + }) + ) + }) - if (channels.create.hasSubscribers) { - channels.create.publish({ request: this }) + return true } - } - onBodySent (chunk) { - if (this[kHandler].onBodySent) { - try { - return this[kHandler].onBodySent(chunk) - } catch (err) { - this.abort(err) + let withinStaleIfErrorThreshold = false + if (!staleResponseRequiresRevalidation(result, globalOpts.type)) { + const staleIfErrorExpiry = result.cacheControlDirectives['stale-if-error'] ?? reqCacheControl?.['stale-if-error'] + if (staleIfErrorExpiry) { + withinStaleIfErrorThreshold = now < (result.staleAt + (staleIfErrorExpiry * 1000)) } } - } - onRequestSent () { - if (channels.bodySent.hasSubscribers) { - channels.bodySent.publish({ request: this }) - } + const headers = makeRevalidationHeaders(opts, result) - if (this[kHandler].onRequestSent) { - try { - return this[kHandler].onRequestSent() - } catch (err) { - this.abort(err) - } - } + // We need to revalidate the response + return dispatch( + { + ...opts, + headers + }, + new CacheRevalidationHandler( + (success, context, statusCode, headers) => { + if (success) { + if (statusCode === 304) { + if (revalidationResponseDisallowsCachedReuse(globalOpts.type, headers)) { + if (util.isStream(result.body)) { + result.body.on('error', nop).destroy() + } + + deleteCachedValue(globalOpts.store, cacheKey) + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)) + } + + if (revalidationResponseUpdatesCacheControl(headers)) { + deleteCachedValue(globalOpts.store, cacheKey) + } else if (revalidationResponseAddsVary(result, headers.vary ? parseVaryHeader(headers.vary, opts.headers) : undefined)) { + if (util.isStream(result.body)) { + result.body.on('error', nop).destroy() + } + + deleteCachedValue(globalOpts.store, cacheKey) + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)) + } + } + + // TODO: successful revalidation should be considered fresh (not give stale warning). + sendCachedValue(handler, opts, result, age, context, stale) + } else if (util.isStream(result.body)) { + result.body.on('error', nop).destroy() + } + }, + new CacheHandler(globalOpts, cacheKey, handler), + withinStaleIfErrorThreshold + ) + ) } - onConnect (abort) { - assert(!this.aborted) - assert(!this.completed) + // Dump request body. + if (util.isStream(opts.body)) { + opts.body.on('error', nop).destroy() + } - if (this.error) { - abort(this.error) - } else { - this.abort = abort - return this[kHandler].onConnect(abort) - } + sendCachedValue(handler, opts, result, age, null, false) +} + +/** + * @param {import('../../types/cache-interceptor.d.ts').default.CacheOptions} [opts] + * @returns {import('../../types/dispatcher.d.ts').default.DispatcherComposeInterceptor} + */ +module.exports = (opts = {}) => { + const { + store = new MemoryCacheStore(), + methods = ['GET'], + cacheByDefault = undefined, + type = 'shared', + origins = undefined + } = opts + + if (typeof opts !== 'object' || opts === null) { + throw new TypeError(`expected type of opts to be an Object, got ${opts === null ? 'null' : typeof opts}`) } - onResponseStarted () { - return this[kHandler].onResponseStarted?.() + assertCacheStore(store, 'opts.store') + assertCacheMethods(methods, 'opts.methods') + assertCacheOrigins(origins, 'opts.origins') + + if (typeof cacheByDefault !== 'undefined' && typeof cacheByDefault !== 'number') { + throw new TypeError(`expected opts.cacheByDefault to be number or undefined, got ${typeof cacheByDefault}`) } - onHeaders (statusCode, headers, resume, statusText) { - assert(!this.aborted) - assert(!this.completed) + if (typeof type !== 'undefined' && type !== 'shared' && type !== 'private') { + throw new TypeError(`expected opts.type to be shared, private, or undefined, got ${typeof type}`) + } - if (channels.headers.hasSubscribers) { - channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) - } + const globalOpts = { + store, + methods, + cacheByDefault, + type + } - try { - return this[kHandler].onHeaders(statusCode, headers, resume, statusText) - } catch (err) { - this.abort(err) + const safeMethodsToNotCache = [] + for (let i = 0; i < util.safeHTTPMethods.length; i++) { + const method = util.safeHTTPMethods[i] + if (!arrayIncludes(methods, method)) { + safeMethodsToNotCache.push(method) } } - onData (chunk) { - assert(!this.aborted) - assert(!this.completed) + return (dispatch, interceptorOrigin) => { + return (opts, handler) => { + const requestOrigin = getInterceptorOrigin(opts, interceptorOrigin) + if (!requestOrigin || arrayIncludes(safeMethodsToNotCache, opts.method)) { + // We cannot safely cache without an authoritative origin, or this is + // not a method we want to cache. + return dispatch(opts, handler) + } - try { - return this[kHandler].onData(chunk) - } catch (err) { - this.abort(err) - return false + // Check if origin is in whitelist + if (origins !== undefined) { + const normalizedRequestOrigin = requestOrigin.toString().toLowerCase() + let isAllowed = false + + for (let i = 0; i < origins.length; i++) { + const allowed = origins[i] + if (typeof allowed === 'string') { + if (allowed.toLowerCase() === normalizedRequestOrigin) { + isAllowed = true + break + } + } else if (allowed.test(normalizedRequestOrigin)) { + isAllowed = true + break + } + } + + if (!isAllowed) { + return dispatch(opts, handler) + } + } + + opts = { + ...opts, + headers: normalizeHeaders(opts) + } + + const reqCacheControl = opts.headers?.['cache-control'] + ? parseCacheControlHeader(opts.headers['cache-control']) + : hasPragmaNoCache(opts.headers) + ? { 'no-cache': true } + : undefined + + if (reqCacheControl?.['no-store']) { + return dispatch(opts, handler) + } + + /** + * @type {import('../../types/cache-interceptor.d.ts').default.CacheKey} + */ + const cacheKey = makeCacheKey(opts, requestOrigin) + + if (!arrayIncludes(util.safeHTTPMethods, opts.method)) { + return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)) + } + + const result = store.get(cacheKey) + + if (result && typeof result.then === 'function') { + return result + .then(result => handleResult(dispatch, + globalOpts, + cacheKey, + handler, + opts, + reqCacheControl, + result + )) + } else { + return handleResult( + dispatch, + globalOpts, + cacheKey, + handler, + opts, + reqCacheControl, + result + ) + } } } +} - onUpgrade (statusCode, headers, socket) { - assert(!this.aborted) - assert(!this.completed) - return this[kHandler].onUpgrade(statusCode, headers, socket) - } +/***/ }), - onComplete (trailers) { - this.onFinally() +/***/ 557: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - assert(!this.aborted) +"use strict"; + + +const { createInflate, createGunzip, createBrotliDecompress, createZstdDecompress, constants } = __nccwpck_require__(8522) +const { pipeline, Transform: TransformStream } = __nccwpck_require__(7075) +const { InvalidArgumentError, ResponseExceededMaxSizeError } = __nccwpck_require__(8707) +const DecoratorHandler = __nccwpck_require__(8155) + +/** @typedef {import('node:stream').Transform} Transform */ +/** @typedef {import('node:stream').Transform} Controller */ +/** @typedef {Transform&import('node:zlib').Zlib} DecompressorStream */ - this.completed = true - if (channels.trailers.hasSubscribers) { - channels.trailers.publish({ request: this, trailers }) - } +class DecompressController { + #onPause + #onResume + #onAbort + #paused = false - try { - return this[kHandler].onComplete(trailers) - } catch (err) { - // TODO (fix): This might be a bad idea? - this.onError(err) - } + constructor (onPause, onResume, onAbort) { + this.#onPause = onPause + this.#onResume = onResume + this.#onAbort = onAbort + this.target = null } - onError (error) { - this.onFinally() - - if (channels.error.hasSubscribers) { - channels.error.publish({ request: this, error }) + pause () { + if (this.#paused) { + return } - if (this.aborted) { + this.#paused = true + this.#onPause() + } + + resume () { + if (!this.#paused) { return } - this.aborted = true - return this[kHandler].onError(error) + this.#paused = false + this.#onResume() } - onFinally () { - if (this.errorHandler) { - this.body.off('error', this.errorHandler) - this.errorHandler = null - } + abort (reason) { + this.target?.abort(reason) + this.#onAbort(reason) + } - if (this.endHandler) { - this.body.off('end', this.endHandler) - this.endHandler = null + get paused () { return this.#paused } + get aborted () { return this.target?.aborted ?? false } + get reason () { return this.target?.reason ?? null } + get rawHeaders () { return this.target?.rawHeaders ?? null } + set rawHeaders (value) { + if (this.target) { + this.target.rawHeaders = value } } - addHeader (key, value) { - processHeader(this, key, value) - return this + get rawTrailers () { return this.target?.rawTrailers ?? null } + set rawTrailers (value) { + if (this.target) { + this.target.rawTrailers = value + } } } -function processHeader (request, key, val) { - if (val && (typeof val === 'object' && !Array.isArray(val))) { - throw new InvalidArgumentError(`invalid ${key} header`) - } else if (val === undefined) { - return - } +// `compress` and `x-compress` are deliberately absent. RFC 9110 section +// 8.4.1.1 defines them as the UNIX compress (LZW) format, which zlib cannot +// read, so inflating them turns a readable response into a Z_DATA_ERROR. +// fetch() leaves them alone, and so does this interceptor. +/** @type {Record DecompressorStream>} */ +const supportedEncodings = { + __proto__: null, + gzip: createGunzip, + 'x-gzip': createGunzip, + br: createBrotliDecompress, + deflate: createInflate, + // https://www.rfc-editor.org/rfc/rfc9659.html#section-3 + zstd: createZstdDecompress.bind(null, { params: { [constants.ZSTD_d_windowLogMax]: 23 } }) +} - let headerName = headerNameLowerCasedRecord[key] +const defaultSkipStatusCodes = /** @type {const} */ ([204, 304]) +const defaultMaxSize = 0 - if (headerName === undefined) { - headerName = key.toLowerCase() - if (headerNameLowerCasedRecord[headerName] === undefined && !isValidHTTPToken(headerName)) { - throw new InvalidArgumentError('invalid header key') +/** + * Limits the output of one stage in a decompression chain. + * @param {number} maxSize - Maximum output size in bytes + * @returns {Transform} + */ +function createMaxSizeLimiter (maxSize) { + let size = 0 + + return new TransformStream({ + transform (chunk, _encoding, callback) { + const decompressedSize = size + chunk.length + if (decompressedSize > maxSize) { + callback(new ResponseExceededMaxSizeError( + `Decompressed response size (${decompressedSize}) exceeded maxSize (${maxSize})` + )) + return + } + + size = decompressedSize + callback(null, chunk) } - } + }) +} - if (Array.isArray(val)) { - const arr = [] - for (let i = 0; i < val.length; i++) { - if (typeof val[i] === 'string') { - if (!isValidHeaderValue(val[i])) { - throw new InvalidArgumentError(`invalid ${key} header`) +let warningEmitted = /** @type {boolean} */ (false) + +/** + * @typedef {Object} DecompressHandlerOptions + * @property {number[]|Readonly} [skipStatusCodes=[204, 304]] - List of status codes to skip decompression for + * @property {boolean} [skipErrorResponses] - Whether to skip decompression for error responses (status codes >= 400) + * @property {number} [maxSize=0] - Maximum decompressed response size in bytes. 0 disables the limit + */ + +class DecompressHandler extends DecoratorHandler { + /** @type {Transform[]} */ + #decompressors = [] + /** @type {Record | undefined} */ + #trailers + /** @type {Readonly} */ + #skipStatusCodes + /** @type {boolean} */ + #skipErrorResponses + /** @type {number} */ + #maxSize + /** @type {number} */ + #decompressedSize = 0 + /** @type {boolean} */ + #terminated = false + /** @type {boolean} */ + #inputEnded = false + /** @type {boolean} */ + #inputBackpressured = false + /** @type {boolean} */ + #upstreamPaused = false + /** @type {boolean} */ + #draining = false + /** @type {boolean} */ + #drainRequested = false + /** @type {boolean} */ + #completionPending = false + /** @type {DecompressorStream | undefined} */ + #finalDecompressor + /** @type {DecompressController} */ + #controller + + constructor (handler, { skipStatusCodes = defaultSkipStatusCodes, skipErrorResponses = true, maxSize = defaultMaxSize } = {}) { + if (!Number.isSafeInteger(maxSize) || maxSize < 0) { + throw new InvalidArgumentError('maxSize must be a non-negative integer') + } + + super(handler) + this.#skipStatusCodes = skipStatusCodes + this.#skipErrorResponses = skipErrorResponses + this.#maxSize = maxSize + this.#controller = new DecompressController( + () => this.#onDownstreamPause(), + () => this.#onDownstreamResume(), + reason => { + if (this.#inputEnded && !this.#terminated) { + this.onResponseError(this.#controller, reason) } - arr.push(val[i]) - } else if (val[i] === null) { - arr.push('') - } else if (typeof val[i] === 'object') { - throw new InvalidArgumentError(`invalid ${key} header`) - } else { - arr.push(`${val[i]}`) } - } - val = arr - } else if (typeof val === 'string') { - if (!isValidHeaderValue(val)) { - throw new InvalidArgumentError(`invalid ${key} header`) - } - } else if (val === null) { - val = '' - } else { - val = `${val}` + ) } - if (headerName === 'host') { - if (request.host !== null) { - throw new InvalidArgumentError('duplicate host header') - } - if (typeof val !== 'string') { - throw new InvalidArgumentError('invalid host header') - } - // Consumed by Client - request.host = val - } else if (headerName === 'content-length') { - if (request.contentLength !== null) { - throw new InvalidArgumentError('duplicate content-length header') - } - request.contentLength = parseInt(val, 10) - if (!Number.isFinite(request.contentLength)) { - throw new InvalidArgumentError('invalid content-length header') - } - } else if (request.contentType === null && headerName === 'content-type') { - request.contentType = val - request.headers.push(key, val) - } else if (headerName === 'transfer-encoding' || headerName === 'keep-alive' || headerName === 'upgrade') { - throw new InvalidArgumentError(`invalid ${headerName} header`) - } else if (headerName === 'connection') { - const value = typeof val === 'string' ? val.toLowerCase() : null - if (value !== 'close' && value !== 'keep-alive') { - throw new InvalidArgumentError('invalid connection header') + #onDownstreamPause () { + this.#pauseUpstream() + } + + #onDownstreamResume () { + const drainWasDeferred = this.#draining + this.#drainOutput() + if (!drainWasDeferred) { + this.#resumeUpstreamIfNeeded() + this.#finishIfReady() } + } - if (value === 'close') { - request.reset = true + #pauseUpstream () { + if (!this.#upstreamPaused && !this.#terminated) { + this.#upstreamPaused = true + this.#controller.target?.pause() } - } else if (headerName === 'expect') { - throw new NotSupportedError('expect header not supported') - } else { - request.headers.push(key, val) } -} -module.exports = Request + #resumeUpstreamIfNeeded () { + if (this.#upstreamPaused && !this.#controller.paused && !this.#inputBackpressured) { + this.#upstreamPaused = false + if (!this.#inputEnded) { + this.#controller.target?.resume() + } + } + } + #drainOutput () { + if (this.#terminated || this.#controller.paused || !this.#finalDecompressor) { + return + } -/***/ }), + if (this.#draining) { + this.#drainRequested = true + return + } -/***/ 6443: -/***/ ((module) => { + this.#draining = true + try { + do { + this.#drainRequested = false + let chunk + while (!this.#terminated && !this.#controller.paused && (chunk = this.#finalDecompressor.read()) !== null) { + if (this.#maxSize > 0) { + const decompressedSize = this.#decompressedSize + chunk.length + if (decompressedSize > this.#maxSize) { + this.#fail(new ResponseExceededMaxSizeError( + `Decompressed response size (${decompressedSize}) exceeded maxSize (${this.#maxSize})` + )) + return + } -module.exports = { - kClose: Symbol('close'), - kDestroy: Symbol('destroy'), - kDispatch: Symbol('dispatch'), - kUrl: Symbol('url'), - kWriting: Symbol('writing'), - kResuming: Symbol('resuming'), - kQueue: Symbol('queue'), - kConnect: Symbol('connect'), - kConnecting: Symbol('connecting'), - kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), - kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), - kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), - kKeepAliveTimeoutValue: Symbol('keep alive timeout'), - kKeepAlive: Symbol('keep alive'), - kHeadersTimeout: Symbol('headers timeout'), - kBodyTimeout: Symbol('body timeout'), - kServerName: Symbol('server name'), - kLocalAddress: Symbol('local address'), - kHost: Symbol('host'), - kNoRef: Symbol('no ref'), - kBodyUsed: Symbol('used'), - kBody: Symbol('abstracted request body'), - kRunning: Symbol('running'), - kBlocking: Symbol('blocking'), - kPending: Symbol('pending'), - kSize: Symbol('size'), - kBusy: Symbol('busy'), - kQueued: Symbol('queued'), - kFree: Symbol('free'), - kConnected: Symbol('connected'), - kClosed: Symbol('closed'), - kNeedDrain: Symbol('need drain'), - kReset: Symbol('reset'), - kDestroyed: Symbol.for('nodejs.stream.destroyed'), - kResume: Symbol('resume'), - kOnError: Symbol('on error'), - kMaxHeadersSize: Symbol('max headers size'), - kRunningIdx: Symbol('running index'), - kPendingIdx: Symbol('pending index'), - kError: Symbol('error'), - kClients: Symbol('clients'), - kClient: Symbol('client'), - kParser: Symbol('parser'), - kOnDestroyed: Symbol('destroy callbacks'), - kPipelining: Symbol('pipelining'), - kSocket: Symbol('socket'), - kHostHeader: Symbol('host header'), - kConnector: Symbol('connector'), - kStrictContentLength: Symbol('strict content length'), - kMaxRedirections: Symbol('maxRedirections'), - kMaxRequests: Symbol('maxRequestsPerClient'), - kProxy: Symbol('proxy agent options'), - kCounter: Symbol('socket request counter'), - kInterceptors: Symbol('dispatch interceptors'), - kMaxResponseSize: Symbol('max response size'), - kHTTP2Session: Symbol('http2Session'), - kHTTP2SessionState: Symbol('http2Session state'), - kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), - kConstruct: Symbol('constructable'), - kListeners: Symbol('listeners'), - kHTTPContext: Symbol('http context'), - kMaxConcurrentStreams: Symbol('max concurrent streams'), - kNoProxyAgent: Symbol('no proxy agent'), - kHttpProxyAgent: Symbol('http proxy agent'), - kHttpsProxyAgent: Symbol('https proxy agent') -} + this.#decompressedSize = decompressedSize + } + try { + const result = super.onResponseData(this.#controller, chunk) + if (result === false && !this.#controller.paused) { + this.#controller.pause() + } + } catch (err) { + this.#fail(err) + return + } + } + } while (this.#drainRequested && !this.#terminated && !this.#controller.paused) + } finally { + this.#draining = false + } -/***/ }), + this.#resumeUpstreamIfNeeded() + this.#finishIfReady() + } -/***/ 7752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + #finishIfReady () { + if (this.#terminated || !this.#completionPending || this.#controller.paused || this.#draining) { + return + } -"use strict"; + this.#cleanupDecompressors() + try { + super.onResponseEnd(this.#controller, this.#trailers) + } catch (err) { + this.#fail(err) + return + } + this.#terminated = true + } + #onDecompressionEnd () { + if (this.#terminated) { + return + } -const { - wellknownHeaderNames, - headerNameLowerCasedRecord -} = __nccwpck_require__(735) + this.#completionPending = true + this.#drainOutput() + this.#finishIfReady() + } -class TstNode { - /** @type {any} */ - value = null - /** @type {null | TstNode} */ - left = null - /** @type {null | TstNode} */ - middle = null - /** @type {null | TstNode} */ - right = null - /** @type {number} */ - code /** - * @param {string} key - * @param {any} value - * @param {number} index + * Determines if decompression should be skipped based on encoding and status code + * @param {string} contentEncoding - Content-Encoding header value + * @param {number} statusCode - HTTP status code of the response + * @returns {boolean} - True if decompression should be skipped */ - constructor (key, value, index) { - if (index === undefined || index >= key.length) { - throw new TypeError('Unreachable') - } - const code = this.code = key.charCodeAt(index) - // check code is ascii string - if (code > 0x7F) { - throw new TypeError('key must be ascii string') - } - if (key.length !== ++index) { - this.middle = new TstNode(key, value, index) - } else { - this.value = value - } + #shouldSkipDecompression (contentEncoding, statusCode) { + if (!contentEncoding || statusCode < 200) return true + if (this.#skipStatusCodes.includes(statusCode)) return true + if (this.#skipErrorResponses && statusCode >= 400) return true + return false } /** - * @param {string} key - * @param {any} value + * Creates a chain of decompressors for multiple content encodings + * + * @param {string} encodings - Comma-separated list of content encodings + * @returns {Array} - Array of decompressor and limiting streams + * @throws {Error} - If the number of content-encodings exceeds the maximum allowed */ - add (key, value) { - const length = key.length - if (length === 0) { - throw new TypeError('Unreachable') + #createDecompressionChain (encodings) { + const parts = encodings.split(',') + + // Limit the number of content-encodings to prevent resource exhaustion. + // CVE fix similar to urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206). + const maxContentEncodings = 5 + if (parts.length > maxContentEncodings) { + throw new Error(`too many content-encodings in response: ${parts.length}, maximum allowed is ${maxContentEncodings}`) } - let index = 0 - let node = this - while (true) { - const code = key.charCodeAt(index) - // check code is ascii string - if (code > 0x7F) { - throw new TypeError('key must be ascii string') + + /** @type {DecompressorStream[]} */ + const decompressors = [] + + for (let i = parts.length - 1; i >= 0; i--) { + const encoding = parts[i].trim() + if (!encoding) continue + + if (!supportedEncodings[encoding]) { + decompressors.length = 0 // Clear if unsupported encoding + return decompressors // Unsupported encoding } - if (node.code === code) { - if (length === ++index) { - node.value = value - break - } else if (node.middle !== null) { - node = node.middle - } else { - node.middle = new TstNode(key, value, index) - break - } - } else if (node.code < code) { - if (node.left !== null) { - node = node.left - } else { - node.left = new TstNode(key, value, index) - break - } - } else if (node.right !== null) { - node = node.right - } else { - node.right = new TstNode(key, value, index) - break + + decompressors.push(supportedEncodings[encoding]()) + } + + if (decompressors.length < 2) { + return decompressors + } + + /** @type {Transform[]} */ + const streams = [] + for (let i = 0; i < decompressors.length; i++) { + streams.push(decompressors[i]) + if (i < decompressors.length - 1 && this.#maxSize > 0) { + streams.push(createMaxSizeLimiter(this.#maxSize)) } } + + return streams } /** - * @param {Uint8Array} key - * @return {TstNode | null} + * Stops decompression and reports an error. + * @param {Error} error - The decompression error + * @returns {void} */ - search (key) { - const keylength = key.length - let index = 0 - let node = this - while (node !== null && index < keylength) { - let code = key[index] - // A-Z - // First check if it is bigger than 0x5a. - // Lowercase letters have higher char codes than uppercase ones. - // Also we assume that headers will mostly contain lowercase characters. - if (code <= 0x5a && code >= 0x41) { - // Lowercase for uppercase. - code |= 32 - } - while (node !== null) { - if (code === node.code) { - if (keylength === ++index) { - // Returns Node since it is the last key. - return node - } - node = node.middle - break - } - node = node.code < code ? node.left : node.right - } + #fail (error) { + if (this.#terminated) { + return } - return null - } -} - -class TernarySearchTree { - /** @type {TstNode | null} */ - node = null - /** - * @param {string} key - * @param {any} value - * */ - insert (key, value) { - if (this.node === null) { - this.node = new TstNode(key, value, 0) + if (this.#inputEnded) { + // The request is already marked complete once the compressed input ends, + // so controller.abort() can no longer propagate decoder flush errors. + this.onResponseError(this.#controller, error) } else { - this.node.add(key, value) + this.#controller.abort(error) } } /** - * @param {Uint8Array} key - * @return {any} + * Sets up event handlers for the final decompressor stream. + * @param {DecompressorStream} decompressor - The decompressor stream + * @returns {void} */ - lookup (key) { - return this.node?.search(key)?.value ?? null + #setupDecompressorEvents (decompressor) { + this.#finalDecompressor = decompressor + decompressor.on('readable', () => this.#drainOutput()) + decompressor.on('error', (error) => this.#fail(error)) } -} - -const tree = new TernarySearchTree() -for (let i = 0; i < wellknownHeaderNames.length; ++i) { - const key = headerNameLowerCasedRecord[wellknownHeaderNames[i]] - tree.insert(key, key) -} + /** + * Sets up event handling for a single decompressor + * @returns {void} + */ + #setupSingleDecompressor () { + const decompressor = this.#decompressors[0] + this.#setupDecompressorEvents(decompressor) -module.exports = { - TernarySearchTree, - tree -} + decompressor.on('end', () => this.#onDecompressionEnd()) + } + /** + * Sets up event handling for multiple chained decompressors using pipeline + * @returns {void} + */ + #setupMultipleDecompressors () { + const lastDecompressor = this.#decompressors[this.#decompressors.length - 1] + this.#setupDecompressorEvents(lastDecompressor) -/***/ }), + pipeline(this.#decompressors, (err) => { + if (this.#terminated) { + return + } -/***/ 3440: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (err) { + this.#fail(err) + return + } -"use strict"; + this.#onDecompressionEnd() + }) + } + #setupInputBackpressure () { + const decompressor = this.#decompressors[0] + decompressor.on('drain', () => { + if (this.#terminated) { + return + } -const assert = __nccwpck_require__(4589) -const { kDestroyed, kBodyUsed, kListeners, kBody } = __nccwpck_require__(6443) -const { IncomingMessage } = __nccwpck_require__(7067) -const stream = __nccwpck_require__(7075) -const net = __nccwpck_require__(7030) -const { Blob } = __nccwpck_require__(4573) -const nodeUtil = __nccwpck_require__(7975) -const { stringify } = __nccwpck_require__(1792) -const { EventEmitter: EE } = __nccwpck_require__(8474) -const { InvalidArgumentError } = __nccwpck_require__(8707) -const { headerNameLowerCasedRecord } = __nccwpck_require__(735) -const { tree } = __nccwpck_require__(7752) + this.#inputBackpressured = false + if (!this.#controller.paused) { + this.#drainOutput() + this.#resumeUpstreamIfNeeded() + } + }) + } -const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) + /** + * Cleans up decompressor references to prevent memory leaks + * @returns {void} + */ + #cleanupDecompressors () { + this.#decompressors.length = 0 + this.#finalDecompressor = undefined + } -class BodyAsyncIterable { - constructor (body) { - this[kBody] = body - this[kBodyUsed] = false + onRequestStart (controller, context) { + this.#controller.target = controller + return super.onRequestStart(this.#controller, context) } - async * [Symbol.asyncIterator] () { - assert(!this[kBodyUsed], 'disturbed') - this[kBodyUsed] = true - yield * this[kBody] + onRequestUpgrade (controller, statusCode, headers, socket) { + return super.onRequestUpgrade(this.#controller, statusCode, headers, socket) } -} -function wrapRequestBody (body) { - if (isStream(body)) { - // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp - // so that it can be dispatched again? - // TODO (fix): Do we need 100-expect support to provide a way to do this properly? - if (bodyLength(body) === 0) { - body - .on('data', function () { - assert(false) - }) - } + /** + * @param {Controller} controller + * @param {number} statusCode + * @param {Record} headers + * @param {string} statusMessage + * @returns {void} + */ + onResponseStart (controller, statusCode, headers, statusMessage) { + // Repeated field lines reach us as an array. RFC 9110 section 5.3 lets a + // recipient join them with commas, which yields the single-line form the + // decompression chain already handles. + const rawContentEncoding = headers['content-encoding'] + const contentEncoding = Array.isArray(rawContentEncoding) + ? rawContentEncoding.join(',') + : rawContentEncoding - if (typeof body.readableDidRead !== 'boolean') { - body[kBodyUsed] = false - EE.prototype.on.call(body, 'data', function () { - this[kBodyUsed] = true - }) + // If content encoding is not supported or status code is in skip list + if (this.#shouldSkipDecompression(contentEncoding, statusCode)) { + return super.onResponseStart(this.#controller, statusCode, headers, statusMessage) } - return body - } else if (body && typeof body.pipeTo === 'function') { - // TODO (fix): We can't access ReadableStream internal state - // to determine whether or not it has been disturbed. This is just - // a workaround. - return new BodyAsyncIterable(body) - } else if ( - body && - typeof body !== 'string' && - !ArrayBuffer.isView(body) && - isIterable(body) - ) { - // TODO: Should we allow re-using iterable if !this.opts.idempotent - // or through some other flag? - return new BodyAsyncIterable(body) - } else { - return body - } -} + const decompressors = this.#createDecompressionChain(contentEncoding.toLowerCase()) -function nop () {} + if (decompressors.length === 0) { + this.#cleanupDecompressors() + return super.onResponseStart(this.#controller, statusCode, headers, statusMessage) + } -function isStream (obj) { - return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' -} + this.#decompressors = decompressors -// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) -function isBlobLike (object) { - if (object === null) { - return false - } else if (object instanceof Blob) { - return true - } else if (typeof object !== 'object') { - return false - } else { - const sTag = object[Symbol.toStringTag] + // Remove compression headers since we're decompressing + const { 'content-encoding': _, 'content-length': __, ...newHeaders } = headers - return (sTag === 'Blob' || sTag === 'File') && ( - ('stream' in object && typeof object.stream === 'function') || - ('arrayBuffer' in object && typeof object.arrayBuffer === 'function') - ) - } -} + if (this.#controller.rawHeaders) { + const rawHeaders = this.#controller.rawHeaders -function buildURL (url, queryParams) { - if (url.includes('?') || url.includes('#')) { - throw new Error('Query params cannot be passed when url already contains "?" or "#".') - } + if (Array.isArray(rawHeaders)) { + const filteredHeaders = [] + for (let i = 0; i < rawHeaders.length; i += 2) { + const headerName = rawHeaders[i] + const name = Buffer.isBuffer(headerName) ? headerName.toString('latin1') : `${headerName}` + const lowerName = name.toLowerCase() - const stringified = stringify(queryParams) + if (lowerName === 'content-encoding' || lowerName === 'content-length') { + continue + } - if (stringified) { - url += '?' + stringified - } + filteredHeaders.push(rawHeaders[i], rawHeaders[i + 1]) + } + rawHeaders.splice(0, rawHeaders.length, ...filteredHeaders) + } else if (typeof rawHeaders === 'object') { + for (const name of Object.keys(rawHeaders)) { + const lowerName = name.toLowerCase() + if (lowerName === 'content-encoding' || lowerName === 'content-length') { + delete rawHeaders[name] + } + } + } + } - return url -} + this.#setupInputBackpressure() + if (this.#decompressors.length === 1) { + this.#setupSingleDecompressor() + } else { + this.#setupMultipleDecompressors() + } -function isValidPort (port) { - const value = parseInt(port, 10) - return ( - value === Number(port) && - value >= 0 && - value <= 65535 - ) -} + return super.onResponseStart(this.#controller, statusCode, newHeaders, statusMessage) + } -function isHttpOrHttpsPrefixed (value) { - return ( - value != null && - value[0] === 'h' && - value[1] === 't' && - value[2] === 't' && - value[3] === 'p' && - ( - value[4] === ':' || - ( - value[4] === 's' && - value[5] === ':' - ) - ) - ) -} + /** + * @param {Controller} controller + * @param {Buffer} chunk + * @returns {void} + */ + onResponseData (controller, chunk) { + if (this.#decompressors.length > 0) { + if (!this.#decompressors[0].write(chunk)) { + this.#inputBackpressured = true + this.#pauseUpstream() + } + return + } + return super.onResponseData(this.#controller, chunk) + } -function parseURL (url) { - if (typeof url === 'string') { - url = new URL(url) + /** + * @param {Controller} controller + * @param {Record | undefined} trailers + * @returns {void} + */ + onResponseEnd (controller, trailers) { + if (this.#decompressors.length > 0) { + this.#inputEnded = true + this.#trailers = trailers + this.#decompressors[0].end() + return + } + return super.onResponseEnd(this.#controller, trailers) + } - if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + /** + * @param {Controller} controller + * @param {Error} err + * @returns {void} + */ + onResponseError (controller, err) { + if (this.#terminated) { + return } - return url + this.#terminated = true + for (const decompressor of this.#decompressors) { + decompressor.destroy() + } + this.#cleanupDecompressors() + super.onResponseError(this.#controller, err) } +} - if (!url || typeof url !== 'object') { - throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') +/** + * Creates a decompression interceptor for HTTP responses + * @param {DecompressHandlerOptions} [options] - Options for the interceptor + * @returns {Function} - Interceptor function + */ +function createDecompressInterceptor (options = {}) { + // Emit experimental warning only once + if (!warningEmitted) { + process.emitWarning( + 'DecompressInterceptor is experimental and subject to change', + 'ExperimentalWarning' + ) + warningEmitted = true } - if (!(url instanceof URL)) { - if (url.port != null && url.port !== '' && isValidPort(url.port) === false) { - throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') - } + return (dispatch) => { + return (opts, handler) => { + if (opts.method === 'HEAD') { + return dispatch(opts, handler) + } - if (url.path != null && typeof url.path !== 'string') { - throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') + const decompressHandler = new DecompressHandler(handler, options) + return dispatch(opts, decompressHandler) } + } +} - if (url.pathname != null && typeof url.pathname !== 'string') { - throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') - } +module.exports = createDecompressInterceptor - if (url.hostname != null && typeof url.hostname !== 'string') { - throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') - } - if (url.origin != null && typeof url.origin !== 'string') { - throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') - } +/***/ }), - if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') - } +/***/ 7240: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - const port = url.port != null - ? url.port - : (url.protocol === 'https:' ? 443 : 80) - let origin = url.origin != null - ? url.origin - : `${url.protocol || ''}//${url.hostname || ''}:${port}` - let path = url.path != null - ? url.path - : `${url.pathname || ''}${url.search || ''}` +"use strict"; - if (origin[origin.length - 1] === '/') { - origin = origin.slice(0, origin.length - 1) - } - if (path && path[0] !== '/') { - path = `/${path}` - } - // new URL(path, origin) is unsafe when `path` contains an absolute URL - // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: - // If first parameter is a relative URL, second param is required, and will be used as the base URL. - // If first parameter is an absolute URL, a given second param will be ignored. - return new URL(`${origin}${path}`) +const diagnosticsChannel = __nccwpck_require__(3053) +const util = __nccwpck_require__(3440) +const DeduplicationHandler = __nccwpck_require__(3599) +const { getInterceptorOrigin, normalizeHeaders, makeCacheKey, makeDeduplicationKey } = __nccwpck_require__(7659) + +const pendingRequestsChannel = diagnosticsChannel.channel('undici:request:pending-requests') + +/** + * @param {import('../../types/interceptors.d.ts').default.DeduplicateInterceptorOpts} [opts] + * @returns {import('../../types/dispatcher.d.ts').default.DispatcherComposeInterceptor} + */ +module.exports = (opts = {}) => { + const { + methods = ['GET'], + skipHeaderNames = [], + excludeHeaderNames = [], + maxBufferSize = 5 * 1024 * 1024 + } = opts + + if (typeof opts !== 'object' || opts === null) { + throw new TypeError(`expected type of opts to be an Object, got ${opts === null ? 'null' : typeof opts}`) } - if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + if (!Array.isArray(methods)) { + throw new TypeError(`expected opts.methods to be an array, got ${typeof methods}`) } - return url -} + for (const method of methods) { + if (!util.safeHTTPMethods.includes(method)) { + throw new TypeError(`expected opts.methods to only contain safe HTTP methods, got ${method}`) + } + } -function parseOrigin (url) { - url = parseURL(url) + if (!Array.isArray(skipHeaderNames)) { + throw new TypeError(`expected opts.skipHeaderNames to be an array, got ${typeof skipHeaderNames}`) + } - if (url.pathname !== '/' || url.search || url.hash) { - throw new InvalidArgumentError('invalid url') + if (!Array.isArray(excludeHeaderNames)) { + throw new TypeError(`expected opts.excludeHeaderNames to be an array, got ${typeof excludeHeaderNames}`) } - return url -} + if (!Number.isFinite(maxBufferSize) || maxBufferSize <= 0) { + throw new TypeError(`expected opts.maxBufferSize to be a positive finite number, got ${maxBufferSize}`) + } -function getHostname (host) { - if (host[0] === '[') { - const idx = host.indexOf(']') + // Convert to lowercase Set for case-insensitive header matching + const skipHeaderNamesSet = new Set(skipHeaderNames.map(name => name.toLowerCase())) - assert(idx !== -1) - return host.substring(1, idx) - } + // Convert to lowercase Set for case-insensitive header exclusion from deduplication key + const excludeHeaderNamesSet = new Set(excludeHeaderNames.map(name => name.toLowerCase())) - const idx = host.indexOf(':') - if (idx === -1) return host + /** + * Map of pending requests for deduplication + * @type {Map} + */ + const pendingRequests = new Map() - return host.substring(0, idx) -} + return (dispatch, interceptorOrigin) => { + return (opts, handler) => { + const requestOrigin = getInterceptorOrigin(opts, interceptorOrigin) + if (!requestOrigin || opts.upgrade || methods.includes(opts.method) === false) { + return dispatch(opts, handler) + } -// IP addresses are not valid server names per RFC6066 -// > Currently, the only server names supported are DNS hostnames -function getServerName (host) { - if (!host) { - return null - } + opts = { + ...opts, + headers: normalizeHeaders(opts) + } - assert(typeof host === 'string') + // Skip deduplication if request contains any of the specified headers + if (skipHeaderNamesSet.size > 0) { + for (const headerName of Object.keys(opts.headers)) { + if (skipHeaderNamesSet.has(headerName.toLowerCase())) { + return dispatch(opts, handler) + } + } + } - const servername = getHostname(host) - if (net.isIP(servername)) { - return '' - } + const cacheKey = makeCacheKey(opts, requestOrigin) + const dedupeKey = makeDeduplicationKey(cacheKey, excludeHeaderNamesSet) - return servername -} + // Check if there's already a pending request for this key + const pendingHandler = pendingRequests.get(dedupeKey) + if (pendingHandler) { + // Add this handler to the waiting list when safe. + // If body streaming has already started, this request must be sent independently. + if (pendingHandler.addWaitingHandler(handler)) { + return true + } -function deepClone (obj) { - return JSON.parse(JSON.stringify(obj)) -} + return dispatch(opts, handler) + } -function isAsyncIterable (obj) { - return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') -} + // Create a new deduplication handler + const deduplicationHandler = new DeduplicationHandler( + handler, + () => { + // Clean up when request completes + pendingRequests.delete(dedupeKey) + if (pendingRequestsChannel.hasSubscribers) { + pendingRequestsChannel.publish({ size: pendingRequests.size, key: dedupeKey, type: 'removed' }) + } + }, + maxBufferSize + ) -function isIterable (obj) { - return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) -} + // Register the pending request + pendingRequests.set(dedupeKey, deduplicationHandler) + if (pendingRequestsChannel.hasSubscribers) { + pendingRequestsChannel.publish({ size: pendingRequests.size, key: dedupeKey, type: 'added' }) + } -function bodyLength (body) { - if (body == null) { - return 0 - } else if (isStream(body)) { - const state = body._readableState - return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) - ? state.length - : null - } else if (isBlobLike(body)) { - return body.size != null ? body.size : null - } else if (isBuffer(body)) { - return body.byteLength + return dispatch(opts, deduplicationHandler) + } } +} - return null + +/***/ }), + +/***/ 379: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + +const { isIP } = __nccwpck_require__(7030) +const { lookup } = __nccwpck_require__(610) +const DecoratorHandler = __nccwpck_require__(8155) +const { InvalidArgumentError, InformationalError } = __nccwpck_require__(8707) +const { kRequestOrigin } = __nccwpck_require__(6443) +const maxInt = Math.pow(2, 31) - 1 + +function hasSafeIterator (headers) { + const prototype = Object.getPrototypeOf(headers) + const ownIterator = Object.hasOwn(headers, Symbol.iterator) + return ownIterator || (prototype != null && prototype !== Object.prototype && typeof headers[Symbol.iterator] === 'function') } -function isDestroyed (body) { - return body && !!(body.destroyed || body[kDestroyed] || (stream.isDestroyed?.(body))) +function isHostHeader (key) { + return typeof key === 'string' && key.toLowerCase() === 'host' } -function destroy (stream, err) { - if (stream == null || !isStream(stream) || isDestroyed(stream)) { - return +function normalizeHeaders (headers) { + if (headers == null) { + return null } - if (typeof stream.destroy === 'function') { - if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { - // See: https://github.com/nodejs/node/pull/38505/files - stream.socket = null + if (Array.isArray(headers)) { + if (headers.length === 0 || !Array.isArray(headers[0])) { + return headers } - stream.destroy(err) - } else if (err) { - queueMicrotask(() => { - stream.emit('error', err) - }) - } + const normalized = [] + for (const header of headers) { + if (Array.isArray(header) && header.length === 2) { + normalized.push(header[0], header[1]) + } else { + normalized.push(header) + } + } - if (stream.destroyed !== true) { - stream[kDestroyed] = true + return normalized } -} -const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/ -function parseKeepAliveTimeout (val) { - const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR) - return m ? parseInt(m[1], 10) * 1000 : null -} + if (typeof headers === 'object' && hasSafeIterator(headers)) { + const normalized = [] + for (const header of headers) { + if (Array.isArray(header) && header.length === 2) { + normalized.push(header[0], header[1]) + } else { + normalized.push(header) + } + } -/** - * Retrieves a header name and returns its lowercase value. - * @param {string | Buffer} value Header name - * @returns {string} - */ -function headerNameToString (value) { - return typeof value === 'string' - ? headerNameLowerCasedRecord[value] ?? value.toLowerCase() - : tree.lookup(value) ?? value.toString('latin1').toLowerCase() -} + return normalized + } -/** - * Receive the buffer as a string and return its lowercase value. - * @param {Buffer} value Header name - * @returns {string} - */ -function bufferToLowerCasedHeaderName (value) { - return tree.lookup(value) ?? value.toString('latin1').toLowerCase() + return headers } -/** - * @param {Record | (Buffer | string | (Buffer | string)[])[]} headers - * @param {Record} [obj] - * @returns {Record} - */ -function parseHeaders (headers, obj) { - if (obj === undefined) obj = {} - for (let i = 0; i < headers.length; i += 2) { - const key = headerNameToString(headers[i]) - let val = obj[key] +function hasHostHeader (headers) { + if (headers == null) { + return false + } - if (val) { - if (typeof val === 'string') { - val = [val] - obj[key] = val - } - val.push(headers[i + 1].toString('utf8')) - } else { - const headersValue = headers[i + 1] - if (typeof headersValue === 'string') { - obj[key] = headersValue - } else { - obj[key] = Array.isArray(headersValue) ? headersValue.map(x => x.toString('utf8')) : headersValue.toString('utf8') + if (Array.isArray(headers)) { + if (headers.length === 0) { + return false + } + + for (let i = 0; i < headers.length; i += 2) { + if (isHostHeader(headers[i])) { + return true } } + + return false } - // See https://github.com/nodejs/node/pull/46528 - if ('content-length' in obj && 'content-disposition' in obj) { - obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1') + if (typeof headers === 'object') { + for (const key in headers) { + if (isHostHeader(key)) { + return true + } + } } - return obj + return false } -function parseRawHeaders (headers) { - const len = headers.length - const ret = new Array(len) - - let hasContentLength = false - let contentDispositionIdx = -1 - let key - let val - let kLen = 0 +function withHostHeader (host, headers) { + const normalizedHeaders = normalizeHeaders(headers) - for (let n = 0; n < headers.length; n += 2) { - key = headers[n] - val = headers[n + 1] + if (hasHostHeader(normalizedHeaders)) { + return normalizedHeaders + } - typeof key !== 'string' && (key = key.toString()) - typeof val !== 'string' && (val = val.toString('utf8')) + if (Array.isArray(normalizedHeaders)) { + return ['host', host, ...normalizedHeaders] + } - kLen = key.length - if (kLen === 14 && key[7] === '-' && (key === 'content-length' || key.toLowerCase() === 'content-length')) { - hasContentLength = true - } else if (kLen === 19 && key[7] === '-' && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { - contentDispositionIdx = n + 1 + if (normalizedHeaders && typeof normalizedHeaders === 'object') { + return { + host, + ...normalizedHeaders } - ret[n] = key - ret[n + 1] = val } - // See https://github.com/nodejs/node/pull/46528 - if (hasContentLength && contentDispositionIdx !== -1) { - ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1') + return { host } +} + +class DNSStorage { + #maxItems = 0 + #records = new Map() + + constructor (opts) { + this.#maxItems = opts.maxItems + } + + get size () { + return this.#records.size } - return ret -} - -function isBuffer (buffer) { - // See, https://github.com/mcollina/undici/pull/319 - return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) -} + get (hostname) { + return this.#records.get(hostname) ?? null + } -function validateHandler (handler, method, upgrade) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') + set (hostname, records) { + this.#records.set(hostname, records) } - if (typeof handler.onConnect !== 'function') { - throw new InvalidArgumentError('invalid onConnect method') + delete (hostname) { + this.#records.delete(hostname) } - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') + // Delegate to storage decide can we do more lookups or not + full () { + return this.size >= this.#maxItems } +} - if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { - throw new InvalidArgumentError('invalid onBodySent method') +class DNSInstance { + #maxTTL = 0 + #maxItems = 0 + dualStack = true + affinity = null + lookup = null + pick = null + storage = null + + constructor (opts) { + this.#maxTTL = opts.maxTTL + this.#maxItems = opts.maxItems + this.dualStack = opts.dualStack + this.affinity = opts.affinity + this.lookup = opts.lookup ?? this.#defaultLookup + this.pick = opts.pick ?? this.#defaultPick + this.storage = opts.storage ?? new DNSStorage(opts) } - if (upgrade || method === 'CONNECT') { - if (typeof handler.onUpgrade !== 'function') { - throw new InvalidArgumentError('invalid onUpgrade method') - } - } else { - if (typeof handler.onHeaders !== 'function') { - throw new InvalidArgumentError('invalid onHeaders method') - } + runLookup (origin, opts, cb) { + const ips = this.storage.get(origin.hostname) - if (typeof handler.onData !== 'function') { - throw new InvalidArgumentError('invalid onData method') + // If full, we just return the origin + if (ips == null && this.storage.full()) { + cb(null, origin) + return } - if (typeof handler.onComplete !== 'function') { - throw new InvalidArgumentError('invalid onComplete method') + const newOpts = { + affinity: this.affinity, + dualStack: this.dualStack, + lookup: this.lookup, + pick: this.pick, + ...opts.dns, + maxTTL: this.#maxTTL, + maxItems: this.#maxItems } - } -} - -// A body is disturbed if it has been read from and it cannot -// be re-used without losing state or data. -function isDisturbed (body) { - // TODO (fix): Why is body[kBodyUsed] needed? - return !!(body && (stream.isDisturbed(body) || body[kBodyUsed])) -} -function isErrored (body) { - return !!(body && stream.isErrored(body)) -} + // If no IPs we lookup + if (ips == null) { + this.lookup(origin, newOpts, (err, addresses) => { + if (err || addresses == null || addresses.length === 0) { + cb(err ?? new InformationalError('No DNS entries found')) + return + } -function isReadable (body) { - return !!(body && stream.isReadable(body)) -} + this.setRecords(origin, addresses) + const records = this.storage.get(origin.hostname) -function getSocketInfo (socket) { - return { - localAddress: socket.localAddress, - localPort: socket.localPort, - remoteAddress: socket.remoteAddress, - remotePort: socket.remotePort, - remoteFamily: socket.remoteFamily, - timeout: socket.timeout, - bytesWritten: socket.bytesWritten, - bytesRead: socket.bytesRead - } -} + const ip = this.pick( + origin, + records, + newOpts.affinity + ) -/** @type {globalThis['ReadableStream']} */ -function ReadableStreamFrom (iterable) { - // We cannot use ReadableStream.from here because it does not return a byte stream. + // The lookup succeeded, but nothing it returned is usable here: with + // dualStack disabled and an affinity set, records of the other family + // cannot be picked. Running the lookup again would return the same + // records, so report it the way an empty result is reported. + if (ip == null) { + this.storage.delete(origin.hostname) + cb(new InformationalError('No DNS entries found')) + return + } - let iterator - return new ReadableStream( - { - async start () { - iterator = iterable[Symbol.asyncIterator]() - }, - async pull (controller) { - const { done, value } = await iterator.next() - if (done) { - queueMicrotask(() => { - controller.close() - controller.byobRequest?.respond(0) - }) + let port + if (typeof ip.port === 'number') { + port = `:${ip.port}` + } else if (origin.port !== '') { + port = `:${origin.port}` } else { - const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) - if (buf.byteLength) { - controller.enqueue(new Uint8Array(buf)) - } + port = '' } - return controller.desiredSize > 0 - }, - async cancel (reason) { - await iterator.return() - }, - type: 'bytes' - } - ) -} -// The chunk should be a FormData instance and contains -// all the required methods. -function isFormDataLike (object) { - return ( - object && - typeof object === 'object' && - typeof object.append === 'function' && - typeof object.delete === 'function' && - typeof object.get === 'function' && - typeof object.getAll === 'function' && - typeof object.has === 'function' && - typeof object.set === 'function' && - object[Symbol.toStringTag] === 'FormData' - ) -} + cb( + null, + new URL(`${origin.protocol}//${ + ip.family === 6 ? `[${ip.address}]` : ip.address + }${port}`) + ) + }) + } else { + // If there's IPs we pick + const ip = this.pick( + origin, + ips, + newOpts.affinity + ) -function addAbortListener (signal, listener) { - if ('addEventListener' in signal) { - signal.addEventListener('abort', listener, { once: true }) - return () => signal.removeEventListener('abort', listener) + // If no IPs we lookup - deleting old records + if (ip == null) { + this.storage.delete(origin.hostname) + this.runLookup(origin, opts, cb) + return + } + + let port + if (typeof ip.port === 'number') { + port = `:${ip.port}` + } else if (origin.port !== '') { + port = `:${origin.port}` + } else { + port = '' + } + + cb( + null, + new URL(`${origin.protocol}//${ + ip.family === 6 ? `[${ip.address}]` : ip.address + }${port}`) + ) + } } - signal.addListener('abort', listener) - return () => signal.removeListener('abort', listener) -} -const hasToWellFormed = typeof String.prototype.toWellFormed === 'function' -const hasIsWellFormed = typeof String.prototype.isWellFormed === 'function' + #defaultLookup (origin, opts, cb) { + lookup( + origin.hostname, + { + all: true, + family: this.dualStack === false ? this.affinity : 0, + order: 'ipv4first' + }, + (err, addresses) => { + if (err) { + return cb(err) + } -/** - * @param {string} val - */ -function toUSVString (val) { - return hasToWellFormed ? `${val}`.toWellFormed() : nodeUtil.toUSVString(val) -} + const results = new Map() -/** - * @param {string} val - */ -// TODO: move this to webidl -function isUSVString (val) { - return hasIsWellFormed ? `${val}`.isWellFormed() : toUSVString(val) === `${val}` -} + for (const addr of addresses) { + // On linux we found duplicates, we attempt to remove them with + // the latest record + results.set(`${addr.address}:${addr.family}`, addr) + } -/** - * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 - * @param {number} c - */ -function isTokenCharCode (c) { - switch (c) { - case 0x22: - case 0x28: - case 0x29: - case 0x2c: - case 0x2f: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0x40: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x7b: - case 0x7d: - // DQUOTE and "(),/:;<=>?@[\]{}" - return false - default: - // VCHAR %x21-7E - return c >= 0x21 && c <= 0x7e + cb(null, results.values()) + } + ) } -} -/** - * @param {string} characters - */ -function isValidHTTPToken (characters) { - if (characters.length === 0) { - return false - } - for (let i = 0; i < characters.length; ++i) { - if (!isTokenCharCode(characters.charCodeAt(i))) { - return false - } - } - return true -} + #defaultPick (origin, hostnameRecords, affinity) { + let ip = null + const { records, offset } = hostnameRecords -// headerCharRegex have been lifted from -// https://github.com/nodejs/node/blob/main/lib/_http_common.js + let family + if (this.dualStack) { + if (affinity == null) { + // Balance between ip families + if (offset == null || offset === maxInt) { + hostnameRecords.offset = 0 + affinity = 4 + } else { + hostnameRecords.offset++ + affinity = (hostnameRecords.offset & 1) === 1 ? 6 : 4 + } + } -/** - * Matches if val contains an invalid field-vchar - * field-value = *( field-content / obs-fold ) - * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] - * field-vchar = VCHAR / obs-text - */ -const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ + if (records[affinity] != null && records[affinity].ips.length > 0) { + family = records[affinity] + } else { + family = records[affinity === 4 ? 6 : 4] + } + } else { + family = records[affinity] + } -/** - * @param {string} characters - */ -function isValidHeaderValue (characters) { - return !headerCharRegex.test(characters) -} + // If no IPs we return null + if (family == null || family.ips.length === 0) { + return ip + } -// Parsed accordingly to RFC 9110 -// https://www.rfc-editor.org/rfc/rfc9110#field.content-range -function parseRangeHeader (range) { - if (range == null || range === '') return { start: 0, end: null, size: null } + if (family.offset == null || family.offset === maxInt) { + family.offset = 0 + } else { + family.offset++ + } - const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null - return m - ? { - start: parseInt(m[1]), - end: m[2] ? parseInt(m[2]) : null, - size: m[3] ? parseInt(m[3]) : null - } - : null -} + const position = family.offset % family.ips.length + ip = family.ips[position] ?? null + + if (ip == null) { + return ip + } -function addListener (obj, name, listener) { - const listeners = (obj[kListeners] ??= []) - listeners.push([name, listener]) - obj.on(name, listener) - return obj -} + if (Date.now() - ip.timestamp > ip.ttl) { // record TTL is already in ms + // We delete expired records + // It is possible that they have different TTL, so we manage them individually + family.ips.splice(position, 1) + return this.pick(origin, hostnameRecords, affinity) + } -function removeAllListeners (obj) { - for (const [name, listener] of obj[kListeners] ?? []) { - obj.removeListener(name, listener) + return ip } - obj[kListeners] = null -} -function errorRequest (client, request, err) { - try { - request.onError(err) - assert(request.aborted) - } catch (err) { - client.emit('error', err) - } -} + pickFamily (origin, ipFamily) { + const records = this.storage.get(origin.hostname)?.records + if (!records) { + return null + } -const kEnumerableProperty = Object.create(null) -kEnumerableProperty.enumerable = true + const family = records[ipFamily] + if (!family) { + return null + } -const normalizedMethodRecordsBase = { - delete: 'DELETE', - DELETE: 'DELETE', - get: 'GET', - GET: 'GET', - head: 'HEAD', - HEAD: 'HEAD', - options: 'OPTIONS', - OPTIONS: 'OPTIONS', - post: 'POST', - POST: 'POST', - put: 'PUT', - PUT: 'PUT' -} + if (family.offset == null || family.offset === maxInt) { + family.offset = 0 + } else { + family.offset++ + } -const normalizedMethodRecords = { - ...normalizedMethodRecordsBase, - patch: 'patch', - PATCH: 'PATCH' -} + const position = family.offset % family.ips.length + const ip = family.ips[position] ?? null + if (ip == null) { + return ip + } -// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. -Object.setPrototypeOf(normalizedMethodRecordsBase, null) -Object.setPrototypeOf(normalizedMethodRecords, null) + if (Date.now() - ip.timestamp > ip.ttl) { // record TTL is already in ms + // We delete expired records + // It is possible that they have different TTL, so we manage them individually + family.ips.splice(position, 1) + return this.pickFamily(origin, ipFamily) + } -module.exports = { - kEnumerableProperty, - nop, - isDisturbed, - isErrored, - isReadable, - toUSVString, - isUSVString, - isBlobLike, - parseOrigin, - parseURL, - getServerName, - isStream, - isIterable, - isAsyncIterable, - isDestroyed, - headerNameToString, - bufferToLowerCasedHeaderName, - addListener, - removeAllListeners, - errorRequest, - parseRawHeaders, - parseHeaders, - parseKeepAliveTimeout, - destroy, - bodyLength, - deepClone, - ReadableStreamFrom, - isBuffer, - validateHandler, - getSocketInfo, - isFormDataLike, - buildURL, - addAbortListener, - isValidHTTPToken, - isValidHeaderValue, - isTokenCharCode, - parseRangeHeader, - normalizedMethodRecordsBase, - normalizedMethodRecords, - isValidPort, - isHttpOrHttpsPrefixed, - nodeMajor, - nodeMinor, - safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'], - wrapRequestBody -} + return ip + } + setRecords (origin, addresses) { + const timestamp = Date.now() + const records = { records: { 4: null, 6: null } } + let minTTL = this.#maxTTL + for (const record of addresses) { + record.timestamp = timestamp + if (typeof record.ttl === 'number') { + // The record TTL is expected to be in ms + record.ttl = Math.min(record.ttl, this.#maxTTL) + minTTL = Math.min(minTTL, record.ttl) + } else { + record.ttl = this.#maxTTL + } -/***/ }), + const familyRecords = records.records[record.family] ?? { ips: [] } -/***/ 7405: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + familyRecords.ips.push(record) + records.records[record.family] = familyRecords + } -"use strict"; + // We provide a default TTL if external storage will be used without TTL per record-level support + this.storage.set(origin.hostname, records, { ttl: minTTL }) + } + deleteRecords (origin) { + this.storage.delete(origin.hostname) + } -const { InvalidArgumentError } = __nccwpck_require__(8707) -const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = __nccwpck_require__(6443) -const DispatcherBase = __nccwpck_require__(1841) -const Pool = __nccwpck_require__(628) -const Client = __nccwpck_require__(3701) -const util = __nccwpck_require__(3440) -const createRedirectInterceptor = __nccwpck_require__(5092) + getHandler (meta, opts) { + return new DNSDispatchHandler(this, meta, opts) + } +} -const kOnConnect = Symbol('onConnect') -const kOnDisconnect = Symbol('onDisconnect') -const kOnConnectionError = Symbol('onConnectionError') -const kMaxRedirections = Symbol('maxRedirections') -const kOnDrain = Symbol('onDrain') -const kFactory = Symbol('factory') -const kOptions = Symbol('options') +class DNSDispatchHandler extends DecoratorHandler { + #state = null + #opts = null + #dispatch = null + #origin = null + #controller = null + #newOrigin = null + #firstTry = true -function defaultFactory (origin, opts) { - return opts && opts.connections === 1 - ? new Client(origin, opts) - : new Pool(origin, opts) -} + constructor (state, { origin, handler, dispatch, newOrigin }, opts) { + super(handler) + this.#origin = origin + this.#newOrigin = newOrigin + this.#opts = { ...opts } + this.#state = state + this.#dispatch = dispatch + } -class Agent extends DispatcherBase { - constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { - super() + onResponseError (controller, err) { + switch (err.code) { + case 'ETIMEDOUT': + case 'ECONNREFUSED': { + if (this.#state.dualStack) { + if (!this.#firstTry) { + super.onResponseError(controller, err) + return + } + this.#firstTry = false - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') - } + // Pick an ip address from the other family + const otherFamily = this.#newOrigin.hostname[0] === '[' ? 4 : 6 + const ip = this.#state.pickFamily(this.#origin, otherFamily) + if (ip == null) { + super.onResponseError(controller, err) + return + } - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } + let port + if (typeof ip.port === 'number') { + port = `:${ip.port}` + } else if (this.#origin.port !== '') { + port = `:${this.#origin.port}` + } else { + port = '' + } - if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } + const dispatchOpts = { + ...this.#opts, + origin: `${this.#origin.protocol}//${ + ip.family === 6 ? `[${ip.address}]` : ip.address + }${port}`, + [kRequestOrigin]: this.#opts[kRequestOrigin] === undefined + ? this.#origin + : this.#opts[kRequestOrigin], + headers: withHostHeader(this.#origin.host, this.#opts.headers) + } + this.#dispatch(dispatchOpts, this) + return + } - if (connect && typeof connect !== 'function') { - connect = { ...connect } + // if dual-stack disabled, we error out + super.onResponseError(controller, err) + break + } + case 'ENOTFOUND': + this.#state.deleteRecords(this.#origin) + super.onResponseError(controller, err) + break + default: + super.onResponseError(controller, err) + break } + } +} + +module.exports = interceptorOpts => { + if ( + interceptorOpts?.maxTTL != null && + (typeof interceptorOpts?.maxTTL !== 'number' || interceptorOpts?.maxTTL < 0) + ) { + throw new InvalidArgumentError('Invalid maxTTL. Must be a positive number') + } - this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) - ? options.interceptors.Agent - : [createRedirectInterceptor({ maxRedirections })] + if ( + interceptorOpts?.maxItems != null && + (typeof interceptorOpts?.maxItems !== 'number' || + interceptorOpts?.maxItems < 1) + ) { + throw new InvalidArgumentError( + 'Invalid maxItems. Must be a positive number and greater than zero' + ) + } - this[kOptions] = { ...util.deepClone(options), connect } - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined - this[kMaxRedirections] = maxRedirections - this[kFactory] = factory - this[kClients] = new Map() + if ( + interceptorOpts?.affinity != null && + interceptorOpts?.affinity !== 4 && + interceptorOpts?.affinity !== 6 + ) { + throw new InvalidArgumentError('Invalid affinity. Must be either 4 or 6') + } - this[kOnDrain] = (origin, targets) => { - this.emit('drain', origin, [this, ...targets]) - } + if ( + interceptorOpts?.dualStack != null && + typeof interceptorOpts?.dualStack !== 'boolean' + ) { + throw new InvalidArgumentError('Invalid dualStack. Must be a boolean') + } - this[kOnConnect] = (origin, targets) => { - this.emit('connect', origin, [this, ...targets]) - } + if ( + interceptorOpts?.lookup != null && + typeof interceptorOpts?.lookup !== 'function' + ) { + throw new InvalidArgumentError('Invalid lookup. Must be a function') + } - this[kOnDisconnect] = (origin, targets, err) => { - this.emit('disconnect', origin, [this, ...targets], err) - } + if ( + interceptorOpts?.pick != null && + typeof interceptorOpts?.pick !== 'function' + ) { + throw new InvalidArgumentError('Invalid pick. Must be a function') + } - this[kOnConnectionError] = (origin, targets, err) => { - this.emit('connectionError', origin, [this, ...targets], err) - } + if ( + interceptorOpts?.storage != null && + (typeof interceptorOpts?.storage?.get !== 'function' || + typeof interceptorOpts?.storage?.set !== 'function' || + typeof interceptorOpts?.storage?.full !== 'function' || + typeof interceptorOpts?.storage?.delete !== 'function' + ) + ) { + throw new InvalidArgumentError('Invalid storage. Must be a object with methods: { get, set, full, delete }') } - get [kRunning] () { - let ret = 0 - for (const client of this[kClients].values()) { - ret += client[kRunning] - } - return ret + const dualStack = interceptorOpts?.dualStack ?? true + let affinity + if (dualStack) { + affinity = interceptorOpts?.affinity ?? null + } else { + affinity = interceptorOpts?.affinity ?? 4 } - [kDispatch] (opts, handler) { - let key - if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { - key = String(opts.origin) - } else { - throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') - } + const opts = { + maxTTL: interceptorOpts?.maxTTL ?? 10e3, // Expressed in ms + lookup: interceptorOpts?.lookup ?? null, + pick: interceptorOpts?.pick ?? null, + dualStack, + affinity, + maxItems: interceptorOpts?.maxItems ?? Infinity, + storage: interceptorOpts?.storage + } - let dispatcher = this[kClients].get(key) + const instance = new DNSInstance(opts) - if (!dispatcher) { - dispatcher = this[kFactory](opts.origin, this[kOptions]) - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]) + return dispatch => { + return function dnsInterceptor (origDispatchOpts, handler) { + if (origDispatchOpts.origin == null) { + return dispatch(origDispatchOpts, handler) + } - // This introduces a tiny memory leak, as dispatchers are never removed from the map. - // TODO(mcollina): remove te timer when the client/pool do not have any more - // active connections. - this[kClients].set(key, dispatcher) - } + const origin = + origDispatchOpts.origin.constructor === URL + ? origDispatchOpts.origin + : new URL(origDispatchOpts.origin) - return dispatcher.dispatch(opts, handler) - } + if (isIP(origin.hostname) !== 0) { + return dispatch(origDispatchOpts, handler) + } - async [kClose] () { - const closePromises = [] - for (const client of this[kClients].values()) { - closePromises.push(client.close()) - } - this[kClients].clear() + instance.runLookup(origin, origDispatchOpts, (err, newOrigin) => { + if (err) { + return handler.onResponseError(null, err) + } - await Promise.all(closePromises) - } + const dispatchOpts = { + ...origDispatchOpts, + servername: origin.hostname, // For SNI on TLS + origin: newOrigin.origin, + [kRequestOrigin]: origDispatchOpts[kRequestOrigin] === undefined + ? origin + : origDispatchOpts[kRequestOrigin], + headers: withHostHeader(origin.host, origDispatchOpts.headers) + } - async [kDestroy] (err) { - const destroyPromises = [] - for (const client of this[kClients].values()) { - destroyPromises.push(client.destroy(err)) - } - this[kClients].clear() + dispatch( + dispatchOpts, + instance.getHandler( + { origin, dispatch, handler, newOrigin }, + origDispatchOpts + ) + ) + }) - await Promise.all(destroyPromises) + return true + } } } -module.exports = Agent - /***/ }), -/***/ 837: +/***/ 8060: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { - BalancedPoolMissingUpstreamError, - InvalidArgumentError -} = __nccwpck_require__(8707) -const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher -} = __nccwpck_require__(2128) -const Pool = __nccwpck_require__(628) -const { kUrl, kInterceptors } = __nccwpck_require__(6443) -const { parseOrigin } = __nccwpck_require__(3440) -const kFactory = Symbol('factory') +const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8707) +const DecoratorHandler = __nccwpck_require__(8155) -const kOptions = Symbol('options') -const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') -const kCurrentWeight = Symbol('kCurrentWeight') -const kIndex = Symbol('kIndex') -const kWeight = Symbol('kWeight') -const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') -const kErrorPenalty = Symbol('kErrorPenalty') +class DumpHandler extends DecoratorHandler { + #maxSize = 1024 * 1024 + #dumped = false + #size = 0 + aborted = false + reason = false -/** - * Calculate the greatest common divisor of two numbers by - * using the Euclidean algorithm. - * - * @param {number} a - * @param {number} b - * @returns {number} - */ -function getGreatestCommonDivisor (a, b) { - if (a === 0) return b + constructor ({ maxSize, signal }, handler) { + if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) { + throw new InvalidArgumentError('maxSize must be a number greater than 0') + } - while (b !== 0) { - const t = b - b = a % b - a = t + super(handler) + + this.#maxSize = maxSize ?? this.#maxSize + // this.#handler = handler } - return a -} -function defaultFactory (origin, opts) { - return new Pool(origin, opts) -} + #abort (reason) { + this.aborted = true + this.reason = reason + } -class BalancedPool extends PoolBase { - constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { - super() + onRequestStart (controller, context) { + controller.abort = this.#abort.bind(this) - this[kOptions] = opts - this[kIndex] = -1 - this[kCurrentWeight] = 0 + return super.onRequestStart(controller, context) + } - this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 - this[kErrorPenalty] = this[kOptions].errorPenalty || 15 + onResponseStart (controller, statusCode, headers, statusMessage) { + const contentLength = headers['content-length'] - if (!Array.isArray(upstreams)) { - upstreams = [upstreams] + if (contentLength != null && contentLength > this.#maxSize) { + throw new RequestAbortedError( + `Response size (${contentLength}) larger than maxSize (${ + this.#maxSize + })` + ) } - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') + if (this.aborted === true) { + return true } - this[kInterceptors] = opts.interceptors?.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) - ? opts.interceptors.BalancedPool - : [] - this[kFactory] = factory + return super.onResponseStart(controller, statusCode, headers, statusMessage) + } - for (const upstream of upstreams) { - this.addUpstream(upstream) - } - this._updateBalancedPoolStats() + onResponseError (controller, err) { + super.onResponseError(controller, this.aborted === true ? this.reason : err) } - addUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin + onResponseData (controller, chunk) { + this.#size = this.#size + chunk.length - if (this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - ))) { - return this + if (this.#size > this.#maxSize) { + throw new RequestAbortedError( + `Response size (${this.#size}) larger than maxSize (${this.#maxSize})` + ) } - const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])) - - this[kAddClient](pool) - pool.on('connect', () => { - pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]) - }) - - pool.on('connectionError', () => { - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) - this._updateBalancedPoolStats() - }) - - pool.on('disconnect', (...args) => { - const err = args[2] - if (err && err.code === 'UND_ERR_SOCKET') { - // decrease the weight of the pool. - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) - this._updateBalancedPoolStats() - } - }) - for (const client of this[kClients]) { - client[kWeight] = this[kMaxWeightPerServer] + if (this.#size === this.#maxSize) { + this.#dumped = true } - this._updateBalancedPoolStats() - - return this + return true } - _updateBalancedPoolStats () { - let result = 0 - for (let i = 0; i < this[kClients].length; i++) { - result = getGreatestCommonDivisor(this[kClients][i][kWeight], result) + onResponseEnd (controller, trailers) { + if (this.aborted === true) { + super.onResponseError(controller, this.reason) + return } - this[kGreatestCommonDivisor] = result + super.onResponseEnd(controller, this.#dumped ? {} : trailers) } +} - removeUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin - - const pool = this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - )) - - if (pool) { - this[kRemoveClient](pool) - } - - return this +function createDumpInterceptor ( + { maxSize: defaultMaxSize } = { + maxSize: 1024 * 1024 } +) { + return dispatch => { + return function Intercept (opts, handler) { + const { dumpMaxSize = defaultMaxSize } = opts - get upstreams () { - return this[kClients] - .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) - .map((p) => p[kUrl].origin) - } + const dumpHandler = new DumpHandler({ maxSize: dumpMaxSize, signal: opts.signal }, handler) - [kGetDispatcher] () { - // We validate that pools is greater than 0, - // otherwise we would have to wait until an upstream - // is added, which might never happen. - if (this[kClients].length === 0) { - throw new BalancedPoolMissingUpstreamError() + return dispatch(opts, dumpHandler) } + } +} - const dispatcher = this[kClients].find(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )) - - if (!dispatcher) { - return - } +module.exports = createDumpInterceptor - const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true) - if (allClientsBusy) { - return - } +/***/ }), - let counter = 0 +/***/ 1514: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]) +"use strict"; - while (counter++ < this[kClients].length) { - this[kIndex] = (this[kIndex] + 1) % this[kClients].length - const pool = this[kClients][this[kIndex]] - // find pool index with the largest weight - if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { - maxWeightIndex = this[kIndex] - } +const RedirectHandler = __nccwpck_require__(8754) - // decrease the current weight every `this[kClients].length`. - if (this[kIndex] === 0) { - // Set the current weight to the next lower weight. - this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor] +function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections, throwOnMaxRedirect: defaultThrowOnMaxRedirect, stripHeadersOnRedirect: defaultStripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect: defaultStripHeadersOnCrossOriginRedirect } = {}) { + return (dispatch) => { + return function Intercept (opts, handler) { + const { maxRedirections = defaultMaxRedirections, throwOnMaxRedirect = defaultThrowOnMaxRedirect, stripHeadersOnRedirect = defaultStripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect = defaultStripHeadersOnCrossOriginRedirect, ...rest } = opts - if (this[kCurrentWeight] <= 0) { - this[kCurrentWeight] = this[kMaxWeightPerServer] - } - } - if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { - return pool + if (maxRedirections == null || maxRedirections === 0) { + return dispatch(opts, handler) } - } - - this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] - this[kIndex] = maxWeightIndex - return this[kClients][maxWeightIndex] + + const dispatchOpts = { ...rest, throwOnMaxRedirect, stripHeadersOnRedirect, stripHeadersOnCrossOriginRedirect } // Stop sub dispatcher from also redirecting. + const redirectHandler = new RedirectHandler(dispatch, maxRedirections, dispatchOpts, handler) + return dispatch(dispatchOpts, redirectHandler) + } } } -module.exports = BalancedPool +module.exports = createRedirectInterceptor /***/ }), -/***/ 637: +/***/ 8918: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -/* global WebAssembly */ +// const { parseHeaders } = require('../core/util') +const DecoratorHandler = __nccwpck_require__(8155) +const { InvalidArgumentError, ResponseError } = __nccwpck_require__(8707) -const assert = __nccwpck_require__(4589) -const util = __nccwpck_require__(3440) -const { channels } = __nccwpck_require__(2414) -const timers = __nccwpck_require__(6603) -const { - RequestContentLengthMismatchError, - ResponseContentLengthMismatchError, - RequestAbortedError, - HeadersTimeoutError, - HeadersOverflowError, - SocketError, - InformationalError, - BodyTimeoutError, - HTTPParserError, - ResponseExceededMaxSizeError -} = __nccwpck_require__(8707) -const { - kUrl, - kReset, - kClient, - kParser, - kBlocking, - kRunning, - kPending, - kSize, - kWriting, - kQueue, - kNoRef, - kKeepAliveDefaultTimeout, - kHostHeader, - kPendingIdx, - kRunningIdx, - kError, - kPipelining, - kSocket, - kKeepAliveTimeoutValue, - kMaxHeadersSize, - kKeepAliveMaxTimeout, - kKeepAliveTimeoutThreshold, - kHeadersTimeout, - kBodyTimeout, - kStrictContentLength, - kMaxRequests, - kCounter, - kMaxResponseSize, - kOnError, - kResume, - kHTTPContext -} = __nccwpck_require__(6443) +const defaultMaxSize = 1024 * 1024 -const constants = __nccwpck_require__(2824) -const EMPTY_BUF = Buffer.alloc(0) -const FastBuffer = Buffer[Symbol.species] -const addListener = util.addListener -const removeAllListeners = util.removeAllListeners +class ResponseErrorHandler extends DecoratorHandler { + #statusCode + #contentType + #decoder + #headers + #body + #bodySize + #bodyTruncated + #maxSize -let extractBody + constructor ({ maxSize }, { handler }) { + super(handler) + this.#maxSize = maxSize + } -async function lazyllhttp () { - const llhttpWasmData = process.env.JEST_WORKER_ID ? __nccwpck_require__(3870) : undefined + #checkContentType (contentType) { + return (this.#contentType ?? '').indexOf(contentType) === 0 + } - let mod - try { - mod = await WebAssembly.compile(__nccwpck_require__(3434)) - } catch (e) { - /* istanbul ignore next */ + onRequestStart (controller, context) { + this.#statusCode = 0 + this.#contentType = null + this.#decoder = null + this.#headers = null + this.#body = '' + this.#bodySize = 0 + this.#bodyTruncated = false - // We could check if the error was caused by the simd option not - // being enabled, but the occurring of this other error - // * https://github.com/emscripten-core/emscripten/issues/11495 - // got me to remove that check to avoid breaking Node 12. - mod = await WebAssembly.compile(llhttpWasmData || __nccwpck_require__(3870)) + return super.onRequestStart(controller, context) } - return await WebAssembly.instantiate(mod, { - env: { - /* eslint-disable camelcase */ - - wasm_on_url: (p, at, len) => { - /* istanbul ignore next */ - return 0 - }, - wasm_on_status: (p, at, len) => { - assert(currentParser.ptr === p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_begin: (p) => { - assert(currentParser.ptr === p) - return currentParser.onMessageBegin() || 0 - }, - wasm_on_header_field: (p, at, len) => { - assert(currentParser.ptr === p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_header_value: (p, at, len) => { - assert(currentParser.ptr === p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { - assert(currentParser.ptr === p) - return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 - }, - wasm_on_body: (p, at, len) => { - assert(currentParser.ptr === p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_complete: (p) => { - assert(currentParser.ptr === p) - return currentParser.onMessageComplete() || 0 - } + onResponseStart (controller, statusCode, headers, statusMessage) { + this.#statusCode = statusCode + this.#headers = headers + this.#contentType = headers['content-type'] - /* eslint-enable camelcase */ + if (this.#statusCode < 400) { + return super.onResponseStart(controller, statusCode, headers, statusMessage) } - }) -} - -let llhttpInstance = null -let llhttpPromise = lazyllhttp() -llhttpPromise.catch() - -let currentParser = null -let currentBufferRef = null -let currentBufferSize = 0 -let currentBufferPtr = null - -const USE_NATIVE_TIMER = 0 -const USE_FAST_TIMER = 1 - -// Use fast timers for headers and body to take eventual event loop -// latency into account. -const TIMEOUT_HEADERS = 2 | USE_FAST_TIMER -const TIMEOUT_BODY = 4 | USE_FAST_TIMER - -// Use native timers to ignore event loop latency for keep-alive -// handling. -const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER - -class Parser { - constructor (client, socket, { exports }) { - assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0) - - this.llhttp = exports - this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) - this.client = client - this.socket = socket - this.timeout = null - this.timeoutValue = null - this.timeoutType = null - this.statusCode = null - this.statusText = '' - this.upgrade = false - this.headers = [] - this.headersSize = 0 - this.headersMaxSize = client[kMaxHeadersSize] - this.shouldKeepAlive = false - this.paused = false - this.resume = this.resume.bind(this) - - this.bytesRead = 0 - this.keepAlive = '' - this.contentLength = '' - this.connection = '' - this.maxResponseSize = client[kMaxResponseSize] + if (this.#checkContentType('application/json') || this.#checkContentType('text/plain')) { + this.#decoder = new TextDecoder('utf-8') + } } - setTimeout (delay, type) { - // If the existing timer and the new timer are of different timer type - // (fast or native) or have different delay, we need to clear the existing - // timer and set a new one. - if ( - delay !== this.timeoutValue || - (type & USE_FAST_TIMER) ^ (this.timeoutType & USE_FAST_TIMER) - ) { - // If a timeout is already set, clear it with clearTimeout of the fast - // timer implementation, as it can clear fast and native timers. - if (this.timeout) { - timers.clearTimeout(this.timeout) - this.timeout = null - } + #createResponseError () { + this.#body += this.#decoder?.decode(undefined, { stream: false }) ?? '' + this.#decoder = null - if (delay) { - if (type & USE_FAST_TIMER) { - this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this)) - } else { - this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this)) - this.timeout.unref() - } + if (!this.#bodyTruncated && this.#checkContentType('application/json')) { + try { + this.#body = JSON.parse(this.#body) + } catch { + // Do nothing... } + } - this.timeoutValue = delay - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } + let err + const stackTraceLimit = Error.stackTraceLimit + Error.stackTraceLimit = 0 + try { + err = new ResponseError('Response Error', this.#statusCode, { + body: this.#body, + bodyTruncated: this.#bodyTruncated, + headers: this.#headers + }) + } finally { + Error.stackTraceLimit = stackTraceLimit } - this.timeoutType = type + return err } - resume () { - if (this.socket.destroyed || !this.paused) { + onResponseData (controller, chunk) { + if (this.#statusCode < 400) { + return super.onResponseData(controller, chunk) + } + + if (this.#decoder == null) { return } - assert(this.ptr != null) - assert(currentParser == null) + if (this.#maxSize === 0) { + this.#body += this.#decoder.decode(chunk, { stream: true }) + return + } - this.llhttp.llhttp_resume(this.ptr) + const remaining = this.#maxSize - this.#bodySize - assert(this.timeoutType === TIMEOUT_BODY) - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } + if (chunk.length <= remaining) { + this.#bodySize += chunk.length + this.#body += this.#decoder.decode(chunk, { stream: true }) + return } - this.paused = false - this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. - this.readMore() + if (remaining > 0) { + this.#body += this.#decoder.decode(chunk.subarray(0, remaining), { stream: true }) + this.#bodySize = this.#maxSize + } + + this.#bodyTruncated = true + this.#body += this.#decoder.decode(undefined, { stream: false }) + this.#decoder = null } - readMore () { - while (!this.paused && this.ptr) { - const chunk = this.socket.read() - if (chunk === null) { - break - } - this.execute(chunk) + onResponseEnd (controller, trailers) { + if (this.#statusCode >= 400) { + super.onResponseError(controller, this.#createResponseError()) + } else { + super.onResponseEnd(controller, trailers) } } - execute (data) { - assert(this.ptr != null) - assert(currentParser == null) - assert(!this.paused) + onResponseError (controller, err) { + super.onResponseError(controller, err) + } +} - const { socket, llhttp } = this +module.exports = (opts = {}) => { + const { maxSize = defaultMaxSize } = opts - if (data.length > currentBufferSize) { - if (currentBufferPtr) { - llhttp.free(currentBufferPtr) - } - currentBufferSize = Math.ceil(data.length / 4096) * 4096 - currentBufferPtr = llhttp.malloc(currentBufferSize) + if (!Number.isSafeInteger(maxSize) || maxSize < 0) { + throw new InvalidArgumentError('maxSize must be a non-negative integer') + } + + return (dispatch) => { + return function Intercept (opts, handler) { + return dispatch(opts, new ResponseErrorHandler({ maxSize }, { handler })) } + } +} - new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data) - // Call `execute` on the wasm parser. - // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, - // and finally the length of bytes to parse. - // The return value is an error code or `constants.ERROR.OK`. - try { - let ret +/***/ }), - try { - currentBufferRef = data - currentParser = this - ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length) - /* eslint-disable-next-line no-useless-catch */ - } catch (err) { - /* istanbul ignore next: difficult to make a test case for */ - throw err - } finally { - currentParser = null - currentBufferRef = null - } +/***/ 2026: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr +"use strict"; - if (ret === constants.ERROR.PAUSED_UPGRADE) { - this.onUpgrade(data.slice(offset)) - } else if (ret === constants.ERROR.PAUSED) { - this.paused = true - socket.unshift(data.slice(offset)) - } else if (ret !== constants.ERROR.OK) { - const ptr = llhttp.llhttp_get_error_reason(this.ptr) - let message = '' - /* istanbul ignore else: difficult to make a test case for */ - if (ptr) { - const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) - message = - 'Response does not match the HTTP/1.1 protocol (' + - Buffer.from(llhttp.memory.buffer, ptr, len).toString() + - ')' - } - throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) - } - } catch (err) { - util.destroy(socket, err) +const RetryHandler = __nccwpck_require__(7816) + +module.exports = globalOpts => { + return dispatch => { + return function retryInterceptor (opts, handler) { + return dispatch( + opts, + new RetryHandler( + { ...opts, retryOptions: { ...globalOpts, ...opts.retryOptions } }, + { + handler, + dispatch + } + ) + ) } } +} - destroy () { - assert(this.ptr != null) - assert(currentParser == null) - - this.llhttp.llhttp_free(this.ptr) - this.ptr = null - - this.timeout && timers.clearTimeout(this.timeout) - this.timeout = null - this.timeoutValue = null - this.timeoutType = null - - this.paused = false - } - onStatus (buf) { - this.statusText = buf.toString() - } +/***/ }), - onMessageBegin () { - const { socket, client } = this +/***/ 2824: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 - } +"use strict"; - const request = client[kQueue][client[kRunningIdx]] - if (!request) { - return -1 +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SPECIAL_HEADERS = exports.MINOR = exports.MAJOR = exports.HTAB_SP_VCHAR_OBS_TEXT = exports.QUOTED_STRING = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.HEX = exports.URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.STATUSES_HTTP = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.HEADER_STATE = exports.FINISH = exports.STATUSES = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; +const utils_1 = __nccwpck_require__(172); +// Emums +exports.ERROR = { + OK: 0, + INTERNAL: 1, + STRICT: 2, + CR_EXPECTED: 25, + LF_EXPECTED: 3, + UNEXPECTED_CONTENT_LENGTH: 4, + UNEXPECTED_SPACE: 30, + CLOSED_CONNECTION: 5, + INVALID_METHOD: 6, + INVALID_URL: 7, + INVALID_CONSTANT: 8, + INVALID_VERSION: 9, + INVALID_HEADER_TOKEN: 10, + INVALID_CONTENT_LENGTH: 11, + INVALID_CHUNK_SIZE: 12, + INVALID_STATUS: 13, + INVALID_EOF_STATE: 14, + INVALID_TRANSFER_ENCODING: 15, + CB_MESSAGE_BEGIN: 16, + CB_HEADERS_COMPLETE: 17, + CB_MESSAGE_COMPLETE: 18, + CB_CHUNK_HEADER: 19, + CB_CHUNK_COMPLETE: 20, + PAUSED: 21, + PAUSED_UPGRADE: 22, + PAUSED_H2_UPGRADE: 23, + USER: 24, + CB_URL_COMPLETE: 26, + CB_STATUS_COMPLETE: 27, + CB_METHOD_COMPLETE: 32, + CB_VERSION_COMPLETE: 33, + CB_HEADER_FIELD_COMPLETE: 28, + CB_HEADER_VALUE_COMPLETE: 29, + CB_CHUNK_EXTENSION_NAME_COMPLETE: 34, + CB_CHUNK_EXTENSION_VALUE_COMPLETE: 35, + CB_RESET: 31, + CB_PROTOCOL_COMPLETE: 38, +}; +exports.TYPE = { + BOTH: 0, // default + REQUEST: 1, + RESPONSE: 2, +}; +exports.FLAGS = { + CONNECTION_KEEP_ALIVE: 1 << 0, + CONNECTION_CLOSE: 1 << 1, + CONNECTION_UPGRADE: 1 << 2, + CHUNKED: 1 << 3, + UPGRADE: 1 << 4, + CONTENT_LENGTH: 1 << 5, + SKIPBODY: 1 << 6, + TRAILING: 1 << 7, + // 1 << 8 is unused + TRANSFER_ENCODING: 1 << 9, +}; +exports.LENIENT_FLAGS = { + HEADERS: 1 << 0, + CHUNKED_LENGTH: 1 << 1, + KEEP_ALIVE: 1 << 2, + TRANSFER_ENCODING: 1 << 3, + VERSION: 1 << 4, + DATA_AFTER_CLOSE: 1 << 5, + OPTIONAL_LF_AFTER_CR: 1 << 6, + OPTIONAL_CRLF_AFTER_CHUNK: 1 << 7, + OPTIONAL_CR_BEFORE_LF: 1 << 8, + SPACES_AFTER_CHUNK_SIZE: 1 << 9, +}; +exports.METHODS = { + 'DELETE': 0, + 'GET': 1, + 'HEAD': 2, + 'POST': 3, + 'PUT': 4, + /* pathological */ + 'CONNECT': 5, + 'OPTIONS': 6, + 'TRACE': 7, + /* WebDAV */ + 'COPY': 8, + 'LOCK': 9, + 'MKCOL': 10, + 'MOVE': 11, + 'PROPFIND': 12, + 'PROPPATCH': 13, + 'SEARCH': 14, + 'UNLOCK': 15, + 'BIND': 16, + 'REBIND': 17, + 'UNBIND': 18, + 'ACL': 19, + /* subversion */ + 'REPORT': 20, + 'MKACTIVITY': 21, + 'CHECKOUT': 22, + 'MERGE': 23, + /* upnp */ + 'M-SEARCH': 24, + 'NOTIFY': 25, + 'SUBSCRIBE': 26, + 'UNSUBSCRIBE': 27, + /* RFC-5789 */ + 'PATCH': 28, + 'PURGE': 29, + /* CalDAV */ + 'MKCALENDAR': 30, + /* RFC-2068, section 19.6.1.2 */ + 'LINK': 31, + 'UNLINK': 32, + /* icecast */ + 'SOURCE': 33, + /* RFC-7540, section 11.6 */ + 'PRI': 34, + /* RFC-2326 RTSP */ + 'DESCRIBE': 35, + 'ANNOUNCE': 36, + 'SETUP': 37, + 'PLAY': 38, + 'PAUSE': 39, + 'TEARDOWN': 40, + 'GET_PARAMETER': 41, + 'SET_PARAMETER': 42, + 'REDIRECT': 43, + 'RECORD': 44, + /* RAOP */ + 'FLUSH': 45, + /* DRAFT https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-02.html */ + 'QUERY': 46, +}; +exports.STATUSES = { + CONTINUE: 100, + SWITCHING_PROTOCOLS: 101, + PROCESSING: 102, + EARLY_HINTS: 103, + RESPONSE_IS_STALE: 110, // Unofficial + REVALIDATION_FAILED: 111, // Unofficial + DISCONNECTED_OPERATION: 112, // Unofficial + HEURISTIC_EXPIRATION: 113, // Unofficial + MISCELLANEOUS_WARNING: 199, // Unofficial + OK: 200, + CREATED: 201, + ACCEPTED: 202, + NON_AUTHORITATIVE_INFORMATION: 203, + NO_CONTENT: 204, + RESET_CONTENT: 205, + PARTIAL_CONTENT: 206, + MULTI_STATUS: 207, + ALREADY_REPORTED: 208, + TRANSFORMATION_APPLIED: 214, // Unofficial + IM_USED: 226, + MISCELLANEOUS_PERSISTENT_WARNING: 299, // Unofficial + MULTIPLE_CHOICES: 300, + MOVED_PERMANENTLY: 301, + FOUND: 302, + SEE_OTHER: 303, + NOT_MODIFIED: 304, + USE_PROXY: 305, + SWITCH_PROXY: 306, // No longer used + TEMPORARY_REDIRECT: 307, + PERMANENT_REDIRECT: 308, + BAD_REQUEST: 400, + UNAUTHORIZED: 401, + PAYMENT_REQUIRED: 402, + FORBIDDEN: 403, + NOT_FOUND: 404, + METHOD_NOT_ALLOWED: 405, + NOT_ACCEPTABLE: 406, + PROXY_AUTHENTICATION_REQUIRED: 407, + REQUEST_TIMEOUT: 408, + CONFLICT: 409, + GONE: 410, + LENGTH_REQUIRED: 411, + PRECONDITION_FAILED: 412, + PAYLOAD_TOO_LARGE: 413, + URI_TOO_LONG: 414, + UNSUPPORTED_MEDIA_TYPE: 415, + RANGE_NOT_SATISFIABLE: 416, + EXPECTATION_FAILED: 417, + IM_A_TEAPOT: 418, + PAGE_EXPIRED: 419, // Unofficial + ENHANCE_YOUR_CALM: 420, // Unofficial + MISDIRECTED_REQUEST: 421, + UNPROCESSABLE_ENTITY: 422, + LOCKED: 423, + FAILED_DEPENDENCY: 424, + TOO_EARLY: 425, + UPGRADE_REQUIRED: 426, + PRECONDITION_REQUIRED: 428, + TOO_MANY_REQUESTS: 429, + REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL: 430, // Unofficial + REQUEST_HEADER_FIELDS_TOO_LARGE: 431, + LOGIN_TIMEOUT: 440, // Unofficial + NO_RESPONSE: 444, // Unofficial + RETRY_WITH: 449, // Unofficial + BLOCKED_BY_PARENTAL_CONTROL: 450, // Unofficial + UNAVAILABLE_FOR_LEGAL_REASONS: 451, + CLIENT_CLOSED_LOAD_BALANCED_REQUEST: 460, // Unofficial + INVALID_X_FORWARDED_FOR: 463, // Unofficial + REQUEST_HEADER_TOO_LARGE: 494, // Unofficial + SSL_CERTIFICATE_ERROR: 495, // Unofficial + SSL_CERTIFICATE_REQUIRED: 496, // Unofficial + HTTP_REQUEST_SENT_TO_HTTPS_PORT: 497, // Unofficial + INVALID_TOKEN: 498, // Unofficial + CLIENT_CLOSED_REQUEST: 499, // Unofficial + INTERNAL_SERVER_ERROR: 500, + NOT_IMPLEMENTED: 501, + BAD_GATEWAY: 502, + SERVICE_UNAVAILABLE: 503, + GATEWAY_TIMEOUT: 504, + HTTP_VERSION_NOT_SUPPORTED: 505, + VARIANT_ALSO_NEGOTIATES: 506, + INSUFFICIENT_STORAGE: 507, + LOOP_DETECTED: 508, + BANDWIDTH_LIMIT_EXCEEDED: 509, + NOT_EXTENDED: 510, + NETWORK_AUTHENTICATION_REQUIRED: 511, + WEB_SERVER_UNKNOWN_ERROR: 520, // Unofficial + WEB_SERVER_IS_DOWN: 521, // Unofficial + CONNECTION_TIMEOUT: 522, // Unofficial + ORIGIN_IS_UNREACHABLE: 523, // Unofficial + TIMEOUT_OCCURED: 524, // Unofficial + SSL_HANDSHAKE_FAILED: 525, // Unofficial + INVALID_SSL_CERTIFICATE: 526, // Unofficial + RAILGUN_ERROR: 527, // Unofficial + SITE_IS_OVERLOADED: 529, // Unofficial + SITE_IS_FROZEN: 530, // Unofficial + IDENTITY_PROVIDER_AUTHENTICATION_ERROR: 561, // Unofficial + NETWORK_READ_TIMEOUT: 598, // Unofficial + NETWORK_CONNECT_TIMEOUT: 599, // Unofficial +}; +exports.FINISH = { + SAFE: 0, + SAFE_WITH_CB: 1, + UNSAFE: 2, +}; +exports.HEADER_STATE = { + GENERAL: 0, + CONNECTION: 1, + CONTENT_LENGTH: 2, + TRANSFER_ENCODING: 3, + UPGRADE: 4, + CONNECTION_KEEP_ALIVE: 5, + CONNECTION_CLOSE: 6, + CONNECTION_UPGRADE: 7, + TRANSFER_ENCODING_CHUNKED: 8, +}; +// C headers +exports.METHODS_HTTP = [ + exports.METHODS.DELETE, + exports.METHODS.GET, + exports.METHODS.HEAD, + exports.METHODS.POST, + exports.METHODS.PUT, + exports.METHODS.CONNECT, + exports.METHODS.OPTIONS, + exports.METHODS.TRACE, + exports.METHODS.COPY, + exports.METHODS.LOCK, + exports.METHODS.MKCOL, + exports.METHODS.MOVE, + exports.METHODS.PROPFIND, + exports.METHODS.PROPPATCH, + exports.METHODS.SEARCH, + exports.METHODS.UNLOCK, + exports.METHODS.BIND, + exports.METHODS.REBIND, + exports.METHODS.UNBIND, + exports.METHODS.ACL, + exports.METHODS.REPORT, + exports.METHODS.MKACTIVITY, + exports.METHODS.CHECKOUT, + exports.METHODS.MERGE, + exports.METHODS['M-SEARCH'], + exports.METHODS.NOTIFY, + exports.METHODS.SUBSCRIBE, + exports.METHODS.UNSUBSCRIBE, + exports.METHODS.PATCH, + exports.METHODS.PURGE, + exports.METHODS.MKCALENDAR, + exports.METHODS.LINK, + exports.METHODS.UNLINK, + exports.METHODS.PRI, + // TODO(indutny): should we allow it with HTTP? + exports.METHODS.SOURCE, + exports.METHODS.QUERY, +]; +exports.METHODS_ICE = [ + exports.METHODS.SOURCE, +]; +exports.METHODS_RTSP = [ + exports.METHODS.OPTIONS, + exports.METHODS.DESCRIBE, + exports.METHODS.ANNOUNCE, + exports.METHODS.SETUP, + exports.METHODS.PLAY, + exports.METHODS.PAUSE, + exports.METHODS.TEARDOWN, + exports.METHODS.GET_PARAMETER, + exports.METHODS.SET_PARAMETER, + exports.METHODS.REDIRECT, + exports.METHODS.RECORD, + exports.METHODS.FLUSH, + // For AirPlay + exports.METHODS.GET, + exports.METHODS.POST, +]; +exports.METHOD_MAP = (0, utils_1.enumToMap)(exports.METHODS); +exports.H_METHOD_MAP = Object.fromEntries(Object.entries(exports.METHODS).filter(([k]) => k.startsWith('H'))); +exports.STATUSES_HTTP = [ + exports.STATUSES.CONTINUE, + exports.STATUSES.SWITCHING_PROTOCOLS, + exports.STATUSES.PROCESSING, + exports.STATUSES.EARLY_HINTS, + exports.STATUSES.RESPONSE_IS_STALE, + exports.STATUSES.REVALIDATION_FAILED, + exports.STATUSES.DISCONNECTED_OPERATION, + exports.STATUSES.HEURISTIC_EXPIRATION, + exports.STATUSES.MISCELLANEOUS_WARNING, + exports.STATUSES.OK, + exports.STATUSES.CREATED, + exports.STATUSES.ACCEPTED, + exports.STATUSES.NON_AUTHORITATIVE_INFORMATION, + exports.STATUSES.NO_CONTENT, + exports.STATUSES.RESET_CONTENT, + exports.STATUSES.PARTIAL_CONTENT, + exports.STATUSES.MULTI_STATUS, + exports.STATUSES.ALREADY_REPORTED, + exports.STATUSES.TRANSFORMATION_APPLIED, + exports.STATUSES.IM_USED, + exports.STATUSES.MISCELLANEOUS_PERSISTENT_WARNING, + exports.STATUSES.MULTIPLE_CHOICES, + exports.STATUSES.MOVED_PERMANENTLY, + exports.STATUSES.FOUND, + exports.STATUSES.SEE_OTHER, + exports.STATUSES.NOT_MODIFIED, + exports.STATUSES.USE_PROXY, + exports.STATUSES.SWITCH_PROXY, + exports.STATUSES.TEMPORARY_REDIRECT, + exports.STATUSES.PERMANENT_REDIRECT, + exports.STATUSES.BAD_REQUEST, + exports.STATUSES.UNAUTHORIZED, + exports.STATUSES.PAYMENT_REQUIRED, + exports.STATUSES.FORBIDDEN, + exports.STATUSES.NOT_FOUND, + exports.STATUSES.METHOD_NOT_ALLOWED, + exports.STATUSES.NOT_ACCEPTABLE, + exports.STATUSES.PROXY_AUTHENTICATION_REQUIRED, + exports.STATUSES.REQUEST_TIMEOUT, + exports.STATUSES.CONFLICT, + exports.STATUSES.GONE, + exports.STATUSES.LENGTH_REQUIRED, + exports.STATUSES.PRECONDITION_FAILED, + exports.STATUSES.PAYLOAD_TOO_LARGE, + exports.STATUSES.URI_TOO_LONG, + exports.STATUSES.UNSUPPORTED_MEDIA_TYPE, + exports.STATUSES.RANGE_NOT_SATISFIABLE, + exports.STATUSES.EXPECTATION_FAILED, + exports.STATUSES.IM_A_TEAPOT, + exports.STATUSES.PAGE_EXPIRED, + exports.STATUSES.ENHANCE_YOUR_CALM, + exports.STATUSES.MISDIRECTED_REQUEST, + exports.STATUSES.UNPROCESSABLE_ENTITY, + exports.STATUSES.LOCKED, + exports.STATUSES.FAILED_DEPENDENCY, + exports.STATUSES.TOO_EARLY, + exports.STATUSES.UPGRADE_REQUIRED, + exports.STATUSES.PRECONDITION_REQUIRED, + exports.STATUSES.TOO_MANY_REQUESTS, + exports.STATUSES.REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL, + exports.STATUSES.REQUEST_HEADER_FIELDS_TOO_LARGE, + exports.STATUSES.LOGIN_TIMEOUT, + exports.STATUSES.NO_RESPONSE, + exports.STATUSES.RETRY_WITH, + exports.STATUSES.BLOCKED_BY_PARENTAL_CONTROL, + exports.STATUSES.UNAVAILABLE_FOR_LEGAL_REASONS, + exports.STATUSES.CLIENT_CLOSED_LOAD_BALANCED_REQUEST, + exports.STATUSES.INVALID_X_FORWARDED_FOR, + exports.STATUSES.REQUEST_HEADER_TOO_LARGE, + exports.STATUSES.SSL_CERTIFICATE_ERROR, + exports.STATUSES.SSL_CERTIFICATE_REQUIRED, + exports.STATUSES.HTTP_REQUEST_SENT_TO_HTTPS_PORT, + exports.STATUSES.INVALID_TOKEN, + exports.STATUSES.CLIENT_CLOSED_REQUEST, + exports.STATUSES.INTERNAL_SERVER_ERROR, + exports.STATUSES.NOT_IMPLEMENTED, + exports.STATUSES.BAD_GATEWAY, + exports.STATUSES.SERVICE_UNAVAILABLE, + exports.STATUSES.GATEWAY_TIMEOUT, + exports.STATUSES.HTTP_VERSION_NOT_SUPPORTED, + exports.STATUSES.VARIANT_ALSO_NEGOTIATES, + exports.STATUSES.INSUFFICIENT_STORAGE, + exports.STATUSES.LOOP_DETECTED, + exports.STATUSES.BANDWIDTH_LIMIT_EXCEEDED, + exports.STATUSES.NOT_EXTENDED, + exports.STATUSES.NETWORK_AUTHENTICATION_REQUIRED, + exports.STATUSES.WEB_SERVER_UNKNOWN_ERROR, + exports.STATUSES.WEB_SERVER_IS_DOWN, + exports.STATUSES.CONNECTION_TIMEOUT, + exports.STATUSES.ORIGIN_IS_UNREACHABLE, + exports.STATUSES.TIMEOUT_OCCURED, + exports.STATUSES.SSL_HANDSHAKE_FAILED, + exports.STATUSES.INVALID_SSL_CERTIFICATE, + exports.STATUSES.RAILGUN_ERROR, + exports.STATUSES.SITE_IS_OVERLOADED, + exports.STATUSES.SITE_IS_FROZEN, + exports.STATUSES.IDENTITY_PROVIDER_AUTHENTICATION_ERROR, + exports.STATUSES.NETWORK_READ_TIMEOUT, + exports.STATUSES.NETWORK_CONNECT_TIMEOUT, +]; +exports.ALPHA = []; +for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { + // Upper case + exports.ALPHA.push(String.fromCharCode(i)); + // Lower case + exports.ALPHA.push(String.fromCharCode(i + 0x20)); +} +exports.NUM_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, +}; +exports.HEX_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, + A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, + a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, +}; +exports.NUM = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', +]; +exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); +exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; +exports.USERINFO_CHARS = exports.ALPHANUM + .concat(exports.MARK) + .concat(['%', ';', ':', '&', '=', '+', '$', ',']); +// TODO(indutny): use RFC +exports.URL_CHAR = [ + '!', '"', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + ':', ';', '<', '=', '>', + '@', '[', '\\', ']', '^', '_', + '`', + '{', '|', '}', '~', +].concat(exports.ALPHANUM); +exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +exports.TOKEN = [ + '!', '#', '$', '%', '&', '\'', + '*', '+', '-', '.', + '^', '_', '`', + '|', '~', +].concat(exports.ALPHANUM); +/* + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + */ +exports.HEADER_CHARS = ['\t']; +for (let i = 32; i <= 255; i++) { + if (i !== 127) { + exports.HEADER_CHARS.push(i); } - request.onResponseStarted() - } - - onHeaderField (buf) { - const len = this.headers.length - - if ((len & 1) === 0) { - this.headers.push(buf) - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) +} +// ',' = \x44 +exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); +exports.QUOTED_STRING = ['\t', ' ']; +for (let i = 0x21; i <= 0xff; i++) { + if (i !== 0x22 && i !== 0x5c) { // All characters in ASCII except \ and " + exports.QUOTED_STRING.push(i); } +} +exports.HTAB_SP_VCHAR_OBS_TEXT = ['\t', ' ']; +// VCHAR: https://tools.ietf.org/html/rfc5234#appendix-B.1 +for (let i = 0x21; i <= 0x7E; i++) { + exports.HTAB_SP_VCHAR_OBS_TEXT.push(i); +} +// OBS_TEXT: https://datatracker.ietf.org/doc/html/rfc9110#name-collected-abnf +for (let i = 0x80; i <= 0xff; i++) { + exports.HTAB_SP_VCHAR_OBS_TEXT.push(i); +} +exports.MAJOR = exports.NUM_MAP; +exports.MINOR = exports.MAJOR; +exports.SPECIAL_HEADERS = { + 'connection': exports.HEADER_STATE.CONNECTION, + 'content-length': exports.HEADER_STATE.CONTENT_LENGTH, + 'proxy-connection': exports.HEADER_STATE.CONNECTION, + 'transfer-encoding': exports.HEADER_STATE.TRANSFER_ENCODING, + 'upgrade': exports.HEADER_STATE.UPGRADE, +}; +exports["default"] = { + ERROR: exports.ERROR, + TYPE: exports.TYPE, + FLAGS: exports.FLAGS, + LENIENT_FLAGS: exports.LENIENT_FLAGS, + METHODS: exports.METHODS, + STATUSES: exports.STATUSES, + FINISH: exports.FINISH, + HEADER_STATE: exports.HEADER_STATE, + ALPHA: exports.ALPHA, + NUM_MAP: exports.NUM_MAP, + HEX_MAP: exports.HEX_MAP, + NUM: exports.NUM, + ALPHANUM: exports.ALPHANUM, + MARK: exports.MARK, + USERINFO_CHARS: exports.USERINFO_CHARS, + URL_CHAR: exports.URL_CHAR, + HEX: exports.HEX, + TOKEN: exports.TOKEN, + HEADER_CHARS: exports.HEADER_CHARS, + CONNECTION_TOKEN_CHARS: exports.CONNECTION_TOKEN_CHARS, + QUOTED_STRING: exports.QUOTED_STRING, + HTAB_SP_VCHAR_OBS_TEXT: exports.HTAB_SP_VCHAR_OBS_TEXT, + MAJOR: exports.MAJOR, + MINOR: exports.MINOR, + SPECIAL_HEADERS: exports.SPECIAL_HEADERS, + METHODS_HTTP: exports.METHODS_HTTP, + METHODS_ICE: exports.METHODS_ICE, + METHODS_RTSP: exports.METHODS_RTSP, + METHOD_MAP: exports.METHOD_MAP, + H_METHOD_MAP: exports.H_METHOD_MAP, + STATUSES_HTTP: exports.STATUSES_HTTP, +}; - this.trackHeader(buf.length) - } - onHeaderValue (buf) { - let len = this.headers.length +/***/ }), - if ((len & 1) === 1) { - this.headers.push(buf) - len += 1 - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) - } +/***/ 3870: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - const key = this.headers[len - 2] - if (key.length === 10) { - const headerName = util.bufferToLowerCasedHeaderName(key) - if (headerName === 'keep-alive') { - this.keepAlive += buf.toString() - } else if (headerName === 'connection') { - this.connection += buf.toString() - } - } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') { - this.contentLength += buf.toString() - } +"use strict"; +/* module decorator */ module = __nccwpck_require__.nmd(module); - this.trackHeader(buf.length) - } - trackHeader (len) { - this.headersSize += len - if (this.headersSize >= this.headersMaxSize) { - util.destroy(this.socket, new HeadersOverflowError()) - } - } +const { Buffer } = __nccwpck_require__(4573) - onUpgrade (head) { - const { upgrade, client, socket, headers, statusCode } = this +const wasmBase64 = 'AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAn9/AGABfwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAzU0BQYAAAMAAAAAAAADAQMAAwMDAAACAAAAAAICAgICAgICAgIBAQEBAQEBAQEBAwAAAwAAAAQFAXABExMFAwEAAgYIAX8BQcDZBAsHxQcoBm1lbW9yeQIAC19pbml0aWFsaXplAAgZX19pbmRpcmVjdF9mdW5jdGlvbl90YWJsZQEAC2xsaHR0cF9pbml0AAkYbGxodHRwX3Nob3VsZF9rZWVwX2FsaXZlADcMbGxodHRwX2FsbG9jAAsGbWFsbG9jADkLbGxodHRwX2ZyZWUADARmcmVlAAwPbGxodHRwX2dldF90eXBlAA0VbGxodHRwX2dldF9odHRwX21ham9yAA4VbGxodHRwX2dldF9odHRwX21pbm9yAA8RbGxodHRwX2dldF9tZXRob2QAEBZsbGh0dHBfZ2V0X3N0YXR1c19jb2RlABESbGxodHRwX2dldF91cGdyYWRlABIMbGxodHRwX3Jlc2V0ABMObGxodHRwX2V4ZWN1dGUAFBRsbGh0dHBfc2V0dGluZ3NfaW5pdAAVDWxsaHR0cF9maW5pc2gAFgxsbGh0dHBfcGF1c2UAFw1sbGh0dHBfcmVzdW1lABgbbGxodHRwX3Jlc3VtZV9hZnRlcl91cGdyYWRlABkQbGxodHRwX2dldF9lcnJubwAaF2xsaHR0cF9nZXRfZXJyb3JfcmVhc29uABsXbGxodHRwX3NldF9lcnJvcl9yZWFzb24AHBRsbGh0dHBfZ2V0X2Vycm9yX3BvcwAdEWxsaHR0cF9lcnJub19uYW1lAB4SbGxodHRwX21ldGhvZF9uYW1lAB8SbGxodHRwX3N0YXR1c19uYW1lACAabGxodHRw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AXRrQT5qIQILIAEgAjYCHCABQgA3AhAgAkECdEH01wBqIQACQEHI1QAoAgAiA0EBIAJ0IgdxRQRAIAAgATYCAEHI1QAgAyAHcjYCACABIAA2AhggASABNgIIIAEgATYCDAwBCyAEQRkgAkEBdmtBACACQR9HG3QhAiAAKAIAIQACQANAIAAiAygCBEF4cSAERg0BIAJBHXYhACACQQF0IQIgAyAAQQRxakEQaiIHKAIAIgANAAsgByABNgIAIAEgAzYCGCABIAE2AgwgASABNgIIDAELIAMoAggiACABNgIMIAMgATYCCCABQQA2AhggASADNgIMIAEgADYCCAtB5NUAQeTVACgCAEEBayIAQX8gABs2AgALCwcAIAAtACgLBwAgAC0AKgsHACAALQArCwcAIAAtACkLBwAgAC8BNAsHACAALQAwC0ABBH8gACgCGCEBIAAvAS4hAiAALQAoIQMgACgCOCEEIAAQOCAAIAQ2AjggACADOgAoIAAgAjsBLiAAIAE2AhgL5YUCAgd/A34gASACaiEEAkAgACIDKAIMIgANACADKAIEBEAgAyABNgIECyMAQRBrIgkkAAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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C0HjAQwHC0HXAQwGC0HYAQwFC0HZAQwEC0HaAQwDC0HbAQwCC0HdAQwBC0HcAQshAgNAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCADAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQAJ/AkACQAJAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAMCfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAg7jAQABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEjJCUnKCmeA5sDmgORA4oDgwOAA/0C+wL4AvIC8QLvAu0C6ALnAuYC5QLkAtwC2wLaAtkC2ALXAtYC1QLPAs4CzALLAsoCyQLIAscCxgLEAsMCvgK8AroCuQK4ArcCtgK1ArQCswKyArECsAKuAq0CqQKoAqcCpgKlAqQCowKiAqECoAKfApgCkAKMAosCigKBAv4B/QH8AfsB+gH5AfgB9wH1AfMB8AHrAekB6AHnAeYB5QHkAeMB4gHhAeAB3wHeAd0B3AHaAdkB2AHXAdYB1QHUAdMB0gHRAdABzwHOAc0BzAHLAcoByQHIAccBxgHFAcQBwwHCAcEBwAG/Ab4BvQG8AbsBugG5AbgBtwG2AbUBtAGzAbIBsQGwAa8BrgGtAawBqwGqAakBqAGnAaYBpQGkAaMBogGfAZ4BmQGYAZcBlgGVAZQBkwGSAZEBkAGPAY0BjAGHAYYBhQGEAYMBggF9fHt6eXZ1dFBRUlNUVQsgASAERw1yQf0BIQIMvgMLIAEgBEcNmAFB2wEhAgy9AwsgASAERw3xAUGOASECDLwDCyABIARHDfwBQYQBIQIMuwMLIAEgBEcNigJB/wAhAgy6AwsgASAERw2RAkH9ACECDLkDCyABIARHDZQCQfsAIQIMuAMLIAEgBEcNHkEeIQIMtwMLIAEgBEcNGUEYIQIMtgMLIAEgBEcNygJBzQAhAgy1AwsgASAERw3VAkHGACECDLQDCyABIARHDdYCQcMAIQIMswMLIAEgBEcN3AJBOCECDLIDCyADLQAwQQFGDa0DDIkDC0EAIQACQAJAAkAgAy0AKkUNACADLQArRQ0AIAMvATIiAkECcUUNAQwCCyADLwEyIgJBAXFFDQELQQEhACADLQAoQQFGDQAgAy8BNCIGQeQAa0HkAEkNACAGQcwBRg0AIAZBsAJGDQAgAkHAAHENAEEAIQAgAkGIBHFBgARGDQAgAkEocUEARyEACyADQQA7ATIgA0EAOgAxAkAgAEUEQCADQQA6ADEgAy0ALkEEcQ0BDLEDCyADQgA3AyALIANBADoAMSADQQE6ADYMSAtBACEAAkAgAygCOCICRQ0AIAIoAjAiAkUNACADIAIRAAAhAAsgAEUNSCAAQRVHDWIgA0EENgIcIAMgATYCFCADQdIbNgIQIANBFTYCDEEAIQIMrwMLIAEgBEYEQEEGIQIMrwMLIAEtAABBCkcNGSABQQFqIQEMGgsgA0IANwMgQRIhAgyUAwsgASAERw2KA0EjIQIMrAMLIAEgBEYEQEEHIQIMrAMLAkACQCABLQAAQQprDgQBGBgAGAsgAUEBaiEBQRAhAgyTAwsgAUEBaiEBIANBL2otAABBAXENF0EAIQIgA0EANgIcIAMgATYCFCADQZkgNgIQIANBGTYCDAyrAwsgAyADKQMgIgwgBCABa60iCn0iC0IAIAsgDFgbNwMgIAogDFoNGEEIIQIMqgMLIAEgBEcEQCADQQk2AgggAyABNgIEQRQhAgyRAwtBCSECDKkDCyADKQMgUA2uAgxDCyABIARGBEBBCyECDKgDCyABLQAAQQpHDRYgAUEBaiEBDBcLIANBL2otAABBAXFFDRkMJgtBACEAAkAgAygCOCICRQ0AIAIoAlAiAkUNACADIAIRAAAhAAsgAA0ZDEILQQAhAAJAIAMoAjgiAkUNACACKAJQIgJFDQAgAyACEQAAIQALIAANGgwkC0EAIQACQCADKAI4IgJFDQAgAigCUCICRQ0AIAMgAhEAACEACyAADRsMMgsgA0Evai0AAEEBcUUNHAwiC0EAIQACQCADKAI4IgJFDQAgAigCVCICRQ0AIAMgAhEAACEACyAADRwMQgtBACEAAkAgAygCOCICRQ0AIAIoAlQiAkUNACADIAIRAAAhAAsgAA0dDCALIAEgBEYEQEETIQIMoAMLAkAgAS0AACIAQQprDgQfIyMAIgsgAUEBaiEBDB8LQQAhAAJAIAMoAjgiAkUNACACKAJUIgJFDQAgAyACEQAAIQALIAANIgxCCyABIARGBEBBFiECDJ4DCyABLQAAQcDBAGotAABBAUcNIwyDAwsCQANAIAEtAABBsDtqLQAAIgBBAUcEQAJAIABBAmsOAgMAJwsgAUEBaiEBQSEhAgyGAwsgBCABQQFqIgFHDQALQRghAgydAwsgAygCBCEAQQAhAiADQQA2AgQgAyAAIAFBAWoiARA0IgANIQxBC0EAIQACQCADKAI4IgJFDQAgAigCVCICRQ0AIAMgAhEAACEACyAADSMMKgsgASAERgRAQRwhAgybAwsgA0EKNgIIIAMgATYCBEEAIQACQCADKAI4IgJFDQAgAigCUCICRQ0AIAMgAhEAACEACyAADSVBJCECDIEDCyABIARHBEADQCABLQAAQbA9ai0AACIAQQNHBEAgAEEBaw4FGBomggMlJgsgBCABQQFqIgFHDQALQRshAgyaAwtBGyECDJkDCwNAIAEtAABBsD9qLQAAIgBBA0cEQCAAQQFrDgUPEScTJicLIAQgAUEBaiIBRw0AC0EeIQIMmAMLIAEgBEcEQCADQQs2AgggAyABNgIEQQchAgz/AgtBHyECDJcDCyABIARGBEBBICECDJcDCwJAIAEtAABBDWsOFC4/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8APwtBACECIANBADYCHCADQb8LNgIQIANBAjYCDCADIAFBAWo2AhQMlgMLIANBL2ohAgNAIAEgBEYEQEEhIQIMlwMLAkACQAJAIAEtAAAiAEEJaw4YAgApKQEpKSkpKSkpKSkpKSkpKSkpKSkCJwsgAUEBaiEBIANBL2otAABBAXFFDQoMGAsgAUEBaiEBDBcLIAFBAWohASACLQAAQQJxDQALQQAhAiADQQA2AhwgAyABNgIUIANBnxU2AhAgA0EMNgIMDJUDCyADLQAuQYABcUUNAQtBACEAAkAgAygCOCICRQ0AIAIoAlwiAkUNACADIAIRAAAhAAsgAEUN5gIgAEEVRgRAIANBJDYCHCADIAE2AhQgA0GbGzYCECADQRU2AgxBACECDJQDC0EAIQIgA0EANgIcIAMgATYCFCADQZAONgIQIANBFDYCDAyTAwtBACECIANBADYCHCADIAE2AhQgA0G+IDYCECADQQI2AgwMkgMLIAMoAgQhAEEAIQIgA0EANgIEIAMgACABIAynaiIBEDIiAEUNKyADQQc2AhwgAyABNgIUIAMgADYCDAyRAwsgAy0ALkHAAHFFDQELQQAhAAJAIAMoAjgiAkUNACACKAJYIgJFDQAgAyACEQAAIQALIABFDSsgAEEVRgRAIANBCjYCHCADIAE2AhQgA0HrGTYCECADQRU2AgxBACECDJADC0EAIQIgA0EANgIcIAMgATYCFCADQZMMNgIQIANBEzYCDAyPAwtBACECIANBADYCHCADIAE2AhQgA0GCFTYCECADQQI2AgwMjgMLQQAhAiADQQA2AhwgAyABNgIUIANB3RQ2AhAgA0EZNgIMDI0DC0EAIQIgA0EANgIcIAMgATYCFCADQeYdNgIQIANBGTYCDAyMAwsgAEEVRg09QQAhAiADQQA2AhwgAyABNgIUIANB0A82AhAgA0EiNgIMDIsDCyADKAIEIQBBACECIANBADYCBCADIAAgARAzIgBFDSggA0ENNgIcIAMgATYCFCADIAA2AgwMigMLIABBFUYNOkEAIQIgA0EANgIcIAMgATYCFCADQdAPNgIQIANBIjYCDAyJAwsgAygCBCEAQQAhAiADQQA2AgQgAyAAIAEQMyIARQRAIAFBAWohAQwoCyADQQ42AhwgAyAANgIMIAMgAUEBajYCFAyIAwsgAEEVRg03QQAhAiADQQA2AhwgAyABNgIUIANB0A82AhAgA0EiNgIMDIcDCyADKAIEIQBBACECIANBADYCBCADIAAgARAzIgBFBEAgAUEBaiEBDCcLIANBDzYCHCADIAA2AgwgAyABQQFqNgIUDIYDC0EAIQIgA0EANgIcIAMgATYCFCADQeIXNgIQIANBGTYCDAyFAwsgAEEVRg0zQQAhAiADQQA2AhwgAyABNgIUIANB1gw2AhAgA0EjNgIMDIQDCyADKAIEIQBBACECIANBADYCBCADIAAgARA0IgBFDSUgA0ERNgIcIAMgATYCFCADIAA2AgwMgwMLIABBFUYNMEEAIQIgA0EANgIcIAMgATYCFCADQdYMNgIQIANBIzYCDAyCAwsgAygCBCEAQQAhAiADQQA2AgQgAyAAIAEQNCIARQRAIAFBAWohAQwlCyADQRI2AhwgAyAANgIMIAMgAUEBajYCFAyBAwsgA0Evai0AAEEBcUUNAQtBFyECDOYCC0EAIQIgA0EANgIcIAMgATYCFCADQeIXNgIQIANBGTYCDAz+AgsgAEE7Rw0AIAFBAWohAQwMC0EAIQIgA0EANgIcIAMgATYCFCADQZIYNgIQIANBAjYCDAz8AgsgAEEVRg0oQQAhAiADQQA2AhwgAyABNgIUIANB1gw2AhAgA0EjNgIMDPsCCyADQRQ2AhwgAyABNgIUIAMgADYCDAz6AgsgAygCBCEAQQAhAiADQQA2AgQgAyAAIAEQNCIARQRAIAFBAWohAQz1AgsgA0EVNgIcIAMgADYCDCADIAFBAWo2AhQM+QILIAMoAgQhAEEAIQIgA0EANgIEIAMgACABEDQiAEUEQCABQQFqIQEM8wILIANBFzYCHCADIAA2AgwgAyABQQFqNgIUDPgCCyAAQRVGDSNBACECIANBADYCHCADIAE2AhQgA0HWDDYCECADQSM2AgwM9wILIAMoAgQhAEEAIQIgA0EANgIEIAMgACABEDQiAEUEQCABQQFqIQEMHQsgA0EZNgIcIAMgADYCDCADIAFBAWo2AhQM9gILIAMoAgQhAEEAIQIgA0EANgIEIAMgACABEDQiAEUEQCABQQFqIQEM7wILIANBGjYCHCADIAA2AgwgAyABQQFqNgIUDPUCCyAAQRVGDR9BACECIANBADYCHCADIAE2AhQgA0HQDzYCECADQSI2AgwM9AILIAMoAgQhACADQQA2AgQgAyAAIAEQMyIARQRAIAFBAWohAQwbCyADQRw2AhwgAyAANgIMIAMgAUEBajYCFEEAIQIM8wILIAMoAgQhACADQQA2AgQgAyAAIAEQMyIARQRAIAFBAWohAQzrAgsgA0EdNgIcIAMgADYCDCADIAFBAWo2AhRBACECDPICCyAAQTtHDQEgAUEBaiEBC0EmIQIM1wILQQAhAiADQQA2AhwgAyABNgIUIANBnxU2AhAgA0EMNgIMDO8CCyABIARHBEADQCABLQAAQSBHDYQCIAQgAUEBaiIBRw0AC0EsIQIM7wILQSwhAgzuAgsgASAERgRAQTQhAgzuAgsCQAJAA0ACQCABLQAAQQprDgQCAAADAAsgBCABQQFqIgFHDQALQTQhAgzvAgsgAygCBCEAIANBADYCBCADIAAgARAxIgBFDZ8CIANBMjYCHCADIAE2AhQgAyAANgIMQQAhAgzuAgsgAygCBCEAIANBADYCBCADIAAgARAxIgBFBEAgAUEBaiEBDJ8CCyADQTI2AhwgAyAANgIMIAMgAUEBajYCFEEAIQIM7QILIAEgBEcEQAJAA0AgAS0AAEEwayIAQf8BcUEKTwRAQTohAgzXAgsgAykDICILQpmz5syZs+bMGVYNASADIAtCCn4iCjcDICAKIACtQv8BgyILQn+FVg0BIAMgCiALfDcDICAEIAFBAWoiAUcNAAtBwAAhAgzuAgsgAygCBCEAIANBADYCBCADIAAgAUEBaiIBEDEiAA0XDOICC0HAACECDOwCCyABIARGBEBByQAhAgzsAgsCQANAAkAgAS0AAEEJaw4YAAKiAqICqQKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogIAogILIAQgAUEBaiIBRw0AC0HJACECDOwCCyABQQFqIQEgA0Evai0AAEEBcQ2lAiADQQA2AhwgAyABNgIUIANBlxA2AhAgA0EKNgIMQQAhAgzrAgsgASAERwRAA0AgAS0AAEEgRw0VIAQgAUEBaiIBRw0AC0H4ACECDOsCC0H4ACECDOoCCyADQQI6ACgMOAtBACECIANBADYCHCADQb8LNgIQIANBAjYCDCADIAFBAWo2AhQM6AILQQAhAgzOAgtBDSECDM0CC0ETIQIMzAILQRUhAgzLAgtBFiECDMoCC0EYIQIMyQILQRkhAgzIAgtBGiECDMcCC0EbIQIMxgILQRwhAgzFAgtBHSECDMQCC0EeIQIMwwILQR8hAgzCAgtBICECDMECC0EiIQIMwAILQSMhAgy/AgtBJSECDL4CC0HlACECDL0CCyADQT02AhwgAyABNgIUIAMgADYCDEEAIQIM1QILIANBGzYCHCADIAE2AhQgA0GkHDYCECADQRU2AgxBACECDNQCCyADQSA2AhwgAyABNgIUIANBmBo2AhAgA0EVNgIMQQAhAgzTAgsgA0ETNgIcIAMgATYCFCADQZgaNgIQIANBFTYCDEEAIQIM0gILIANBCzYCHCADIAE2AhQgA0GYGjYCECADQRU2AgxBACECDNECCyADQRA2AhwgAyABNgIUIANBmBo2AhAgA0EVNgIMQQAhAgzQAgsgA0EgNgIcIAMgATYCFCADQaQcNgIQIANBFTYCDEEAIQIMzwILIANBCzYCHCADIAE2AhQgA0GkHDYCECADQRU2AgxBACECDM4CCyADQQw2AhwgAyABNgIUIANBpBw2AhAgA0EVNgIMQQAhAgzNAgtBACECIANBADYCHCADIAE2AhQgA0HdDjYCECADQRI2AgwMzAILAkADQAJAIAEtAABBCmsOBAACAgACCyAEIAFBAWoiAUcNAAtB/QEhAgzMAgsCQAJAIAMtADZBAUcNAEEAIQACQCADKAI4IgJFDQAgAigCYCICRQ0AIAMgAhEAACEACyAARQ0AIABBFUcNASADQfwBNgIcIAMgATYCFCADQdwZNgIQIANBFTYCDEEAIQIMzQILQdwBIQIMswILIANBADYCHCADIAE2AhQgA0H5CzYCECADQR82AgxBACECDMsCCwJAAkAgAy0AKEEBaw4CBAEAC0HbASECDLICC0HUASECDLECCyADQQI6ADFBACEAAkAgAygCOCICRQ0AIAIoAgAiAkUNACADIAIRAAAhAAsgAEUEQEHdASECDLECCyAAQRVHBEAgA0EANgIcIAMgATYCFCADQbQMNgIQIANBEDYCDEEAIQIMygILIANB+wE2AhwgAyABNgIUIANBgRo2AhAgA0EVNgIMQQAhAgzJAgsgASAERgRAQfoBIQIMyQILIAEtAABByABGDQEgA0EBOgAoC0HAASECDK4CC0HaASECDK0CCyABIARHBEAgA0EMNgIIIAMgATYCBEHZASECDK0CC0H5ASECDMUCCyABIARGBEBB+AEhAgzFAgsgAS0AAEHIAEcNBCABQQFqIQFB2AEhAgyrAgsgASAERgRAQfcBIQIMxAILAkACQCABLQAAQcUAaw4QAAUFBQUFBQUFBQUFBQUFAQULIAFBAWohAUHWASECDKsCCyABQQFqIQFB1wEhAgyqAgtB9gEhAiABIARGDcICIAMoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQbrVAGotAABHDQMgAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADMMCCyADKAIEIQAgA0IANwMAIAMgACAGQQFqIgEQLiIARQRAQeMBIQIMqgILIANB9QE2AhwgAyABNgIUIAMgADYCDEEAIQIMwgILQfQBIQIgASAERg3BAiADKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEG41QBqLQAARw0CIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzCAgsgA0GBBDsBKCADKAIEIQAgA0IANwMAIAMgACAGQQFqIgEQLiIADQMMAgsgA0EANgIAC0EAIQIgA0EANgIcIAMgATYCFCADQeUfNgIQIANBCDYCDAy/AgtB1QEhAgylAgsgA0HzATYCHCADIAE2AhQgAyAANgIMQQAhAgy9AgtBACEAAkAgAygCOCICRQ0AIAIoAkAiAkUNACADIAIRAAAhAAsgAEUNbiAAQRVHBEAgA0EANgIcIAMgATYCFCADQYIPNgIQIANBIDYCDEEAIQIMvQILIANBjwE2AhwgAyABNgIUIANB7Bs2AhAgA0EVNgIMQQAhAgy8AgsgASAERwRAIANBDTYCCCADIAE2AgRB0wEhAgyjAgtB8gEhAgy7AgsgASAERgRAQfEBIQIMuwILAkACQAJAIAEtAABByABrDgsAAQgICAgICAgIAggLIAFBAWohAUHQASECDKMCCyABQQFqIQFB0QEhAgyiAgsgAUEBaiEBQdIBIQIMoQILQfABIQIgASAERg25AiADKAIAIgAgBCABa2ohBiABIABrQQJqIQUDQCABLQAAIABBtdUAai0AAEcNBCAAQQJGDQMgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAY2AgAMuQILQe8BIQIgASAERg24AiADKAIAIgAgBCABa2ohBiABIABrQQFqIQUDQCABLQAAIABBs9UAai0AAEcNAyAAQQFGDQIgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAY2AgAMuAILQe4BIQIgASAERg23AiADKAIAIgAgBCABa2ohBiABIABrQQJqIQUDQCABLQAAIABBsNUAai0AAEcNAiAAQQJGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAY2AgAMtwILIAMoAgQhACADQgA3AwAgAyAAIAVBAWoiARArIgBFDQIgA0HsATYCHCADIAE2AhQgAyAANgIMQQAhAgy2AgsgA0EANgIACyADKAIEIQAgA0EANgIEIAMgACABECsiAEUNnAIgA0HtATYCHCADIAE2AhQgAyAANgIMQQAhAgy0AgtBzwEhAgyaAgtBACEAAkAgAygCOCICRQ0AIAIoAjQiAkUNACADIAIRAAAhAAsCQCAABEAgAEEVRg0BIANBADYCHCADIAE2AhQgA0HqDTYCECADQSY2AgxBACECDLQCC0HOASECDJoCCyADQesBNgIcIAMgATYCFCADQYAbNgIQIANBFTYCDEEAIQIMsgILIAEgBEYEQEHrASECDLICCyABLQAAQS9GBEAgAUEBaiEBDAELIANBADYCHCADIAE2AhQgA0GyODYCECADQQg2AgxBACECDLECC0HNASECDJcCCyABIARHBEAgA0EONgIIIAMgATYCBEHMASECDJcCC0HqASECDK8CCyABIARGBEBB6QEhAgyvAgsgAS0AAEEwayIAQf8BcUEKSQRAIAMgADoAKiABQQFqIQFBywEhAgyWAgsgAygCBCEAIANBADYCBCADIAAgARAvIgBFDZcCIANB6AE2AhwgAyABNgIUIAMgADYCDEEAIQIMrgILIAEgBEYEQEHnASECDK4CCwJAIAEtAABBLkYEQCABQQFqIQEMAQsgAygCBCEAIANBADYCBCADIAAgARAvIgBFDZgCIANB5gE2AhwgAyABNgIUIAMgADYCDEEAIQIMrgILQcoBIQIMlAILIAEgBEYEQEHlASECDK0CC0EAIQBBASEFQQEhB0EAIQICQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQCABLQAAQTBrDgoKCQABAgMEBQYICwtBAgwGC0EDDAULQQQMBAtBBQwDC0EGDAILQQcMAQtBCAshAkEAIQVBACEHDAILQQkhAkEBIQBBACEFQQAhBwwBC0EAIQVBASECCyADIAI6ACsgAUEBaiEBAkACQCADLQAuQRBxDQACQAJAAkAgAy0AKg4DAQACBAsgB0UNAwwCCyAADQEMAgsgBUUNAQsgAygCBCEAIANBADYCBCADIAAgARAvIgBFDQIgA0HiATYCHCADIAE2AhQgAyAANgIMQQAhAgyvAgsgAygCBCEAIANBADYCBCADIAAgARAvIgBFDZoCIANB4wE2AhwgAyABNgIUIAMgADYCDEEAIQIMrgILIAMoAgQhACADQQA2AgQgAyAAIAEQLyIARQ2YAiADQeQBNgIcIAMgATYCFCADIAA2AgwMrQILQckBIQIMkwILQQAhAAJAIAMoAjgiAkUNACACKAJEIgJFDQAgAyACEQAAIQALAkAgAARAIABBFUYNASADQQA2AhwgAyABNgIUIANBpA02AhAgA0EhNgIMQQAhAgytAgtByAEhAgyTAgsgA0HhATYCHCADIAE2AhQgA0HQGjYCECADQRU2AgxBACECDKsCCyABIARGBEBB4QEhAgyrAgsCQCABLQAAQSBGBEAgA0EAOwE0IAFBAWohAQwBCyADQQA2AhwgAyABNgIUIANBmRE2AhAgA0EJNgIMQQAhAgyrAgtBxwEhAgyRAgsgASAERgRAQeABIQIMqgILAkAgAS0AAEEwa0H/AXEiAkEKSQRAIAFBAWohAQJAIAMvATQiAEGZM0sNACADIABBCmwiADsBNCAAQf7/A3EgAkH//wNzSw0AIAMgACACajsBNAwCC0EAIQIgA0EANgIcIAMgATYCFCADQZUeNgIQIANBDTYCDAyrAgsgA0EANgIcIAMgATYCFCADQZUeNgIQIANBDTYCDEEAIQIMqgILQcYBIQIMkAILIAEgBEYEQEHfASECDKkCCwJAIAEtAABBMGtB/wFxIgJBCkkEQCABQQFqIQECQCADLwE0IgBBmTNLDQAgAyAAQQpsIgA7ATQgAEH+/wNxIAJB//8Dc0sNACADIAAgAmo7ATQMAgtBACECIANBADYCHCADIAE2AhQgA0GVHjYCECADQQ02AgwMqgILIANBADYCHCADIAE2AhQgA0GVHjYCECADQQ02AgxBACECDKkCC0HFASECDI8CCyABIARGBEBB3gEhAgyoAgsCQCABLQAAQTBrQf8BcSICQQpJBEAgAUEBaiEBAkAgAy8BNCIAQZkzSw0AIAMgAEEKbCIAOwE0IABB/v8DcSACQf//A3NLDQAgAyAAIAJqOwE0DAILQQAhAiADQQA2AhwgAyABNgIUIANBlR42AhAgA0ENNgIMDKkCCyADQQA2AhwgAyABNgIUIANBlR42AhAgA0ENNgIMQQAhAgyoAgtBxAEhAgyOAgsgASAERgRAQd0BIQIMpwILAkACQAJAAkAgAS0AAEEKaw4XAgMDAAMDAwMDAwMDAwMDAwMDAwMDAwEDCyABQQFqDAULIAFBAWohAUHDASECDI8CCyABQQFqIQEgA0Evai0AAEEBcQ0IIANBADYCHCADIAE2AhQgA0GNCzYCECADQQ02AgxBACECDKcCCyADQQA2AhwgAyABNgIUIANBjQs2AhAgA0ENNgIMQQAhAgymAgsgASAERwRAIANBDzYCCCADIAE2AgRBASECDI0CC0HcASECDKUCCwJAAkADQAJAIAEtAABBCmsOBAIAAAMACyAEIAFBAWoiAUcNAAtB2wEhAgymAgsgAygCBCEAIANBADYCBCADIAAgARAtIgBFBEAgAUEBaiEBDAQLIANB2gE2AhwgAyAANgIMIAMgAUEBajYCFEEAIQIMpQILIAMoAgQhACADQQA2AgQgAyAAIAEQLSIADQEgAUEBagshAUHBASECDIoCCyADQdkBNgIcIAMgADYCDCADIAFBAWo2AhRBACECDKICC0HCASECDIgCCyADQS9qLQAAQQFxDQEgA0EANgIcIAMgATYCFCADQeQcNgIQIANBGTYCDEEAIQIMoAILIAEgBEYEQEHZASEC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IAFBAWohAUGeASECDOQBCyABQQFqIQFBnwEhAgzjAQtBtwEhAiABIARGDfsBIAMoAgAiACAEIAFraiEFIAEgAGtBA2ohBgJAA0AgAS0AACAAQezUAGotAABHDSggAEEDRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADPwBCyADQQA2AgAgBkEBaiEBQQ0MKAtBtgEhAiABIARGDfoBIAMoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQaHVAGotAABHDScgAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADPsBCyADQQA2AgAgBkEBaiEBQQwMJwtBtQEhAiABIARGDfkBIAMoAgAiACAEIAFraiEFIAEgAGtBAWohBgJAA0AgAS0AACAAQerUAGotAABHDSYgAEEBRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADPoBCyADQQA2AgAgBkEBaiEBQQMMJgtBtAEhAiABIARGDfgBIAMoAgAiACAEIAFraiEFIAEgAGtBAWohBgJAA0AgAS0AACAAQejUAGotAABHDSUgAEEBRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADPkBCyADQQA2AgAgBkEBaiEBQSYMJQsgASAERgRAQbMBIQIM+AELAkACQCABLQAAQdQAaw4CAAEnCyABQQFqIQFBmQEhAgzfAQsgAUEBaiEBQZoBIQIM3gELQbIBIQIgASAERg32ASADKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHm1ABqLQAARw0jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAz3AQsgA0EANgIAIAZBAWohAUEnDCMLQbEBIQIgASAERg31ASADKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHk1ABqLQAARw0iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAz2AQsgA0EANgIAIAZBAWohAUEcDCILQbABIQIgASAERg30ASADKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEHe1ABqLQAARw0hIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAz1AQsgA0EANgIAIAZBAWohAUEGDCELQa8BIQIgASAERg3zASADKAIAIgAgBCABa2ohBSABIABrQQRqIQYCQANAIAEtAAAgAEHZ1ABqLQAARw0gIABBBEYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAz0AQsgA0EANgIAIAZBAWohAUEZDCALIAEgBEYEQEGuASECDPMBCwJAAkACQAJAIAEtAABBLWsOIwAkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJAEkJCQkJAIkJCQDJAsgAUEBaiEBQY4BIQIM3AELIAFBAWohAUGPASECDNsBCyABQQFqIQFBlAEhAgzaAQsgAUEBaiEBQZUBIQIM2QELQa0BIQIgASAERg3xASADKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHX1ABqLQAARw0eIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzyAQsgA0EANgIAIAZBAWohAUELDB4LIAEgBEYEQEGsASECDPEBCwJAAkAgAS0AAEHBAGsOAwAgASALIAFBAWohAUGQASECDNgBCyABQQFqIQFBkwEhAgzXAQsgASAERgRAQasBIQIM8AELAkACQCABLQAAQcEAaw4PAB8fHx8fHx8fHx8fHx8BHwsgAUEBaiEBQZEBIQIM1wELIAFBAWohAUGSASECDNYBCyABIARGBEBBqgEhAgzvAQsgAS0AAEHMAEcNHCABQQFqIQFBCgwbC0GpASECIAEgBEYN7QEgAygCACIAIAQgAWtqIQUgASAAa0EFaiEGAkADQCABLQAAIABB0dQAai0AAEcNGiAAQQVGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM7gELIANBADYCACAGQQFqIQFBHgwaC0GoASECIAEgBEYN7AEgAygCACIAIAQgAWtqIQUgASAAa0EGaiEGAkADQCABLQAAIABBytQAai0AAEcNGSAAQQZGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM7QELIANBADYCACAGQQFqIQFBFQwZC0GnASECIAEgBEYN6wEgAygCACIAIAQgAWtqIQUgASAAa0ECaiEGAkADQCABLQAAIABBx9QAai0AAEcNGCAAQQJGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM7AELIANBADYCACAGQQFqIQFBFwwYC0GmASECIAEgBEYN6gEgAygCACIAIAQgAWtqIQUgASAAa0EFaiEGAkADQCABLQAAIABBwdQAai0AAEcNFyAAQQVGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM6wELIANBADYCACAGQQFqIQFBGAwXCyABIARGBEBBpQEhAgzqAQsCQAJAIAEtAABByQBrDgcAGRkZGRkBGQsgAUEBaiEBQYsBIQIM0QELIAFBAWohAUGMASECDNABC0GkASECIAEgBEYN6AEgAygCACIAIAQgAWtqIQUgASAAa0EBaiEGAkADQCABLQAAIABBptUAai0AAEcNFSAAQQFGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM6QELIANBADYCACAGQQFqIQFBCQwVC0GjASECIAEgBEYN5wEgAygCACIAIAQgAWtqIQUgASAAa0EBaiEGAkADQCABLQAAIABBpNUAai0AAEcNFCAAQQFGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM6AELIANBADYCACAGQQFqIQFBHwwUC0GiASECIAEgBEYN5gEgAygCACIAIAQgAWtqIQUgASAAa0ECaiEGAkADQCABLQAAIABBvtQAai0AAEcNEyAAQQJGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM5wELIANBADYCACAGQQFqIQFBAgwTC0GhASECIAEgBEYN5QEgAygCACIAIAQgAWtqIQUgASAAa0EBaiEGA0AgAS0AACAAQbzUAGotAABHDREgAEEBRg0CIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADOUBCyABIARGBEBBoAEhAgzlAQtBASABLQAAQd8ARw0RGiABQQFqIQFBhwEhAgzLAQsgA0EANgIAIAZBAWohAUGIASECDMoBC0GfASECIAEgBEYN4gEgAygCACIAIAQgAWtqIQUgASAAa0EIaiEGAkADQCABLQAAIABBhNUAai0AAEcNDyAAQQhGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM4wELIANBADYCACAGQQFqIQFBKQwPC0GeASECIAEgBEYN4QEgAygCACIAIAQgAWtqIQUgASAAa0EDaiEGAkADQCABLQAAIABBuNQAai0AAEcNDiAAQQNGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM4gELIANBADYCACAGQQFqIQFBLQwOCyABIARGBEBBnQEhAgzhAQsgAS0AAEHFAEcNDiABQQFqIQFBhAEhAgzHAQsgASAERgRAQZwBIQIM4AELAkACQCABLQAAQcwAaw4IAA8PDw8PDwEPCyABQQFqIQFBggEhAgzHAQsgAUEBaiEBQYMBIQIMxgELQZsBIQIgASAERg3eASADKAIAIgAgBCABa2ohBSABIABrQQRqIQYCQANAIAEtAAAgAEGz1ABqLQAARw0LIABBBEYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzfAQsgA0EANgIAIAZBAWohAUEjDAsLQZoBIQIgASAERg3dASADKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGw1ABqLQAARw0KIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzeAQsgA0EANgIAIAZBAWohAUEADAoLIAEgBEYEQEGZASECDN0BCwJAAkAgAS0AAEHIAGsOCAAMDAwMDAwBDAsgAUEBaiEBQf0AIQIMxAELIAFBAWohAUGAASECDMMBCyABIARGBEBBmAEhAgzcAQsCQAJAIAEtAABBzgBrDgMACwELCyABQQFqIQFB/gAhAgzDAQsgAUEBaiEBQf8AIQIMwgELIAEgBEYEQEGXASECDNsBCyABLQAAQdkARw0IIAFBAWohAUEIDAcLQZYBIQIgASAERg3ZASADKAIAIgAgBCABa2ohBSABIABrQQNqIQYCQANAIAEtAAAgAEGs1ABqLQAARw0GIABBA0YNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzaAQsgA0EANgIAIAZBAWohAUEFDAYLQZUBIQIgASAERg3YASADKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGm1ABqLQAARw0FIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzZAQsgA0EANgIAIAZBAWohAUEWDAULQZQBIQIgASAERg3XASADKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGh1QBqLQAARw0EIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzYAQsgA0EANgIAIAZBAWohAUEQDAQLIAEgBEYEQEGTASECDNcBCwJAAkAgAS0AAEHDAGsODAAGBgYGBgYGBgYGAQYLIAFBAWohAUH5ACECDL4BCyABQQFqIQFB+gAhAgy9AQtBkgEhAiABIARGDdUBIAMoAgAiACAEIAFraiEFIAEgAGtBBWohBgJAA0AgAS0AACAAQaDUAGotAABHDQIgAEEFRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADNYBCyADQQA2AgAgBkEBaiEBQSQMAgsgA0EANgIADAILIAEgBEYEQEGRASECDNQBCyABLQAAQcwARw0BIAFBAWohAUETCzoAKSADKAIEIQAgA0EANgIEIAMgACABEC4iAA0CDAELQQAhAiADQQA2AhwgAyABNgIUIANB/h82AhAgA0EGNgIMDNEBC0H4ACECDLcBCyADQZABNgIcIAMgATYCFCADIAA2AgxBACECDM8BC0EAIQACQCADKAI4IgJFDQAgAigCQCICRQ0AIAMgAhEAACEACyAARQ0AIABBFUYNASADQQA2AhwgAyABNgIUIANBgg82AhAgA0EgNgIMQQAhAgzOAQtB9wAhAgy0AQsgA0GPATYCHCADIAE2AhQgA0HsGzYCECADQRU2AgxBACECDMwBCyABIARGBEBBjwEhAgzMAQsCQCABLQAAQSBGBEAgAUEBaiEBDAELIANBADYCHCADIAE2AhQgA0GbHzYCECADQQY2AgxBACECDMwBC0ECIQIMsgELA0AgAS0AAEEgRw0CIAQgAUEBaiIBRw0AC0GOASECDMoBCyABIARGBEBBjQEhAgzKAQsCQCABLQAAQQlrDgRKAABKAAtB9QAhAgywAQsgAy0AKUEFRgRAQfYAIQIMsAELQfQAIQIMrwELIAEgBEYEQEGMASECDMgBCyADQRA2AgggAyABNgIEDAoLIAEgBEYEQEGLASECDMcBCwJAIAEtAABBCWsOBEcAAEcAC0HzACECDK0BCyABIARHBEAgA0EQNgIIIAMgATYCBEHxACECDK0BC0GKASECDMUBCwJAIAEgBEcEQANAIAEtAABBoNAAai0AACIAQQNHBEACQCAAQQFrDgJJAAQLQfAAIQIMrwELIAQgAUEBaiIBRw0AC0GIASEC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BCABQQFqIgFHDQALQfsAIQIMpwELIAMoAgQhACADQQA2AgQgAyAAIAEQLCIARQ0DIANB2wA2AhwgAyABNgIUIAMgADYCDEEAIQIMpgELIAMoAgQhACADQQA2AgQgAyAAIAEQLCIARQ0DIANB3QA2AhwgAyABNgIUIAMgADYCDEEAIQIMpQELIAMoAgQhACADQQA2AgQgAyAAIAEQLCIARQ0DIANB+gA2AhwgAyABNgIUIAMgADYCDEEAIQIMpAELIANBADYCHCADIAE2AhQgA0G8CjYCECADQQc2AgxBACECDKMBC0HPACECDIkBC0HRACECDIgBC0HnACECDIcBCyABIARGBEBB+gAhAgygAQsCQCABLQAAQQlrDgQgAAAgAAsgAUEBaiEBQeYAIQIMhgELIAEgBEYEQEH5ACECDJ8BCwJAIAEtAABBCWsOBB8AAB8AC0EAIQACQCADKAI4IgJFDQAgAigCOCICRQ0AIAMgAhEAACEACyAARQRAQeIBIQIMhgELIABBFUcEQCADQQA2AhwgAyABNgIUIANByQ02AhAgA0EaNgIMQQAhAgyfAQsgA0H4ADYCHCADIAE2AhQgA0HqGjYCECADQRU2AgxBACECDJ4BCyABIARHBEAgA0ENNgIIIAMgATYCBEHkACECDIUBC0H3ACECDJ0BCyABIARGBEBB9gAhAgydAQsCQAJAAkAgAS0AAEHIAGsOCwABCwsLCwsLCwsCCwsgAUEBaiEBQd0AIQIMhQELIAFBAWohAUHgACECDIQBCyABQQFqIQFB4wAhAgyDAQtB9QAhAiABIARGDZsBIAMoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQbXVAGotAABHDQggAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADJwBCyADKAIEIQAgA0IANwMAIAMgACAGQQFqIgEQKyIABEAgA0H0ADYCHCADIAE2AhQgAyAANgIMQQAhAgycAQtB4gAhAgyCAQtBACEAAkAgAygCOCICRQ0AIAIoAjQiAkUNACADIAIRAAAhAAsCQCAABEAgAEEVRg0BIANBADYCHCADIAE2AhQgA0HqDTYCECADQSY2AgxBACECDJwBC0HhACECDIIBCyADQfMANgIcIAMgATYCFCADQYAbNgIQIANBFTYCDEEAIQIMmgELIAMtACkiAEEja0ELSQ0JAkAgAEEGSw0AQQEgAHRBygBxRQ0ADAoLQQAhAiADQQA2AhwgAyABNgIUIANB7Qk2AhAgA0EINgIMDJkBC0HyACECIAEgBEYNmAEgAygCACIAIAQgAWtqIQUgASAAa0EBaiEGAkADQCABLQAAIABBs9UAai0AAEcNBSAAQQFGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAMmQELIAMoAgQhACADQgA3AwAgAyAAIAZBAWoiARArIgAEQCADQfEANgIcIAMgATYCFCADIAA2AgxBACECDJkBC0HfACECDH8LQQAhAAJAIAMoAjgiAkUNACACKAI0IgJFDQAgAyACEQAAIQALAkAgAARAIABBFUYNASADQQA2AhwgAyABNgIUIANB6g02AhAgA0EmNgIMQQAhAgyZAQtB3gAhAgx/CyADQfAANgIcIAMgATYCFCADQYAbNgIQIANBFTYCDEEAIQIMlwELIAMtAClBIUYNBiADQQA2AhwgAyABNgIUIANBkQo2AhAgA0EINgIMQQAhAgyWAQtB7wAhAiABIARGDZUBIAMoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQbDVAGotAABHDQIgAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADJYBCyADKAIEIQAgA0IANwMAIAMgACAGQQFqIgEQKyIARQ0CIANB7QA2AhwgAyABNgIUIAMgADYCDEEAIQIMlQELIANBADYCAAsgAygCBCEAIANBADYCBCADIAAgARArIgBFDYABIANB7gA2AhwgAyABNgIUIAMgADYCDEEAIQIMkwELQdwAIQIMeQtBACEAAkAgAygCOCICRQ0AIAIoAjQiAkUNACADIAIRAAAhAAsCQCAABEAgAEEVRg0BIANBADYCHCADIAE2AhQgA0HqDTYCECADQSY2AgxBACECDJMBC0HbACECDHkLIANB7AA2AhwgAyABNgIUIANBgBs2AhAgA0EVNgIMQQAhAgyRAQsgAy0AKSIAQSNJDQAgAEEuRg0AIANBADYCHCADIAE2AhQgA0HJCTYCECADQQg2AgxBACECDJABC0HaACECDHYLIAEgBEYEQEHrACECDI8BCwJAIAEtAABBL0YEQCABQQFqIQEMAQsgA0EANgIcIAMgATYCFCADQbI4NgIQIANBCDYCDEEAIQIMjwELQdkAIQIMdQsgASAERwRAIANBDjYCCCADIAE2AgRB2AAhAgx1C0HqACECDI0BCyABIARGBEBB6QAhAgyNAQsgAS0AAEEwayIAQf8BcUEKSQRAIAMgADoAKiABQQFqIQFB1wAhAgx0CyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNeiADQegANgIcIAMgATYCFCADIAA2AgxBACECDIwBCyABIARGBEBB5wAhAgyMAQsCQCABLQAAQS5GBEAgAUEBaiEBDAELIAMoAgQhACADQQA2AgQgAyAAIAEQLyIARQ17IANB5gA2AhwgAyABNgIUIAMgADYCDEEAIQIMjAELQdYAIQIMcgsgASAERgRAQeUAIQIMiwELQQAhAEEBIQVBASEHQQAhAgJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAIAEtAABBMGsOCgoJAAECAwQFBggLC0ECDAYLQQMMBQtBBAwEC0EFDAMLQQYMAgtBBwwBC0EICyECQQAhBUEAIQcMAgtBCSECQQEhAEEAIQVBACEHDAELQQAhBUEBIQILIAMgAjoAKyABQQFqIQECQAJAIAMtAC5BEHENAAJAAkACQCADLQAqDgMBAAIECyAHRQ0DDAILIAANAQwCCyAFRQ0BCyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNAiADQeIANgIcIAMgATYCFCADIAA2AgxBACECDI0BCyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNfSADQeMANgIcIAMgATYCFCADIAA2AgxBACECDIwBCyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNeyADQeQANgIcIAMgATYCFCADIAA2AgwMiwELQdQAIQIMcQsgAy0AKUEiRg2GAUHTACECDHALQQAhAAJAIAMoAjgiAkUNACACKAJEIgJFDQAgAyACEQAAIQALIABFBEBB1QAhAgxwCyAAQRVHBEAgA0EANgIcIAMgATYCFCADQaQNNgIQIANBITYCDEEAIQIMiQELIANB4QA2AhwgAyABNgIUIANB0Bo2AhAgA0EVNgIMQQAhAgyIAQsgASAERgRAQeAAIQIMiAELAkACQAJAAkACQCABLQAAQQprDgQBBAQABAsgAUEBaiEBDAELIAFBAWohASADQS9qLQAAQQFxRQ0BC0HSACECDHALIANBADYCHCADIAE2AhQgA0G2ETYCECADQQk2AgxBACECDIgBCyADQQA2AhwgAyABNgIUIANBthE2AhAgA0EJNgIMQQAhAgyHAQsgASAERgRAQd8AIQIMhwELIAEtAABBCkYEQCABQQFqIQEMCQsgAy0ALkHAAHENCCADQQA2AhwgAyABNgIUIANBthE2AhAgA0ECNgIMQQAhAgyGAQsgASAERgRAQd0AIQIMhgELIAEtAAAiAkENRgRAIAFBAWohAUHQACECDG0LIAEhACACQQlrDgQFAQEFAQsgBCABIgBGBEBB3AAhAgyFAQsgAC0AAEEKRw0AIABBAWoMAgtBACECIANBADYCHCADIAA2AhQgA0HKLTYCECADQQc2AgwMgwELIAEgBEYEQEHbACECDIMBCwJAIAEtAABBCWsOBAMAAAMACyABQQFqCyEBQc4AIQIMaAsgASAERgRAQdoAIQIMgQELIAEtAABBCWsOBAABAQABC0EAIQIgA0EANgIcIANBmhI2AhAgA0EHNgIMIAMgAUEBajYCFAx/CyADQYASOwEqQQAhAAJAIAMoAjgiAkUNACACKAI4IgJFDQAgAyACEQAAIQALIABFDQAgAEEVRw0BIANB2QA2AhwgAyABNgIUIANB6ho2AhAgA0EVNgIMQQAhAgx+C0HNACECDGQLIANBADYCHCADIAE2AhQgA0HJDTYCECADQRo2AgxBACECDHwLIAEgBEYEQEHZACECDHwLIAEtAABBIEcNPSABQQFqIQEgAy0ALkEBcQ09IANBADYCHCADIAE2AhQgA0HCHDYCECADQR42AgxBACECDHsLIAEgBEYEQEHYACECDHsLAkACQAJAAkACQCABLQAAIgBBCmsOBAIDAwABCyABQQFqIQFBLCECDGULIABBOkcNASADQQA2AhwgAyABNgIUIANB5xE2AhAgA0EKNgIMQQAhAgx9CyABQQFqIQEgA0Evai0AAEEBcUUNcyADLQAyQYABcUUEQCADQTJqIQIgAxA1QQAhAAJAIAMoAjgiBkUNACAGKAIoIgZFDQAgAyAGEQAAIQALAkACQCAADhZNTEsBAQEBAQEBAQEBAQEBAQEBAQEAAQsgA0EpNgIcIAMgATYCFCADQawZNgIQIANBFTYCDEEAIQIMfgsg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c3BvbnNlIHN0YXR1cwBFeHBlY3RlZCBMRiBhZnRlciBoZWFkZXJzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fcmVzZXRgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19oZWFkZXJgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3Byb3RvY29sX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fcHJvdG9jb2wARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgAVHJhbnNmZXItRW5jb2RpbmcgY2FuJ3QgYmUgcHJlc2VudCB3aXRoIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAE1pc3NpbmcgZXhwZWN0ZWQgQ1IgYWZ0ZXIgY2h1bmsgc2l6ZQBFeHBlY3RlZCBMRiBhZnRlciBjaHVuayBzaXplAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBVbmV4cGVjdGVkIHdoaXRlc3BhY2UgYWZ0ZXIgaGVhZGVyIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgQ1IgYWZ0ZXIgaGVhZGVyIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUATWlzc2luZyBleHBlY3RlZCBDUiBhZnRlciBjaHVuayBleHRlbnNpb24gdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIHF1b3RlZC1wYWlyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fcHJvdG9jb2xfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUATWlzc2luZyBleHBlY3RlZCBDUiBhZnRlciByZXNwb25zZSBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAE1pc3NpbmcgZXhwZWN0ZWQgQ1IgYWZ0ZXIgY2h1bmsgZXh0ZW5zaW9uIG5hbWUASW52YWxpZCBzdGF0dXMgY29kZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABNaXNzaW5nIGV4cGVjdGVkIENSIGFmdGVyIGNodW5rIGRhdGEARXhwZWN0ZWQgTEYgYWZ0ZXIgY2h1bmsgZGF0YQBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AARGF0YSBhZnRlciBgQ29ubmVjdGlvbjogY2xvc2VgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBRVUVSWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAEV4cGVjdGVkIExGIGFmdGVyIENSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX1BST1RPQ09MX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8sIFJUU1AvIG9yIElDRS8A5xUAAK8VAACkEgAAkhoAACYWAACeFAAA2xkAAHkVAAB+EgAA/hQAADYVAAALFgAA2BYAAPMSAABCGAAArBYAABIVAAAUFwAA7xcAAEgUAABxFwAAshoAAGsZAAB+GQAANRQAAIIaAABEFwAA/RYAAB4YAACHFwAAqhkAAJMSAAAHGAAALBcAAMoXAACkFwAA5xUAAOcVAABYFwAAOxgAAKASAAAtHAAAwxEAAEgRAADeEgAAQhMAAKQZAAD9EAAA9xUAAKUVAADvFgAA+BkAAEoWAABWFgAA9RUAAAoaAAAIGgAAARoAAKsVAABCEgAA1xAAAEwRAAAFGQAAVBYAAB4RAADKGQAAyBkAAE4WAAD/GAAAcRQAAPAVAADuFQAAlBkAAPwVAAC/GQAAmxkAAHwUAABDEQAAcBgAAJUUAAAnFAAAGRQAANUSAADUGQAARBYAAPcQAEG5OwsBAQBB0DsL4AEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBuj0LBAEAAAIAQdE9C14DBAMDAwMDAAADAwADAwADAwMDAwMDAwMDAAUAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAwADAEG6PwsEAQAAAgBB0T8LXgMAAwMDAwMAAAMDAAMDAAMDAwMDAwMDAwMABAAFAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwADAAMAQbDBAAsNbG9zZWVlcC1hbGl2ZQBBycEACwEBAEHgwQAL4AEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBycMACwEBAEHgwwAL5wEBAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAWNodW5rZWQAQfHFAAteAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQBB0McACyFlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AQYDIAAsgcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQpTTQ0KDQoAQanIAAsFAQIAAQMAQcDIAAtfBAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUAQanKAAsFAQIAAQMAQcDKAAtfBAUFBgUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUAQanMAAsEAQAAAQBBwcwAC14CAgACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAEGpzgALBQECAAEDAEHAzgALXwQFAAAFBQUFBQUFBQUFBQYFBQUFBQUFBQUFBQUABQAHCAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQAFAAUABQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUAAAAFAEGp0AALBQEBAAEBAEHA0AALAQEAQdrQAAtBAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQanSAAsFAQEAAQEAQcDSAAsBAQBBytIACwYCAAAAAAIAQeHSAAs6AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBBoNQAC50BTk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRVVFUllPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFVFRQQ0VUU1BBRFRQLw==' - assert(upgrade) - assert(client[kSocket] === socket) - assert(!socket.destroyed) - assert(!this.paused) - assert((headers.length & 1) === 0) +let wasmBuffer - const request = client[kQueue][client[kRunningIdx]] - assert(request) - assert(request.upgrade || request.method === 'CONNECT') +Object.defineProperty(module, 'exports', { + get: () => { + return wasmBuffer + ? wasmBuffer + : (wasmBuffer = Buffer.from(wasmBase64, 'base64')) + } +}) - this.statusCode = null - this.statusText = '' - this.shouldKeepAlive = null - this.headers = [] - this.headersSize = 0 +/***/ }), - socket.unshift(head) +/***/ 3434: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - socket[kParser].destroy() - socket[kParser] = null +"use strict"; +/* module decorator */ module = __nccwpck_require__.nmd(module); - socket[kClient] = null - socket[kError] = null - removeAllListeners(socket) +const { Buffer } = __nccwpck_require__(4573) - client[kSocket] = null - client[kHTTPContext] = null // TODO (fix): This is hacky... - client[kQueue][client[kRunningIdx]++] = null - client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) +const wasmBase64 = 'AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAn9/AGABfwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAzU0BQYAAAMAAAAAAAADAQMAAwMDAAACAAAAAAICAgICAgICAgIBAQEBAQEBAQEBAwAAAwAAAAQFAXABExMFAwEAAgYIAX8BQcDZBAsHxQcoBm1lbW9yeQIAC19pbml0aWFsaXplAAgZX19pbmRpcmVjdF9mdW5jdGlvbl90YWJsZQEAC2xsaHR0cF9pbml0AAkYbGxodHRwX3Nob3VsZF9rZWVwX2FsaXZlADcMbGxodHRwX2FsbG9jAAsGbWFsbG9jADkLbGxodHRwX2ZyZWUADARmcmVlAAwPbGxodHRwX2dldF90eXBlAA0VbGxodHRwX2dldF9odHRwX21ham9yAA4VbGxodHRwX2dldF9odHRwX21pbm9yAA8RbGxodHRwX2dldF9tZXRob2QAEBZsbGh0dHBfZ2V0X3N0YXR1c19jb2RlABESbGxodHRwX2dldF91cGdyYWRlABIMbGxodHRwX3Jlc2V0ABMObGxodHRwX2V4ZWN1dGUAFBRsbGh0dHBfc2V0dGluZ3NfaW5pdAAVDWxsaHR0cF9maW5pc2gAFgxsbGh0dHBfcGF1c2UAFw1sbGh0dHBfcmVzdW1lABgbbGxodHRwX3Jlc3VtZV9hZnRlcl91cGdyYWRlABkQbGxodHRwX2dldF9lcnJubwAaF2xsaHR0cF9nZXRfZXJyb3JfcmVhc29uABsXbGxodHRwX3NldF9lcnJvcl9yZWFzb24AHBRsbGh0dHBfZ2V0X2Vycm9yX3BvcwAdEWxsaHR0cF9lcnJub19uYW1lAB4SbGxodHRwX21ldGhvZF9uYW1lAB8SbGxodHRwX3N0YXR1c19uYW1lACAabGxodHRw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AXRrQT5qIQILIAEgAjYCHCABQgA3AhAgAkECdEH01wBqIQACQEHI1QAoAgAiA0EBIAJ0IgdxRQRAIAAgATYCAEHI1QAgAyAHcjYCACABIAA2AhggASABNgIIIAEgATYCDAwBCyAEQRkgAkEBdmtBACACQR9HG3QhAiAAKAIAIQACQANAIAAiAygCBEF4cSAERg0BIAJBHXYhACACQQF0IQIgAyAAQQRxakEQaiIHKAIAIgANAAsgByABNgIAIAEgAzYCGCABIAE2AgwgASABNgIIDAELIAMoAggiACABNgIMIAMgATYCCCABQQA2AhggASADNgIMIAEgADYCCAtB5NUAQeTVACgCAEEBayIAQX8gABs2AgALCwcAIAAtACgLBwAgAC0AKgsHACAALQArCwcAIAAtACkLBwAgAC8BNAsHACAALQAwC0ABBH8gACgCGCEBIAAvAS4hAiAALQAoIQMgACgCOCEEIAAQOCAAIAQ2AjggACADOgAoIAAgAjsBLiAAIAE2AhgLhocCAwd/A34BeyABIAJqIQQCQCAAIgMoAgwiAA0AIAMoAgQEQCADIAE2AgQLIwBBEGsiCSQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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DAgLQeMBDAcLQdcBDAYLQdgBDAULQdkBDAQLQdoBDAMLQdsBDAILQd0BDAELQdwBCyECA0ACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAMCfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAn8CQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAwJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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A0EXNgIcIAMgADYCDCADIAFBAWo2AhQM+AILIABBFUYNI0EAIQIgA0EANgIcIAMgATYCFCADQdYMNgIQIANBIzYCDAz3AgsgAygCBCEAQQAhAiADQQA2AgQgAyAAIAEQNCIARQRAIAFBAWohAQwdCyADQRk2AhwgAyAANgIMIAMgAUEBajYCFAz2AgsgAygCBCEAQQAhAiADQQA2AgQgAyAAIAEQNCIARQRAIAFBAWohAQzvAgsgA0EaNgIcIAMgADYCDCADIAFBAWo2AhQM9QILIABBFUYNH0EAIQIgA0EANgIcIAMgATYCFCADQdAPNgIQIANBIjYCDAz0AgsgAygCBCEAIANBADYCBCADIAAgARAzIgBFBEAgAUEBaiEBDBsLIANBHDYCHCADIAA2AgwgAyABQQFqNgIUQQAhAgzzAgsgAygCBCEAIANBADYCBCADIAAgARAzIgBFBEAgAUEBaiEBDOsCCyADQR02AhwgAyAANgIMIAMgAUEBajYCFEEAIQIM8gILIABBO0cNASABQQFqIQELQSYhAgzXAgtBACECIANBADYCHCADIAE2AhQgA0GfFTYCECADQQw2AgwM7wILIAEgBEcEQANAIAEtAABBIEcNhAIgBCABQQFqIgFHDQALQSwhAgzvAgtBLCECDO4CCyABIARGBEBBNCECDO4CCwJAAkADQAJAIAEtAABBCmsOBAIAAAMACyAEIAFBAWoiAUcNAAtBNCECDO8CCyADKAIEIQAgA0EANgIEIAMgACABEDEiAEUNnwIgA0EyNgIcIAMgATYCFCADIAA2AgxBACECDO4CCyADKAIEIQAgA0EANgIEIAMgACABEDEiAEUEQCABQQFqIQEMnwILIANBMjYCHCADIAA2AgwgAyABQQFqNgIUQQAhAgztAgsgASAERwRAAkADQCABLQAAQTBrIgBB/wFxQQpPBEBBOiECDNcCCyADKQMgIgtCmbPmzJmz5swZVg0BIAMgC0IKfiIKNwMgIAogAK1C/wGDIgtCf4VWDQEgAyAKIAt8NwMgIAQgAUEBaiIBRw0AC0HAACECDO4CCyADKAIEIQAgA0EANgIEIAMgACABQQFqIgEQMSIADRcM4gILQcAAIQIM7AILIAEgBEYEQEHJACECDOwCCwJAA0ACQCABLQAAQQlrDhgAAqICogKpAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAgCiAgsgBCABQQFqIgFHDQALQckAIQIM7AILIAFBAWohASADQS9qLQAAQQFxDaUCIANBADYCHCADIAE2AhQgA0GXEDYCECADQQo2AgxBACECDOsCCyABIARHBEADQCABLQAAQSBHDRUgBCABQQFqIgFHDQALQfgAIQIM6wILQfgAIQIM6gILIANBAjoAKAw4C0EAIQIgA0EANgIcIANBvws2AhAgA0ECNgIMIAMgAUEBajYCFAzoAgtBACECDM4CC0ENIQIMzQILQRMhAgzMAgtBFSECDMsCC0EWIQIMygILQRghAgzJAgtBGSECDMgCC0EaIQIMxwILQRshAgzGAgtBHCECDMUCC0EdIQIMxAILQR4hAgzDAgtBHyECDMICC0EgIQIMwQILQSIhAgzAAgtBIyECDL8CC0ElIQIMvgILQeUAIQIMvQILIANBPTYCHCADIAE2AhQgAyAANgIMQQAhAgzVAgsgA0EbNgIcIAMgATYCFCADQaQcNgIQIANBFTYCDEEAIQIM1AILIANBIDYCHCADIAE2AhQgA0GYGjYCECADQRU2AgxBACECDNMCCyADQRM2AhwgAyABNgIUIANBmBo2AhAgA0EVNgIMQQAhAgzSAgsgA0ELNgIcIAMgATYCFCADQZgaNgIQIANBFTYCDEEAIQIM0QILIANBEDYCHCADIAE2AhQgA0GYGjYCECADQRU2AgxBACECDNACCyADQSA2AhwgAyABNgIUIANBpBw2AhAgA0EVNgIMQQAhAgzPAgsgA0ELNgIcIAMgATYCFCADQaQcNgIQIANBFTYCDEEAIQIMzgILIANBDDYCHCADIAE2AhQgA0GkHDYCECADQRU2AgxBACECDM0CC0EAIQIgA0EANgIcIAMgATYCFCADQd0ONgIQIANBEjYCDAzMAgsCQANAAkAgAS0AAEEKaw4EAAICAAILIAQgAUEBaiIBRw0AC0H9ASECDMwCCwJAAkAgAy0ANkEBRw0AQQAhAAJAIAMoAjgiAkUNACACKAJgIgJFDQAgAyACEQAAIQALIABFDQAgAEEVRw0BIANB/AE2AhwgAyABNgIUIANB3Bk2AhAgA0EVNgIMQQAhAgzNAgtB3AEhAgyzAgsgA0EANgIcIAMgATYCFCADQfkLNgIQIANBHzYCDEEAIQIMywILAkACQCADLQAoQQFrDgIEAQALQdsBIQIMsgILQdQBIQIMsQILIANBAjoAMUEAIQACQCADKAI4IgJFDQAgAigCACICRQ0AIAMgAhEAACEACyAARQRAQd0BIQIMsQILIABBFUcEQCADQQA2AhwgAyABNgIUIANBtAw2AhAgA0EQNgIMQQAhAgzKAgsgA0H7ATYCHCADIAE2AhQgA0GBGjYCECADQRU2AgxBACECDMkCCyABIARGBEBB+gEhAgzJAgsgAS0AAEHIAEYNASADQQE6ACgLQcABIQIMrgILQdoBIQIMrQILIAEgBEcEQCADQQw2AgggAyABNgIEQdkBIQIMrQILQfkBIQIMxQILIAEgBEYEQEH4ASECDMUCCyABLQAAQcgARw0EIAFBAWohAUHYASECDKsCCyABIARGBEBB9wEhAgzEAgsCQAJAIAEtAABBxQBrDhAABQUFBQUFBQUFBQUFBQUBBQsgAUEBaiEBQdYBIQIMqwILIAFBAWohAUHXASECDKoCC0H2ASECIAEgBEYNwgIgAygCACIAIAQgAWtqIQUgASAAa0ECaiEGAkADQCABLQAAIABButUAai0AAEcNAyAAQQJGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAMwwILIAMoAgQhACADQgA3AwAgAyAAIAZBAWoiARAuIgBFBEBB4wEhAgyqAgsgA0H1ATYCHCADIAE2AhQgAyAANgIMQQAhAgzCAgtB9AEhAiABIARGDcECIAMoAgAiACAEIAFraiEFIAEgAGtBAWohBgJAA0AgAS0AACAAQbjVAGotAABHDQIgAEEBRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADMICCyADQYEEOwEoIAMoAgQhACADQgA3AwAgAyAAIAZBAWoiARAuIgANAwwCCyADQQA2AgALQQAhAiADQQA2AhwgAyABNgIUIANB5R82AhAgA0EINgIMDL8CC0HVASECDKUCCyADQfMBNgIcIAMgATYCFCADIAA2AgxBACECDL0CC0EAIQACQCADKAI4IgJFDQAgAigCQCICRQ0AIAMgAhEAACEACyAARQ1uIABBFUcEQCADQQA2AhwgAyABNgIUIANBgg82AhAgA0EgNgIMQQAhAgy9AgsgA0GPATYCHCADIAE2AhQgA0HsGzYCECADQRU2AgxBACECDLwCCyABIARHBEAgA0ENNgIIIAMgATYCBEHTASECDKMCC0HyASECDLsCCyABIARGBEBB8QEhAgy7AgsCQAJAAkAgAS0AAEHIAGsOCwABCAgICAgICAgCCAsgAUEBaiEBQdABIQIMowILIAFBAWohAUHRASECDKICCyABQQFqIQFB0gEhAgyhAgtB8AEhAiABIARGDbkCIAMoAgAiACAEIAFraiEGIAEgAGtBAmohBQNAIAEtAAAgAEG11QBqLQAARw0EIABBAkYNAyAAQQFqIQAgBCABQQFqIgFHDQALIAMgBjYCAAy5AgtB7wEhAiABIARGDbgCIAMoAgAiACAEIAFraiEGIAEgAGtBAWohBQNAIAEtAAAgAEGz1QBqLQAARw0DIABBAUYNAiAAQQFqIQAgBCABQQFqIgFHDQALIAMgBjYCAAy4AgtB7gEhAiABIARGDbcCIAMoAgAiACAEIAFraiEGIAEgAGtBAmohBQNAIAEtAAAgAEGw1QBqLQAARw0CIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBjYCAAy3AgsgAygCBCEAIANCADcDACADIAAgBUEBaiIBECsiAEUNAiADQewBNgIcIAMgATYCFCADIAA2AgxBACECDLYCCyADQQA2AgALIAMoAgQhACADQQA2AgQgAyAAIAEQKyIARQ2cAiADQe0BNgIcIAMgATYCFCADIAA2AgxBACECDLQCC0HPASECDJoCC0EAIQACQCADKAI4IgJFDQAgAigCNCICRQ0AIAMgAhEAACEACwJAIAAEQCAAQRVGDQEgA0EANgIcIAMgATYCFCADQeoNNgIQIANBJjYCDEEAIQIMtAILQc4BIQIMmgILIANB6wE2AhwgAyABNgIUIANBgBs2AhAgA0EVNgIMQQAhAgyyAgsgASAERgRAQesBIQIMsgILIAEtAABBL0YEQCABQQFqIQEMAQsgA0EANgIcIAMgATYCFCADQbI4NgIQIANBCDYCDEEAIQIMsQILQc0BIQIMlwILIAEgBEcEQCADQQ42AgggAyABNgIEQcwBIQIMlwILQeoBIQIMrwILIAEgBEYEQEHpASECDK8CCyABLQAAQTBrIgBB/wFxQQpJBEAgAyAAOgAqIAFBAWohAUHLASECDJYCCyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNlwIgA0HoATYCHCADIAE2AhQgAyAANgIMQQAhAgyuAgsgASAERgRAQecBIQIMrgILAkAgAS0AAEEuRgRAIAFBAWohAQwBCyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNmAIgA0HmATYCHCADIAE2AhQgAyAANgIMQQAhAgyuAgtBygEhAgyUAgsgASAERgRAQeUBIQIMrQILQQAhAEEBIQVBASEHQQAhAgJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAIAEtAABBMGsOCgoJAAECAwQFBggLC0ECDAYLQQMMBQtBBAwEC0EFDAMLQQYMAgtBBwwBC0EICyECQQAhBUEAIQcMAgtBCSECQQEhAEEAIQVBACEHDAELQQAhBUEBIQILIAMgAjoAKyABQQFqIQECQAJAIAMtAC5BEHENAAJAAkACQCADLQAqDgMBAAIECyAHRQ0DDAILIAANAQwCCyAFRQ0BCyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNAiADQeIBNgIcIAMgATYCFCADIAA2AgxBACECDK8CCyADKAIEIQAgA0EANgIEIAMgACABEC8iAEUNmgIgA0HjATYCHCADIAE2AhQgAyAANgIMQQAhAgyuAgsgAygCBCEAIANBADYCBCADIAAgARAvIgBFDZgCIANB5AE2AhwgAyABNgIUIAMgADYCDAytAgtByQEhAgyTAgtBACEAAkAgAygCOCICRQ0AIAIoAkQiAkUNACADIAIRAAAhAAsCQCAABEAgAEEVRg0BIANBADYCHCADIAE2AhQgA0GkDTYCECADQSE2AgxBACECDK0CC0HIASECDJMCCyADQeEBNgIcIAMgATYCFCADQdAaNgIQIANBFTYCDEEAIQIMqwILIAEgBEYEQEHhASECDKsCCwJAIAEtAABBIEYEQCADQQA7ATQgAUEBaiEBDAELIANBADYCHCADIAE2AhQgA0GZETYCECADQQk2AgxBACECDKsCC0HHASECDJECCyABIARGBEBB4AEhAgyqAgsCQCABLQAAQTBrQf8BcSICQQpJBEAgAUEBaiEBAkAgAy8BNCIAQZkzSw0AIAMgAEEKbCIAOwE0IABB/v8DcSACQf//A3NLDQAgAyAAIAJqOwE0DAILQQAhAiADQQA2AhwgAyABNgIUIANBlR42AhAgA0ENNgIMDKsCCyADQQA2AhwgAyABNgIUIANBlR42AhAgA0ENNgIMQQAhAgyqAgtBxgEhAgyQAgsgASAERgRAQd8BIQIMqQILAkAgAS0AAEEwa0H/AXEiAkEKSQRAIAFBAWohAQJAIAMvATQiAEGZM0sNACADIABBCmwiADsBNCAAQf7/A3EgAkH//wNzSw0AIAMgACACajsBNAwCC0EAIQIgA0EANgIcIAMgATYCFCADQZUeNgIQIANBDTYCDAyqAgsgA0EANgIcIAMgATYCFCADQZUeNgIQIANBDTYCDEEAIQIMqQILQcUBIQIMjwILIAEgBEYEQEHeASECDKgCCwJAIAEtAABBMGtB/wFxIgJBCkkEQCABQQFqIQECQCADLwE0IgBBmTNLDQAgAyAAQQpsIgA7ATQgAEH+/wNxIAJB//8Dc0sNACADIAAgAmo7ATQMAgtBACECIANBADYCHCADIAE2AhQgA0GVHjYCECADQQ02AgwMqQILIANBADYCHCADIAE2AhQgA0GVHjYCECADQQ02AgxBACECDKgCC0HEASECDI4CCyABIARGBEBB3QEhAgynAgsCQAJAAkACQCABLQAAQQprDhcCAwMAAwMDAwMDAwMDAwMDAwMDAwMDAQMLIAFBAWoMBQsgAUEBaiEBQcMBIQIMjwILIAFBAWohASADQS9qLQAAQQFxDQggA0EANgIcIAMgATYCFCADQY0LNgIQIANBDTYCDEEAIQIMpwILIANBADYCHCADIAE2AhQgA0GNCzYCECADQQ02AgxBACECDKYCCyABIARHBEAgA0EPNgIIIAMgATYCBEEBIQIMjQILQdwBIQIMpQILAkACQANAAkAgAS0AAEEKaw4EAgAAAwALIAQgAUEBaiIBRw0AC0HbASECDKYCCyADKAIEIQAgA0EANgIEIAMgACABEC0iAEUEQCABQQFqIQEMBAsgA0HaATYCHCADIAA2AgwgAyABQQFqNgIUQQAhAgylAgsgAygCBCEAIANBADYCBCADIAAgARAtIgANASABQQFqCyEBQcEBIQIMigILIANB2QE2AhwgAyAANgIMIAMgAUEBajYCFEEAIQIMogILQcIBIQIMiAILIANBL2otAABBAXENASADQQA2AhwgAyABNgIUIANB5Bw2AhAgA0EZNgIMQQAhAgygAgsgASAERgRAQdkB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CyADIAU2AgAMkAILIANBADYCACAGQQFqIQFBGgw8C0HKASECIAEgBEYNjgIgAygCACIAIAQgAWtqIQUgASAAa0EDaiEGAkADQCABLQAAIABBjdUAai0AAEcNOyAAQQNGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAMjwILIANBADYCACAGQQFqIQFBIQw7CyABIARGBEBByQEhAgyOAgsCQAJAIAEtAABBwQBrDhQAPT09PT09PT09PT09PT09PT09AT0LIAFBAWohAUGtASECDPUBCyABQQFqIQFBsAEhAgz0AQsgASAERgRAQcgBIQIMjQILAkACQCABLQAAQdUAaw4LADw8PDw8PDw8PAE8CyABQQFqIQFBrgEhAgz0AQsgAUEBaiEBQa8BIQIM8wELQccBIQIgASAERg2LAiADKAIAIgAgBCABa2ohBSABIABrQQhqIQYCQANAIAEtAAAgAEGE1QBqLQAARw04IABBCEYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAyMAgsgA0EANgIAIAZBAWohAUEqDDgLIAEgBEYEQEHGASECDIsCCyABLQAAQdAARw04IAFBAWohAUElDDcLQcUBIQIgASAERg2JAiADKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGB1QBqLQAARw02IABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAyKAgsgA0EANgIAIAZBAWohAUEODDYLIAEgBEYEQEHEASECDIkCCyABLQAAQcUARw02IAFBAWohAUGrASECDO8BCyABIARGBEBBwwEhAgyIAgsCQAJAAkACQCABLQAAQcIAaw4PAAECOTk5OTk5OTk5OTkDOQsgAUEBaiEBQacBIQIM8QELIAFBAWohAUGoASECDPABCyABQQFqIQFBqQEhAgzvAQsgAUEBaiEBQaoBIQIM7gELQcIBIQIgASAERg2GAiADKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEH+1ABqLQAARw0zIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAyHAgsgA0EANgIAIAZBAWohAUEUDDMLQcEBIQIgASAERg2FAiADKAIAIgAgBCABa2ohBSABIABrQQRqIQYCQANA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BTYCAAzsAQsgA0EANgIAIAZBAWohAUEXDBgLQaYBIQIgASAERg3qASADKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEHB1ABqLQAARw0XIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzrAQsgA0EANgIAIAZBAWohAUEYDBcLIAEgBEYEQEGlASECDOoBCwJAAkAgAS0AAEHJAGsOBwAZGRkZGQEZCyABQQFqIQFBiwEhAgzRAQsgAUEBaiEBQYwBIQIM0AELQaQBIQIgASAERg3oASADKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEGm1QBqLQAARw0VIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzpAQsgA0EANgIAIAZBAWohAUEJDBULQaMBIQIgASAERg3nASADKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEGk1QBqLQAARw0UIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzoAQsgA0EANgIAIAZBAWohAUEfDBQLQaIBIQIgASAERg3mASADKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEG+1ABqLQAARw0TIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAznAQsgA0EANgIAIAZBAWohAUECDBMLQaEBIQIgASAERg3lASADKAIAIgAgBCABa2ohBSABIABrQQFqIQYDQCABLQAAIABBvNQAai0AAEcNESAAQQFGDQIgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM5QELIAEgBEYEQEGgASECDOUBC0EBIAEtAABB3wBHDREaIAFBAWohAUGHASECDMsBCyADQQA2AgAgBkEBaiEBQYgBIQIMygELQZ8BIQIgASAERg3iASADKAIAIgAgBCABa2ohBSABIABrQQhqIQYCQANAIAEtAAAgAEGE1QBqLQAARw0PIABBCEYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAzjAQsgA0EANgIAIAZBAWohAUEpDA8LQZ4BIQIgASAERg3hASADKAIAIgAgBCABa2ohBSABIABrQQNqIQYCQANAIAEtAAAgAEG41ABqLQAARw0OIABBA0YNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAziAQsgA0EANgIAIAZBAWohAUEtDA4LIAEgBEYEQEGdASECDOEBCyABLQAAQcUARw0OIAFBAWohAUGEASECDMcBCyABIARGBEBBnAEhAgzgAQsCQAJAIAEtAABBzABrDggADw8PDw8PAQ8LIAFBAWohAUGCASECDMcBCyABQQFqIQFBgwEhAgzGAQtBmwEhAiABIARGDd4BIAMoAgAiACAEIAFraiEFIAEgAGtBBGohBgJAA0AgAS0AACAAQbPUAGotAABHDQsgAEEERg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADN8BCyADQQA2AgAgBkEBaiEBQSMMCwtBmgEhAiABIARGDd0BIAMoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQbDUAGotAABHDQogAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADN4BCyADQQA2AgAgBkEBaiEBQQAMCgsgASAERgRAQZkBIQIM3QELAkACQCABLQAAQcgAaw4IAAwMDAwMDAEMCyABQQFqIQFB/QAhAgzEAQsgAUEBaiEBQYABIQIMwwELIAEgBEYEQEGYASECDNwBCwJAAkAgAS0AAEHOAGsOAwALAQsLIAFBAWohAUH+ACECDMMBCyABQQFqIQFB/wAhAgzCAQsgASAERgRAQZcBIQIM2wELIAEtAABB2QBHDQggAUEBaiEBQQgMBwtBlgEhAiABIARGDdkBIAMoAgAiACAEIAFraiEFIAEgAGtBA2ohBgJAA0AgAS0AACAAQazUAGotAABHDQYgAEEDRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADNoBCyADQQA2AgAgBkEBaiEBQQUMBgtBlQEhAiABIARGDdgBIAMoAgAiACAEIAFraiEFIAEgAGtBBWohBgJAA0AgAS0AACAAQabUAGotAABHDQUgAEEFRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADNkBCyADQQA2AgAgBkEBaiEBQRYMBQtBlAEhAiABIARGDdcBIAMoAgAiACAEIAFraiEFIAEgAGtBAmohBgJAA0AgAS0AACAAQaHVAGotAABHDQQgAEECRg0BIABBAWohACAEIAFBAWoiAUcNAAsgAyAFNgIADNgBCyADQQA2AgAgBkEBaiEBQRAMBAsgASAERgRAQZMBIQIM1wELAkACQCABLQAAQcMAaw4MAAYGBgYGBgYGBgYBBgsgAUEBaiEBQfkAIQIMvgELIAFBAWohAUH6ACECDL0BC0GSASECIAEgBEYN1QEgAygCACIAIAQgAWtqIQUgASAAa0EFaiEGAkADQCABLQAAIABBoNQAai0AAEcNAiAAQQVGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAM1gELIANBADYCACAGQQFqIQFBJAwCCyADQQA2AgAMAgsgASAERgRAQZEBIQIM1AELIAEtAABBzABHDQEgAUEBaiEBQRMLOgApIAMoAgQhACADQQA2AgQgAyAAIAEQLiIADQIMAQtBACECIANBADYCHCADIAE2AhQgA0H+HzYCECADQQY2AgwM0QELQfgAIQIMtwELIANBkAE2AhwgAyABNgIUIAMgADYCDEEAIQIMzwELQQAhAAJAIAMoAjgiAkUNACACKAJAIgJFDQAgAyACEQAAIQALIABFDQAgAEEVRg0BIANBADYCHCADIAE2AhQgA0GCDzYCECADQSA2AgxBACECDM4BC0H3ACECDLQBCyADQY8BNgIcIAMgATYCFCADQewbNgIQIANBFTYCDEEAIQIMzAELIAEgBEYEQEGPASECDMwBCwJAIAEtAABBIEYEQCABQQFqIQEMAQsgA0EANgIcIAMgATYCFCADQZsfNgIQIANBBjYCDEEAIQIMzAELQQIhAgyyAQsDQCABLQAAQSBHDQIgBCABQQFqIgFHDQALQY4BIQIMygELIAEgBEYEQEGNASECDMoBCwJAIAEtAABBCWsOBEoAAEoAC0H1ACECDLABCyADLQApQQVGBEBB9gAhAgywAQtB9AAhAgyvAQsgASAERgRAQYwBIQIMyAELIANBEDYCCCADIAE2AgQMCgsgASAERgRAQYsBIQIMxwELAkAgAS0AAEEJaw4ERwAARwALQfMAIQIMrQELIAEgBEcEQCADQRA2AgggAyABNgIEQfEAIQIMrQELQYoBIQIMxQELAkAgASAERwRAA0AgAS0AAEGg0ABqLQAAIgBBA0cEQAJAIABBAWsOAkkABAtB8AAhAgyvAQsgBCABQQFqIgFHDQALQYgBIQIMxgELQYgBIQIMxQELIANBADYCHCADIAE2AhQgA0HbIDYCECADQQc2AgxBACECDMQBCyABIARGBEBBiQEhAgzEAQsCQAJAAkAgAS0AAEGg0gBqLQAAQQFrDgNGAgABC0HyACECDKwBCyADQQA2AhwgAyABNgIUIANBtBI2AhAgA0EHNgIMQQAhAgzEAQtB6gAhAgyqAQsgASAERwRAIAFBAWohAUHvACECDKoBC0GHASECDMIBCyAEIAEiAEYEQEGGASECDMIBCyAALQAAIgFBL0YEQCAAQQFqIQFB7gAhAgypAQsgAUEJayICQRdLDQEgACEBQQEgAnRBm4CABHENQQwBCyAEIAEiAEYEQEGFASECDMEBCyAALQAAQS9HDQAgAEEBaiEBDAMLQQAhAiADQQA2AhwgAyAANgIUIANB2yA2AhAgA0EHNgIMDL8BCwJAAkACQAJAAkADQCABLQAAQaDOAGotAAAiAEEFRwRAAkACQCAAQQFrDghHBQYHCAAEAQgLQesAIQIMrQELIAFBAWohAUHtACECDKwBCyAEIAFBAWoiAUcNAAtBhAEhAgzDAQsgAUEBagwUCyADKAIEIQAgA0EANgIEIAMgACABECwiAEUNHiADQdsANgIcIAMgATYCFCADIAA2AgxBACECDMEBCyADKAIEIQAgA0EANgIEIAMgACABECwiAEUNHiADQd0ANgIcIAMgATYCFCADIAA2AgxBACECDMABCyADKAIEIQAgA0EANgIEIAMgACABECwiAEUNHiADQfoANgIcIAMgATYCFCADIAA2AgxBACECDL8BCyADQQA2AhwgAyABNgIUIANB+Q82AhAgA0EHNgIMQQAhAgy+AQsgASAERgRAQYMBIQIMvgELAkAgAS0AAEGgzgBqLQAAQQFrDgg+BAUGAAgCAwcLIAFBAWohAQtBAyECDKMBCyABQQFqDA0LQQAhAiADQQA2AhwgA0HREjYCECADQQc2AgwgAyABQQFqNgIUDLoBCyADKAIEIQAgA0EANgIEIAMgACABECwiAEUNFiADQdsANgIcIAMgATYCFCADIAA2AgxBACECDLkBCyADKAIEIQAgA0EANgIEIAMgACABECwiAEUNFiADQd0ANgIcIAMgATYCFCADIAA2AgxBACECDLgBCyADKAIEIQAgA0EANgIEIAMgACABECwiAEUNFiADQfoANgIcIAMgATYCFCADIAA2AgxBACECDLcBCyADQQA2AhwgAyABNgIUIANB+Q82AhAgA0EHNgIMQQAhAgy2AQtB7AAhAgycAQsgASAERgRAQYIBIQIMtQELIAFBAWoMAgsgASAERgRAQYEBIQIMtAELIAFBAWoMAQsgASAERg0BIAFBAWoLIQFBBCECDJgBC0GAASECDLABCwNAIAEtAABBoMwAai0AACIAQQJHBEAgAEEBRwRAQekAIQIMmQELDDELIAQgAUEBaiIBRw0AC0H/ACECDK8BCyABIARGBEBB/gAhAgyvAQsCQCABLQAAQQlrDjcvAwYvBAYGBgYGBgYGBgYGBgYGBgYGBgUGBgIGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYABgsgAUEBagshAUEFIQIMlAELIAFBAWoMBgsgAygCBCEAIANBADYCBCADIAAgARAsIgBFDQggA0HbADYCHCADIAE2AhQgAyAANgIMQQAhAgyrAQsgAygCBCEAIANBADYCBCADIAAgARAsIgBFDQggA0HdADYCHCADIAE2AhQgAyAANgIMQQAhAgyqAQsgAygCBCEAIANBADYCBCADIAAgARAsIgBFDQggA0H6ADYCHCADIAE2AhQgAyAANgIMQQAhAgypAQsgA0EANgIcIAMgATYCFCADQY0UNgIQIANBBzYCDEEAIQIMqAELAkACQAJAAkADQCABLQAAQaDKAGotAAAiAEEFRwRAAkAgAEEBaw4GLgMEBQYABgtB6AAhAgyUAQsgBCABQQFqIgFHDQALQf0AIQIMqwELIAMoAgQhACADQQA2AgQgAyAAIAEQLCIARQ0HIANB2wA2AhwgAyABNgIUIAMgADYCDEEAIQIMqgELIAMoAgQhACADQQA2AgQgAyAAIAEQLCIARQ0HIANB3QA2AhwgAyABNgIUIAMgADYCDEEAIQIMqQELIAMoAgQhACADQQA2AgQgAyAAIAEQLCIARQ0HIANB+gA2AhwgAyABNgIUIAMgADYCDEEAIQIMqAELIANBADYCHCADIAE2AhQgA0HkCDYCECADQQc2AgxBACECDKcBCyABIARGDQEgAUEBagshAUEGIQIMjAELQfwAIQIMpAELAkACQAJAAkADQCABLQAAQaDIAGotAAAiAEEFRwRAIABBAWsOBCkCAwQFCyAEIAFBAWoiAUcNAAtB+wAhAgynAQsgAygCBCEAIANBADYCBCADIAAgARAsIgBFDQMgA0HbADYCHCADIAE2AhQgAyAANgIMQQAhAgymAQsgAygCBCEAIANBADYCBCADIAAgARAsIgBFDQMgA0HdADYCHCADIAE2AhQgAyAANgIMQQAhAgylAQsgAygCBCEAIANBADYCBCADIAAgARAsIgBFDQMgA0H6ADYCHCADIAE2AhQgAyAANgIMQQAhAgykAQsgA0EANgIcIAMgATYCFCADQbwKNgIQIANBBzYCDEEAIQIMowELQc8AIQIMiQELQdEAIQIMiAELQecAIQIMhwELIAEgBEYEQEH6ACECDKABCwJAIAEtAABBCWsOBCAAACAACyABQQFqIQFB5gAhAgyGAQsgASAERgRAQfkAIQIMnwELAkAgAS0AAEEJaw4EHwAAHwALQQAhAAJAIAMoAjgiAkUNACACKAI4IgJFDQAgAyACEQAAIQALIABFBEBB4gEhAgyGAQsgAEEVRwRAIANBADYCHCADIAE2AhQgA0HJDTYCECADQRo2AgxBACECDJ8BCyADQfgANgIcIAMgATYCFCADQeoaNgIQIANBFTYCDEEAIQIMngELIAEgBEcEQCADQQ02AgggAyABNgIEQeQAIQIMhQELQfcAIQIMnQELIAEgBEYEQEH2ACECDJ0BCwJAAkACQCABLQAAQcgAaw4LAAELCwsLCwsLCwILCyABQQFqIQFB3QAhAgyFAQsgAUEBaiEBQeAAIQIMhAELIAFBAWohAUHjACECDIMBC0H1ACECIAEgBEYNmwEgAygCACIAIAQgAWtqIQUgASAAa0ECaiEGAkADQCABLQAAIABBtdUAai0AAEcNCCAAQQJGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAMnAELIAMoAgQhACADQgA3AwAgAyAAIAZBAWoiARArIgAEQCADQfQANgIcIAMgATYCFCADIAA2AgxBACECDJwBC0HiACECDIIBC0EAIQACQCADKAI4IgJFDQAgAigCNCICRQ0AIAMgAhEAACEACwJAIAAEQCAAQRVGDQEgA0EANgIcIAMgATYCFCADQeoNNgIQIANBJjYCDEEAIQIMnAELQeEAIQIMggELIANB8wA2AhwgAyABNgIUIANBgBs2AhAgA0EVNgIMQQAhAgyaAQsgAy0AKSIAQSNrQQtJDQkCQCAAQQZLDQBBASAAdEHKAHFFDQAMCgtBACECIANBADYCHCADIAE2AhQgA0HtCTYCECADQQg2AgwMmQELQfIAIQIgASAERg2YASADKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEGz1QBqLQAARw0FIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAMgBTYCAAyZAQsgAygCBCEAIANCADcDACADIAAgBkEBaiIBECsiAARAIANB8QA2AhwgAyABNgIUIAMgADYCDEEAIQIMmQELQd8AIQIMfwtBACEAAkAgAygCOCICRQ0AIAIoAjQiAkUNACADIAIRAAAhAAsCQCAABEAgAEEVRg0BIANBADYCHCADIAE2AhQgA0HqDTYCECADQSY2AgxBACECDJkBC0HeACECDH8LIANB8AA2AhwgAyABNgIUIANBgBs2AhAgA0EVNgIMQQAhAgyXAQsgAy0AKUEhRg0GIANBADYCHCADIAE2AhQgA0GRCjYCECADQQg2AgxBACECDJYBC0HvACECIAEgBEYNlQEgAygCACIAIAQgAWtqIQUgASAAa0ECaiEGAkADQCABLQAAIABBsNUAai0AAEcNAiAAQQJGDQEgAEEBaiEAIAQgAUEBaiIBRw0ACyADIAU2AgAMlgELIAMoAgQhACADQgA3AwAgAyAAIAZBAWoiARArIgBFDQIgA0HtADYCHCADIAE2AhQgAyAANgIMQQAhAgyVAQsgA0EANgIACyADKAIEIQAgA0EANgIEIAMgACABECsiAEUNgAEgA0HuADYCHCADIAE2AhQgAyAANgIMQQAhAgyTAQtB3AAhAgx5C0EAIQACQCADKAI4IgJFDQAgAigCNCICRQ0AIAMgAhEAACEACwJAIAAEQCAAQRVGDQEgA0EANgIcIAMgATYCFCADQeoNNgIQIANBJjYCDEEAIQIMkwELQdsAIQIMeQsgA0HsADYCHCADIAE2AhQgA0GAGzYCECADQRU2AgxBACECDJEBCyADLQApIgBBI0kNACAAQS5GDQAgA0EANgIcIAMgATYCFCADQckJNgIQIANBCDYCDEEAIQIMkAELQdoAIQIMdgsgASAERgRAQesAIQIMjwELAkAgAS0AAEEvRgRAIAFBAWohAQwBCyAD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ciBIVFRQL3gueCByZXF1ZXN0AEludmFsaWQgbWV0aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBFeHBlY3RlZCBMRiBhZnRlciBoZWFkZXJzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fcmVzZXRgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19oZWFkZXJgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3Byb3RvY29sX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fcHJvdG9jb2wARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgAVHJhbnNmZXItRW5jb2RpbmcgY2FuJ3QgYmUgcHJlc2VudCB3aXRoIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAE1pc3NpbmcgZXhwZWN0ZWQgQ1IgYWZ0ZXIgY2h1bmsgc2l6ZQBFeHBlY3RlZCBMRiBhZnRlciBjaHVuayBzaXplAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBVbmV4cGVjdGVkIHdoaXRlc3BhY2UgYWZ0ZXIgaGVhZGVyIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgQ1IgYWZ0ZXIgaGVhZGVyIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUATWlzc2luZyBleHBlY3RlZCBDUiBhZnRlciBjaHVuayBleHRlbnNpb24gdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIHF1b3RlZC1wYWlyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fcHJvdG9jb2xfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUATWlzc2luZyBleHBlY3RlZCBDUiBhZnRlciByZXNwb25zZSBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAE1pc3NpbmcgZXhwZWN0ZWQgQ1IgYWZ0ZXIgY2h1bmsgZXh0ZW5zaW9uIG5hbWUASW52YWxpZCBzdGF0dXMgY29kZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABNaXNzaW5nIGV4cGVjdGVkIENSIGFmdGVyIGNodW5rIGRhdGEARXhwZWN0ZWQgTEYgYWZ0ZXIgY2h1bmsgZGF0YQBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AARGF0YSBhZnRlciBgQ29ubmVjdGlvbjogY2xvc2VgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBRVUVSWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAEV4cGVjdGVkIExGIGFmdGVyIENSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX1BST1RPQ09MX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8sIFJUU1AvIG9yIElDRS8A5xUAAK8VAACkEgAAkhoAACYWAACeFAAA2xkAAHkVAAB+EgAA/hQAADYVAAALFgAA2BYAAPMSAABCGAAArBYAABIVAAAUFwAA7xcAAEgUAABxFwAAshoAAGsZAAB+GQAANRQAAIIaAABEFwAA/RYAAB4YAACHFwAAqhkAAJMSAAAHGAAALBcAAMoXAACkFwAA5xUAAOcVAABYFwAAOxgAAKASAAAtHAAAwxEAAEgRAADeEgAAQhMAAKQZAAD9EAAA9xUAAKUVAADvFgAA+BkAAEoWAABWFgAA9RUAAAoaAAAIGgAAARoAAKsVAABCEgAA1xAAAEwRAAAFGQAAVBYAAB4RAADKGQAAyBkAAE4WAAD/GAAAcRQAAPAVAADuFQAAlBkAAPwVAAC/GQAAmxkAAHwUAABDEQAAcBgAAJUUAAAnFAAAGRQAANUSAADUGQAARBYAAPcQAEG5OwsBAQBB0DsL4AEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBuj0LBAEAAAIAQdE9C14DBAMDAwMDAAADAwADAwADAwMDAwMDAwMDAAUAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAwADAEG6PwsEAQAAAgBB0T8LXgMAAwMDAwMAAAMDAAMDAAMDAwMDAwMDAwMABAAFAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwADAAMAQbDBAAsNbG9zZWVlcC1hbGl2ZQBBycEACwEBAEHgwQAL4AEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBycMACwEBAEHgwwAL5wEBAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAWNodW5rZWQAQfHFAAteAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQBB0McACyFlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AQYDIAAsgcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQpTTQ0KDQoAQanIAAsFAQIAAQMAQcDIAAtfBAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUAQanKAAsFAQIAAQMAQcDKAAtfBAUFBgUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUAQanMAAsEAQAAAQBBwcwAC14CAgACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAEGpzgALBQECAAEDAEHAzgALXwQFAAAFBQUFBQUFBQUFBQYFBQUFBQUFBQUFBQUABQAHCAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQAFAAUABQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUAAAAFAEGp0AALBQEBAAEBAEHA0AALAQEAQdrQAAtBAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQanSAAsFAQEAAQEAQcDSAAsBAQBBytIACwYCAAAAAAIAQeHSAAs6AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBBoNQAC50BTk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRVVFUllPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFVFRQQ0VUU1BBRFRQLw==' - try { - request.onUpgrade(statusCode, headers, socket) - } catch (err) { - util.destroy(socket, err) - } +let wasmBuffer - client[kResume]() +Object.defineProperty(module, 'exports', { + get: () => { + return wasmBuffer + ? wasmBuffer + : (wasmBuffer = Buffer.from(wasmBase64, 'base64')) } +}) - onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { - const { client, socket, headers, statusText } = this - - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 - } - const request = client[kQueue][client[kRunningIdx]] +/***/ }), - /* istanbul ignore next: difficult to make a test case for */ - if (!request) { - return -1 - } +/***/ 172: +/***/ ((__unused_webpack_module, exports) => { - assert(!this.upgrade) - assert(this.statusCode < 200) +"use strict"; - if (statusCode === 100) { - util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) - return -1 - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.enumToMap = enumToMap; +function enumToMap(obj, filter = [], exceptions = []) { + const emptyFilter = (filter?.length ?? 0) === 0; + const emptyExceptions = (exceptions?.length ?? 0) === 0; + return Object.fromEntries(Object.entries(obj).filter(([, value]) => { + return (typeof value === 'number' && + (emptyFilter || filter.includes(value)) && + (emptyExceptions || !exceptions.includes(value))); + })); +} - /* this can only happen if server is misbehaving */ - if (upgrade && !request.upgrade) { - util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))) - return -1 - } - assert(this.timeoutType === TIMEOUT_HEADERS) +/***/ }), - this.statusCode = statusCode - this.shouldKeepAlive = ( - shouldKeepAlive || - // Override llhttp value which does not allow keepAlive for HEAD. - (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') - ) +/***/ 5997: +/***/ ((module) => { - if (this.statusCode >= 200) { - const bodyTimeout = request.bodyTimeout != null - ? request.bodyTimeout - : client[kBodyTimeout] - this.setTimeout(bodyTimeout, TIMEOUT_BODY) - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } +const wasmModule = new WebAssembly.Module( + Buffer.from( + 'AGFzbQEAAAABQgtgA39/fwBgAX8Bf2ACf38AYAF/AGABfwF+YAJ/fgBgBH9/f38AYAABf2AIf39/f39/f3wAYAN/f38Bf2ACf38BfwKUBBwDZW52CG9uX2Vycm9yAAADZW52Cm9uX2hlYWRlcnMACANlbnYJb25fZmluaXNoAAADZW52EG9uX21lc3NhZ2Vfc3RhcnQAAANlbnYTb25fbWVzc2FnZV9jb21wbGV0ZQAAA2Vudgpvbl9yZXF1ZXN0AAADZW52C29uX3Jlc3BvbnNlAAADZW52CG9uX3Jlc2V0AAADZW52CW9uX21ldGhvZAAAA2VudgZvbl91cmwAAANlbnYLb25fcHJvdG9jb2wAAANlbnYKb25fdmVyc2lvbgAAA2Vudglvbl9zdGF0dXMAAANlbnYJb25fcmVhc29uAAADZW52Dm9uX2hlYWRlcl9uYW1lAAADZW52D29uX2hlYWRlcl92YWx1ZQAAA2Vudgpvbl9jb25uZWN0AAADZW52Cm9uX3VwZ3JhZGUAAANlbnYPb25fY2h1bmtfbGVuZ3RoAAADZW52F29uX2NodW5rX2V4dGVuc2lvbl9uYW1lAAADZW52GG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQAAA2Vudghvbl9jaHVuawAAA2Vudgdvbl9ib2R5AAADZW52B29uX2RhdGEAAANlbnYPb25fdHJhaWxlcl9uYW1lAAADZW52EG9uX3RyYWlsZXJfdmFsdWUAAANlbnYLb25fdHJhaWxlcnMAAANlbnYPb25fc3RhdGVfY2hhbmdlAAADQUAGAQMDBwIDBgMEBAEEBAEBAQQBBAQBAQEBAQEBAQEBAQEBAQcJAwIDBQUCAgIFAgICAgICAgEBAQEKAQIDAgICBQMBABEGCQF/AUGAgMAACwedCDkGbWVtb3J5AgAFYWxsb2MAHQVjbGVhcgAeCGNvbXBsZXRlAB8GY3JlYXRlACAHZGVhbGxvYwAhB2Rlc3Ryb3kAIgRmYWlsACMGZmluaXNoACQOZ2V0X2NodW5rX3NpemUAJRJnZXRfY29udGVudF9sZW5ndGgAJg5nZXRfZXJyb3JfY29kZQAnGWdldF9lcnJvcl9kZXNjcmlwdGlvbl9yYXcAKBRnZXRfbWF4X2JvZHlfcGF5bG9hZAApFWdldF9tYXhfaGVhZGVyX2xlbmd0aAAqGWdldF9tYXhfc3RhcnRfbGluZV9sZW5ndGgAKwpnZXRfbWV0aG9kACwKZ2V0X3BhcnNlZAAtDGdldF9wb3NpdGlvbgAuGGdldF9yZW1haW5pbmdfY2h1bmtfc2l6ZQAvHGdldF9yZW1haW5pbmdfY29udGVudF9sZW5ndGgAMAlnZXRfc3RhdGUAMQpnZXRfc3RhdHVzADIdaGFzX2NodW5rZWRfdHJhbnNmZXJfZW5jb2RpbmcAMxRoYXNfY29ubmVjdGlvbl9jbG9zZQA0Fmhhc19jb25uZWN0aW9uX3VwZ3JhZGUANRJoYXNfY29udGVudF9sZW5ndGgANgxoYXNfdHJhaWxlcnMANxVoYXNfdHJhbnNmZXJfZW5jb2RpbmcAOAtoYXNfdXBncmFkZQA5DWlzX2F1dG9kZXRlY3QAOgppc19jb25uZWN0ADsIaXNfZGVidWcAPAlpc19wYXVzZWQAPQppc19yZXF1ZXN0AD4ObWlsb19oYXNfZGVidWcAPwVwYXJzZQBABXBhdXNlAEEFcmVzZXQAQgZyZXN1bWUAQxRzZXRfYWN0aXZlX2NhbGxiYWNrcwBEEXNldF9hY3RpdmVfZXZlbnRzAEUJc2V0X2RlYnVnAEYOc2V0X2lzX2Nvbm5lY3QARw5zZXRfaXNfcmVxdWVzdABIFHNldF9tYXhfYm9keV9wYXlsb2FkAEkVc2V0X21heF9oZWFkZXJfbGVuZ3RoAEoZc2V0X21heF9zdGFydF9saW5lX2xlbmd0aABLFXNldF9zaG91bGRfYXV0b2RldGVjdABMIHNldF9zaG91bGRfY29udGludWVfd2l0aG91dF9kYXRhAE0cc2V0X3Nob3VsZF9tYW5hZ2VfdW5jb25zdW1lZABOFHNldF9zaG91bGRfc2tpcF9ib2R5AE8gc2V0X3Nob3VsZF9zdXNwZW5kX2FmdGVyX2hlYWRlcnMAUBxzaG91bGRfY29udGludWVfd2l0aG91dF9kYXRhAFEYc2hvdWxkX21hbmFnZV91bmNvbnN1bWVkAFIQc2hvdWxkX3NraXBfYm9keQBTHHNob3VsZF9zdXNwZW5kX2FmdGVyX2hlYWRlcnMAVAr7pwJAlgIBBH8CQCACIANPDQAgAS0AACEFAkAgAyACayIHQQNNBEAMAQtBgIKECCAFQYGChAhsIgEgAigAAHMiBmsgBnJBgIGChHhxQYCBgoR4RwRADAELIAJBfHFBBGohAgJAIAdBCU8EQCACIANBCGsiB0sNAQNAQYCChAggAigCACABcyIGayAGckGAgYKEeHFBgIGChHhHDQJBgIKECCACQQRqKAIAIAFzIgZrIAZyQYCBgoR4cUGAgYKEeEcNAiACQQhqIgIgB00NAAsMAQsgAiADTw0CDAELIAIgA08NAQsgA0EBa0EBIQQDQCAFIAItAABGDQEgAkEBaiICIANHDQALIQJBACEECyAAIAI2AgQgACAENgIACyYAAkAgAEEATgRAIABFBEBBASEADAILIABBARBVIgANAQsACyAACzMAIABCADcDKCAAQQA6ABUgAEIANwMwIABCADcDOCAAQgA3A0AgAEIANwNIIABBADYCUAvSAwIDfwF+AkAgACIBLQAkIgBBDk1BAEEBIAB0QYDPAXEbRQRAIAFBAzoAJiABQQI6ACQgAUENOgD0AkEAIQAgAUEAOgB5IAFBp5jAACkAADcAbCABQayYwAApAAA3AHECQCABKQNYIAEpA2CEp0EBcUUEQCABKAL4AiECDAELIAEoAvgCIgJBAToAACACQQVqQQM6AAAgAkEBaiABKAIgNgAAQQYhAAsgACACakEAOgAADAELAn9BACABKQNYIAEpA2CEIgRCyACDUA0AGiAEQgiDQgBSBEAgASgC+AIiAEEEOgAAIABBBWpBADYAACAAQQFqIAEoAiA2AABBCSECCyACIARCwACDUA0AGiABKAL4AiACaiIAQQc6AAAgAEEFakEANgAAIABBAWogASgCIDYAACACQQlqCyECIAFBADoAFiABQQA6ABQCQCABLQBSQQFGBEBBDiEAIAEtABFBAXENAQsgAS0AUCEDIARCAoNQBEAgAyEADAELQQEhACADQQFxRQRAIAMhAAwBCyABKAL4AiACaiIDQQI6AAAgA0EFakEANgAAIANBAWogASgCIDYAACACQQlqIQILIAEgADoAJCABKAL4AiACakEAOgAACwvfAgEDfyMAQeAAayIAJAACQEGAgAQQViICRQ0AIAJBBGstAABBA3FFDQAgAkEAQYCABPwLAAsCQCACRQ0AIABBADYAXCAAQgA3AFQgAEIANwBMIABCADcARCAAQgA3ADwgAEIANwA0IABCADcCHCAAQgA3AiQgAEEANgIsIABCADcADyAAQQA6ABdBgANBCBBVIgFFDQAgAUIANwARIAFBAToAECABQgA3AwggAUKAwICAgIAINwMAIAFCADcAGSABQgA3AB8gASAAKQAzNwAnIAEgACkAOzcALyABIAApAEM3ADcgASAAKQBLNwA/IAEgACkAUzcARyABIAApAFg3AEwgASAAKAIoNgJkIAEgACkCIDcCXCABIAApAhg3AlQgAUHsAGpBAEH/AfwLACABIAI2AvgCIAEgAC8AFjsA8wIgASAAKQAONwDrAiABIAE2AmggAEHgAGokACABDwsACxUAAkAgAEUNACABRQ0AIAAgARBXCws4AQF/IAAEQCAAKALwAiIBBEAgACgC7AIgARBXCyAAKAL4AiIBBEAgAUGAgAQQVwsgAEGAAxBXCwuSAQEBfyAAIAE6ACYgAEECOgAkIABB7ABqIQRB/gEgAyADQf4BTxsiAwRAIAQgAiAD/AoAAAsgACADOgD0AiADIARqQQA6AABBACEDIAApA1ggACkDYIRCAYOnBH8gACgC+AIiAkEBOgAAIAJBBWogAToAACACQQFqIAAoAiA2AABBBgVBAAsgACgC+AJqQQA6AAALrAIBAn8CQAJAAkAgAC0AJCIBQQlNBEBBASABdEEbcQ0BIAFBAkYNAyABQQlGDQILIABBBToAJiAAQQI6ACQgAEEWOgD0AiAAQQA6AIIBIABBgIjAACkAADcAbCAAQYiIwAApAAA3AHQgAEGOiMAAKQAANwB6AkAgACkDWCAAKQNghKdBAXFFBEAgACgC+AIhAQwBCyAAKAL4AiIBQQE6AAAgAUEFakEFOgAAIAFBAWogACgCIDYAAEEGIQILIAEgAmpBADoAAA8LIABBAToAJA8LAn8gACkDWCAAKQNghEIIg1AEQCAAKAL4AiEBQQAMAQsgACgC+AIiAUEEOgAAIAFBBWpBADYAACABQQFqIAAoAiA2AABBCQshAiAAQQE6ACQgASACakEAOgAACwsHACAAKQMwCwcAIAApAygLBwAgAC0AJgsTACAAMQD0AiAAQewAaq1CIIaECwcAIAApAwgLBwAgACgCBAsHACAAKAIACwcAIAAtAEwLBwAgACkDGAsHACAAKAIgCwcAIAApA0ALBwAgACkDOAsHACAALQAkCwcAIAAoAkgL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DQEMAgsgBkEJRg0BCyADQQY6ACYgA0ECOgAkIANB64rAACkAADcAbCADQfOKwAApAAA3AHQgA0H7isAAKQAANwB8IANBgovAACkAADcAgwEMJwsgAEEBaiEAIAlBAWsiCQ0ACwsgAyAHQeQAbCAOQQpsQf4BcWogC2o2AkggIkUNAyA7QgBSBEAgBUEQakGBgARPDTQgAygCICEAIAMoAvgCIAVqQQo6AAAgAygC+AIgBWpBAWogADYAACADKAL4AiAFakEFakEENgAAIAVBCWohBQsgOkIAUgRAIAVBEGpBgYAETw00IAMoAiAhACADKAL4AiAFakELOgAAIAMoAvgCIAVqQQFqIABBBWo2AAAgAygC+AIgBWpBBWpBAzYAACAFQQlqIQULIEJCAFIEQCAFQRBqQYGABE8NNCADKAIgIQAgAygC+AIgBWpBDDoAACADKAL4AiAFakEBaiAAQQlqNgAAIAMoAvgCIAVqQQVqQQM2AAAgBUEJaiEFCyBBUA0DIA0NAyAFQRBqQYCABEsNMyADKAIgIQAgAygC+AIgBWpBDToAACADKAL4AiAFakEBaiAAQQ1qNgAAIAMoAvgCIAVqQQVqIAJBDWs2AAAgBUEJaiEFDAMLIANBDDoAJiADQQI6ACQgA0GKi8AAKQAANwBsIANBkovAACkAADcAdCADQZqLwAApAAA3AHwgA0Gii8AAKQAANwCEASADQaqLwAApAAA3AIwBIANBsYvAACgAADYAkwFBKyEIQZcBDDELIANBBjoAJiADQQI6ACQgA0HSi8AAKQAANwBsIANB2ovAACkAADcAdCADQd+LwAApAAA3AHkMCwsgBC0AAkHUAEcNBCAELQADQdAARw0EIAQtAARBL0cNBCADQRE6ACYgA0ECOgAkIANBhonAACkAADcAbCADQY6JwAApAAA3AHQgA0GWicAAKQAANwB8DAgLIAJBAmohACADLQAkQQJGDScgA0EGOgAkDCcLIANBDDoAJiADQQI6ACQgA0HPisAAKQAANwBsIANB14rAACkAADcAdCADQd+KwAApAAA3AHwgA0HnisAAKAAANgCEAQwcCyADKAIAIAhLDS0gA0EGOgAmIANBAjoAJCADQbuKwAApAAA3AGwgA0HDisAAKQAANwB0IANBy4rAACgAADYAfAwdCyAIRQ0FIAhBAWsgCk8N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KQAANwBsIANBwojAACkAADcAdCADQcqIwAApAAA3AHwMBQsgEyANayITIAtqIRUgCSEHIAYhAAJAA0AgACAKTw0pIAAgBGotAAAtAICGQARAIABBAWohACAHQQFrIgdFDQIMAQsLIANBBjoAJiADQQI6ACQgA0HSiMAAKQAANwBsIANB2ojAACkAADcAdCADQd+IwAApAAA3AHkMBwsgDiAQQQlqRw0CAkAgDiALa0EIRw0AIA0pAAAiLkLIqNGC9cWMlzBRDQIgLkLIqNGC9aWMlzFSDQAgD0UNBCADQRE6ACYgA0ECOgAkIANB54jAACkAADcAbCADQe+IwAApAAA3AHQgA0H3iMAAKQAANwB8IANB/ojAACkAADcAgwEMHgsLIANBBjoAJiADQQI6ACQgA0GeicAAKQAANwBsIANBponAACkAADcAdEEQIQhB/AAMKgsgDw0BIANBEToAJiADQQI6ACQgA0GGicAAKQAANwBsIANBjonAACkAADcAdCADQZaJwAApAAA3AHwMAgsgA0EGOgAmIANBAjoAJCADQa6JwAApAAA3AGwgA0G2icAAKQAANwB0IANBu4nAACkAADcAeQwDCwJAICNFDQAgQEIAUgRAIAVBEGpBgYAETw0qIAMoAiAhACADKAL4AiAFakEIOgAAIAMoAvgCIAVqQQFqIAA2AAAgAygC+AIgBWpBBWogAjYAACAFQQlqIQULID9CAFIEQCAFQRBqQYGABE8NKiADKAIgIQAgAygC+AIgBWpBCToAACADKAL4AiAFakEBaiAAIAZqNgAAIAMoAvgCIAVqQQVqIAk2AAAgBUEJaiEFCyA7QgBSBEAgBUEQakGBgARPDSogAygCICEAIAMoAvgCIAVqQQo6AAAgAygC+AIgBWpBAWogACALajYAACADKAL4AiAFakEFaiATNgAAIAVBCWohBQsgOlANACAFQRBqQYCABEsNKSADKAIgIQAgAygC+AIgBWpBCzoAACADKAL4AiAFakEBaiAAIBVBAWpqNgAAIAMoAvgCIAVqQQVqQQM2AAAgBUEJaiEFCyAOQQJqIQAgAy0AJCECIAMtAExBCkYEQCACQQJGDSEgA0EFOgAkDCELIAJBAkYNICADQQY6ACQMIAtBGCEIQYQBDCYLIAMoAgAgCEsNJiADQQY6ACYgA0ECOgAkIANBpYjA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EFkgASAAIAJqIgBBAXI2AgQgACABaiAANgIAIAFB3JvAACgCAEcNAUHUm8AAIAA2AgAPCyACIANBfnE2AgQgASAAQQFyNgIEIAAgAWogADYCAAsgAEGAAkkNBCABIAAQW0H0m8AAQfSbwAAoAgBBAWsiADYCACAADQZBvJnAACgCACIADQJB/x8MAwtB4JvAACABNgIAQdibwABB2JvAACgCACAAaiIANgIAIAEgAEEBcjYCBEHcm8AAKAIAIAFGBEBB1JvAAEEANgIAQdybwABBADYCAAsgAEHsm8AAKAIAIgJNDQVB4JvAACgCACIARQ0FQdibwAAoAgAiA0EpSQ0EQbSZwAAhAQNAIAAgASgCACIETwRAIAAgBCABKAIEakkNBgsgASgCCCEBDAALAAtB3JvAACABNgIAQdSbwABB1JvAACgCACAAaiIANgIAIAEgAEEBcjYCBCAAIAFqIAA2AgAPC0EAIQEDQCABQQFqIQEgACgCCCIADQALQf8fIAEgAUH/H00bCzYCAA8LAkBBzJvAACgCACICQQEgAEEDdnQiA3FFBEBBzJvAACACIANyNgIAIABB+AFxQcSZwABqIgAhAgwBCyAAQfgBcSIAQcSZwABqIQIgAEHMmcAAaigCACEACyACIAE2AgggACABNgIMIAEgAjYCDCABIAA2AggPC0H0m8AAQbyZwAAoAgAiAAR/QQAhAQNAIAFBAWohASAAKAIIIgANAAtB/x8gASABQf8fTRsFQf8fCzYCACACIANPDQBB7JvAAEF/NgIACwuCAwEEfyAAKAIMIQICQAJAAkAgAUGAAk8EQCAAKAIYIQMCQAJAIAAgAkYEQCAAQRRBECAAKAIUIgIbaigCACIBDQFBACECDAILIAAoAggiASACNgIMIAIgATYCCAwBCyAAQRRqIABBEGogAhshBANAIAQhBSABIgJBFGogAkEQaiACKAIUIgEbIQQgAkEUQRAgARtqKAIAIgENAAsgBUEANgIACyADRQ0CAkAgACgCHEECdEG0mMAAaiIBKAIAIABHBEAgAygCECAARg0BIAMgAjYCFCACDQMMBAsgASACNgIAIAJFDQQMAgsgAyACNgIQIAINAQwCCyAAKAIIIgAgAkcEQCAAIAI2AgwgAiAANgIIDwtBzJvAAEHMm8AAKAIAQX4gAUEDdndxNgIADwsgAiADNgIYIAAoAhAiAQRAIAIgATYCECABIAI2AhgLIAAoAhQiAEUNACACIAA2AhQgACACNgIYDwsPC0HQm8AAQdCbwAAoAgBBfiAAKAIcd3E2AgALjgQBAn8gACABaiECAkACQAJAIAAoAgQiA0EBcQ0AIANBAnFFDQEgACgCACIDIAFqIQEgACADayIAQdybwAAoAgBGBEAgAigCBEEDcUEDRw0BQdSbwAAgATYCACACIAIoAgRBfnE2AgQgACABQQFyNgIEIAIgATYCAA8LIAAgAxBZCwJAAkAgAigCBCIDQQJxRQRAIAJB4JvAACgCAEYNAiACQdybwAAoAgBGDQQgAiADQXhxIgIQWSAAIAEgAmoiAUEBcjYCBCAAIAFqIAE2AgAgAEHcm8AAKAIARw0BQdSbwAAgATYCAA8LIAIgA0F+cTYCBCAAIAFBAXI2AgQgACABaiABNgIACyABQYACTwRAIAAgARBbDwsCQEHMm8AAKAIAIgJBASABQQN2dCIDcUUEQEHMm8AAIAIgA3I2AgAgAUH4AXFBxJnAAGoiASECDAELIAFB+AFxIgFBxJnAAGohAiABQcyZwABqKAIAIQELIAIgADYCCCABIAA2AgwgACACNgIMIAAgATYCCA8LQeCbwAAgADYCAEHYm8AAQdibwAAoAgAgAWoiATYCACAAIAFBAXI2AgQgAEHcm8AAKAIARw0AQdSbwABBADYCAEHcm8AAQQA2AgALDwtB3JvAACAANgIAQdSbwABB1JvAACgCACABaiIBNgIAIAAgAUEBcjYCBCAAIAFqIAE2AgALwwIBBH8gAEIANwIQIAACf0EAIAFBCHYiA0UNABpBHyABQYCAgAhPDQAaIAFBJiADZyIDa3ZBAXEgA0EBdHJBPnMLIgI2AhwgAkECdEG0mMAAaiEEQQEgAnQiA0HQm8AAKAIAcUUEQCAEIAA2AgAgACAENgIYIAAgADYCDCAAIAA2AghB0JvAAEHQm8AAKAIAIANyNgIADwsCQAJAIAEgBCgCACIDKAIEQXhxRgRAIAMhAgwBCyABQRkgAkEBdmtBACACQR9HG3QhBQNAIAMgBUEddkEEcWoiBCgCECICRQ0CIAVBAXQhBSACIQMgAigCBEF4cSABRw0ACwsgAigCCCIBIAA2AgwgAiAANgIIIABBADYCGCAAIAI2AgwgACABNgIIDwsgBEEQaiAANgIAIAAgAzYCGCAAIAA2AgwgACAANgIICwvuFQcAQaGAwAALXgEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAQYmCwAALAQEAQaCCwAAL4AEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBiYTAAAsBAQBBoITAAAvgAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEGhhsAAC14BAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAEGAiMAAC7QQVW5leHBlY3RlZCBlbmQgb2YgZGF0YVVuZXhwZWN0ZWQgZGF0YVJlcXVlc3QgbGluZSB0b28gbG9uZ0ludmFsaWQgbWV0aG9kIGNoYXJhY3RlckludmFsaWQgVVJMIGNoYXJhY3RlclBSSSBpcyBvbmx5IHZhbGlkIHdpdGggSFRUUC8yLjBVbnN1cHBvcnRlZCBIVFRQIHZlcnNpb25JbnZhbGlkIHByb3RvY29sSW52YWxpZCBwcm90b2NvbCBuYW1lRXhwZWN0ZWQgLyBhZnRlciB0aGUgcHJvdG9jb2wgbmFtZUV4cGVjdGVkIHNwYWNlIGFmdGVyIFVSTEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZFJlcXVlc3QgbGluZSB0b28gc2hvcnRFeHBlY3RlZCBDUkxGU3RhdHVzIGxpbmUgdG9vIGxvbmdJbnZhbGlkIEhUVFAgcmVzcG9uc2Ugc3RhdHVzSW52YWxpZCBzdGF0dXMgcmVhc29uIGNoYXJhY3RlckV4cGVjdGVkIGEgc3BhY2UgYWZ0ZXIgSFRUUCByZXNwb25zZSBzdGF0dXNFeHBlY3RlZCBzcGFjZSBhZnRlciBwcm90b2NvbFN0YXR1cyBsaW5lIHRvbyBzaG9ydE1hbGZvcm1lZCBIVFRQLzIuMCBwcmVmYWNlSGVhZGVyIGxpbmUgdG9vIGxvbmdVbmV4cGVjdGVkIENvbnRlbnQtTGVuZ3RoIGhlYWRlciBmb3IgYSByZXNwb25zZSB3aXRob3V0IGJvZHlFeHBlY3RlZCBDb250ZW50LUxlbmd0aCBoZWFkZXIgdmFsdWVJbnZhbGlkIENvbnRlbnQtTGVuZ3RoIGhlYWRlckludmFsaWQgZHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoIGhlYWRlclVuZXhwZWN0ZWQgQ29udGVudC1MZW5ndGggaGVhZGVyIHdoZW4gVHJhbnNmZXItRW5jb2RpbmcgaGVhZGVyIGlzIHByZXNlbnRVbmV4cGVjdGVkIFRyYW5zZmVyLUVuY29kaW5nIGhlYWRlciBmb3IgYSByZXNwb25zZSB3aXRob3V0IGJvZHlFeHBlY3RlZCBUcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgdmFsdWVUaGUgdmFsdWUgImNodW5rZWQiIGluIHRoZSBUcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgbXVzdCBiZSB0aGUgbGFzdCBwcm92aWRlZCBhbmQgY2FuIGJlIHByb3ZpZGVkIG9ubHkgb25jZVRoZSB2YWx1ZSAiY2h1bmtlZCIgaW4gdGhlIFRyYW5zZmVyLUVuY29kaW5nIGhlYWRlciBtdXN0IGJlIHRoZSBsYXN0IHByb3ZpZGVkVW5leHBlY3RlZCBUcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgd2hlbiBDb250ZW50LUxlbmd0aCBoZWFkZXIgaXMgcHJlc2VudEV4cGVjdGVkIENvbm5lY3Rpb24gaGVhZGVyIHZhbHVlSW52YWxpZCBDb25uZWN0aW9uIGhlYWRlciB2YWx1ZUV4cGVjdGVkIFRyYWlsZXIgaGVhZGVyIHZhbHVlRXhwZWN0ZWQgVXBncmFkZSBoZWFkZXIgdmFsdWVJbnZhbGlkIFVwZ3JhZGUgaGVhZGVyIHZhbHVlSW52YWxpZCBoZWFkZXIgZmllbGQgbmFtZSBjaGFyYWN0ZXJJbnZhbGlkIGhlYWRlciBmaWVsZCB2YWx1ZSBjaGFyYWN0ZXJNaXNzaW5nIENvbm5lY3Rpb24gaGVhZGVyIHNldCB0byAidXBncmFkZSIgd2hlbiB1c2luZyB0aGUgVXBncmFkZSBoZWFkZXJUcmFpbGVycyBhcmUgbm90IGFsbG93ZWQgd2hlbiBub3QgdXNpbmcgY2h1bmtlZCB0cmFuc2ZlciBlbmNvZGluZ1VuZXhwZWN0ZWQgY29udGVudCBmb3IgdGhlIHJlcXVlc3QgKEdFVCBvciBIRUFEKVRyYW5zZmVyLUVuY29kaW5nIGxhc3QgaGVhZGVyIHZhbHVlIG11c3QgYmUgImNodW5rZWQiIGlmIHRoZSBoZWFkZXIgaXMgcHJlc2VudENodW5rIGhlYWRlciB0b28gbG9uZ0ludmFsaWQgY2h1bmsgbGVuZ3RoIGNoYXJhY3RlckludmFsaWQgY2h1bmsgbGVuZ3RoIHNpemVFeHBlY3RlZCBjaHVuayBleHRlbnNpb24gbmFtZUludmFsaWQgY2h1bmsgZXh0ZW5zaW9uIG5hbWUgY2hhcmFjdGVyRXhwZWN0ZWQgY2xvc2luZyBxdW90ZSBmb3IgY2h1bmsgZXh0ZW5zaW9uIHZhbHVlSW52YWxpZCBjaHVuayBleHRlbnNpb24gcXVvdGVkIHZhbHVlIGNoYXJhY3RlckV4cGVjdGVkIGNodW5rIGV4dGVuc2lvbiB2YWx1ZUludmFsaWQgY2h1bmsgZXh0ZW5zaW9uIHZhbHVlIGNoYXJhY3RlckludmFsaWQgY2h1bmsgZXh0ZW5zaW9uIGNoYXJhY3RlciBhZnRlciB2YWx1ZUV4cGVjdGVkIENSTEYgYWZ0ZXIgY2h1bmsgZGF0YVRyYWlsZXIgbGluZSB0b28gbG9uZ0ludmFsaWQgdHJhaWxlciBmaWVsZCBuYW1lIGNoYXJhY3RlckludmFsaWQgdHJhaWxlciBmaWVsZCB2YWx1ZSBjaGFyYWN0ZXJJbnZhbGlkIHN0YXRl', + 'base64' + ) +) - if (request.method === 'CONNECT') { - assert(client[kRunning] === 1) - this.upgrade = true - return 2 - } +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() - if (upgrade) { - assert(client[kRunning] === 1) - this.upgrade = true - return 2 - } +function log (logger, raw) { + const len = Number(BigInt.asUintN(32, raw)) + const ptr = Number(raw >> 32n) - assert((this.headers.length & 1) === 0) - this.headers = [] - this.headersSize = 0 + logger(textDecoder.decode(new Uint8Array(this.memory.buffer, ptr, len))) +} - if (this.shouldKeepAlive && client[kPipelining]) { - const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null +function alloc (len) { + return this.alloc(len) >>> 0 +} - if (keepAliveTimeout != null) { - const timeout = Math.min( - keepAliveTimeout - client[kKeepAliveTimeoutThreshold], - client[kKeepAliveMaxTimeout] - ) - if (timeout <= 0) { - socket[kReset] = true - } else { - client[kKeepAliveTimeoutValue] = timeout - } - } else { - client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] - } - } else { - // Stop more requests from being dispatched. - socket[kReset] = true - } +function dealloc (ptr, len) { + return this.dealloc(ptr, len) +} - const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false +function create () { + return this.create() >>> 0 +} - if (request.aborted) { - return -1 - } +function destroy (parser) { + this.destroy(parser) +} - if (request.method === 'HEAD') { - return 1 - } +function parse (parser, data, limit) { + return this.parse(parser, data, limit) >>> 0 +} - if (statusCode < 200) { - return 1 - } +function fail (parser, code, description) { + const len = description.length + const ptr = this.alloc(len) + const buffer = new Uint8Array(this.memory.buffer, ptr, len) + textEncoder.encodeInto(description, buffer) - if (socket[kBlocking]) { - socket[kBlocking] = false - client[kResume]() - } + this.fail(parser, code, ptr, len) + this.dealloc(ptr, len) +} - return pause ? constants.ERROR.PAUSED : 0 - } +function hasDebug () { + return this.milo_has_debug() !== 0 +} - onBody (buf) { - const { client, socket, statusCode, maxResponseSize } = this +const Errors = Object.freeze({ + NONE: 0, + USER: 1, + CALLBACK_ERROR: 2, + UNEXPECTED_STATE: 3, + UNEXPECTED_DATA: 4, + UNEXPECTED_EOF: 5, + UNEXPECTED_CHARACTER: 6, + UNEXPECTED_CONTENT_LENGTH: 7, + UNEXPECTED_TRANSFER_ENCODING: 8, + UNEXPECTED_CONTENT: 9, + UNEXPECTED_TRAILERS: 10, + INVALID_VERSION: 11, + INVALID_STATUS: 12, + INVALID_CONTENT_LENGTH: 13, + INVALID_TRANSFER_ENCODING: 14, + INVALID_CHUNK_SIZE: 15, + MISSING_CONNECTION_UPGRADE: 16, + UNSUPPORTED_HTTP_VERSION: 17, + 0: 'NONE', + 1: 'USER', + 2: 'CALLBACK_ERROR', + 3: 'UNEXPECTED_STATE', + 4: 'UNEXPECTED_DATA', + 5: 'UNEXPECTED_EOF', + 6: 'UNEXPECTED_CHARACTER', + 7: 'UNEXPECTED_CONTENT_LENGTH', + 8: 'UNEXPECTED_TRANSFER_ENCODING', + 9: 'UNEXPECTED_CONTENT', + 10: 'UNEXPECTED_TRAILERS', + 11: 'INVALID_VERSION', + 12: 'INVALID_STATUS', + 13: 'INVALID_CONTENT_LENGTH', + 14: 'INVALID_TRANSFER_ENCODING', + 15: 'INVALID_CHUNK_SIZE', + 16: 'MISSING_CONNECTION_UPGRADE', + 17: 'UNSUPPORTED_HTTP_VERSION' +}) - if (socket.destroyed) { - return -1 - } +const Methods = Object.freeze({ + OTHER: 0, + GET: 1, + HEAD: 2, + POST: 3, + PUT: 4, + DELETE: 5, + CONNECT: 6, + OPTIONS: 7, + TRACE: 8, + PATCH: 9, + PRI: 10, + 0: 'OTHER', + 1: 'GET', + 2: 'HEAD', + 3: 'POST', + 4: 'PUT', + 5: 'DELETE', + 6: 'CONNECT', + 7: 'OPTIONS', + 8: 'TRACE', + 9: 'PATCH', + 10: 'PRI' +}) - const request = client[kQueue][client[kRunningIdx]] - assert(request) +const Callbacks = Object.freeze({ + ON_ERROR: 0, + ON_FINISH: 1, + ON_MESSAGE_START: 2, + ON_MESSAGE_COMPLETE: 3, + ON_REQUEST: 4, + ON_RESPONSE: 5, + ON_RESET: 6, + ON_METHOD: 7, + ON_URL: 8, + ON_PROTOCOL: 9, + ON_VERSION: 10, + ON_STATUS: 11, + ON_REASON: 12, + ON_HEADER_NAME: 13, + ON_HEADER_VALUE: 14, + ON_HEADERS: 15, + ON_CONNECT: 16, + ON_UPGRADE: 17, + ON_CHUNK_LENGTH: 18, + ON_CHUNK_EXTENSION_NAME: 19, + ON_CHUNK_EXTENSION_VALUE: 20, + ON_CHUNK: 21, + ON_BODY: 22, + ON_DATA: 23, + ON_TRAILER_NAME: 24, + ON_TRAILER_VALUE: 25, + ON_TRAILERS: 26, + ON_STATE_CHANGE: 27, + 0: 'ON_ERROR', + 1: 'ON_FINISH', + 2: 'ON_MESSAGE_START', + 3: 'ON_MESSAGE_COMPLETE', + 4: 'ON_REQUEST', + 5: 'ON_RESPONSE', + 6: 'ON_RESET', + 7: 'ON_METHOD', + 8: 'ON_URL', + 9: 'ON_PROTOCOL', + 10: 'ON_VERSION', + 11: 'ON_STATUS', + 12: 'ON_REASON', + 13: 'ON_HEADER_NAME', + 14: 'ON_HEADER_VALUE', + 15: 'ON_HEADERS', + 16: 'ON_CONNECT', + 17: 'ON_UPGRADE', + 18: 'ON_CHUNK_LENGTH', + 19: 'ON_CHUNK_EXTENSION_NAME', + 20: 'ON_CHUNK_EXTENSION_VALUE', + 21: 'ON_CHUNK', + 22: 'ON_BODY', + 23: 'ON_DATA', + 24: 'ON_TRAILER_NAME', + 25: 'ON_TRAILER_VALUE', + 26: 'ON_TRAILERS', + 27: 'ON_STATE_CHANGE' +}) - assert(this.timeoutType === TIMEOUT_BODY) - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } +const CallbackActives = Object.freeze({ + NONE: 0n, + ON_ERROR: 1n, + ON_FINISH: 2n, + ON_MESSAGE_START: 4n, + ON_MESSAGE_COMPLETE: 8n, + ON_REQUEST: 16n, + ON_RESPONSE: 32n, + ON_RESET: 64n, + ON_METHOD: 128n, + ON_URL: 256n, + ON_PROTOCOL: 512n, + ON_VERSION: 1024n, + ON_STATUS: 2048n, + ON_REASON: 4096n, + ON_HEADER_NAME: 8192n, + ON_HEADER_VALUE: 16384n, + ON_HEADERS: 32768n, + ON_CONNECT: 65536n, + ON_UPGRADE: 131072n, + ON_CHUNK_LENGTH: 262144n, + ON_CHUNK_EXTENSION_NAME: 524288n, + ON_CHUNK_EXTENSION_VALUE: 1048576n, + ON_CHUNK: 2097152n, + ON_BODY: 4194304n, + ON_DATA: 8388608n, + ON_TRAILER_NAME: 16777216n, + ON_TRAILER_VALUE: 33554432n, + ON_TRAILERS: 67108864n, + ON_STATE_CHANGE: 134217728n, + ALL: 268435455n, + 0n: 'NONE', + 1n: 'ON_ERROR', + 2n: 'ON_FINISH', + 4n: 'ON_MESSAGE_START', + 8n: 'ON_MESSAGE_COMPLETE', + 16n: 'ON_REQUEST', + 32n: 'ON_RESPONSE', + 64n: 'ON_RESET', + 128n: 'ON_METHOD', + 256n: 'ON_URL', + 512n: 'ON_PROTOCOL', + 1024n: 'ON_VERSION', + 2048n: 'ON_STATUS', + 4096n: 'ON_REASON', + 8192n: 'ON_HEADER_NAME', + 16384n: 'ON_HEADER_VALUE', + 32768n: 'ON_HEADERS', + 65536n: 'ON_CONNECT', + 131072n: 'ON_UPGRADE', + 262144n: 'ON_CHUNK_LENGTH', + 524288n: 'ON_CHUNK_EXTENSION_NAME', + 1048576n: 'ON_CHUNK_EXTENSION_VALUE', + 2097152n: 'ON_CHUNK', + 4194304n: 'ON_BODY', + 8388608n: 'ON_DATA', + 16777216n: 'ON_TRAILER_NAME', + 33554432n: 'ON_TRAILER_VALUE', + 67108864n: 'ON_TRAILERS', + 134217728n: 'ON_STATE_CHANGE', + 268435455n: 'ALL' +}) - assert(statusCode >= 200) +const Events = Object.freeze({ + END: 0, + ERROR: 1, + FINISH: 2, + MESSAGE_START: 3, + MESSAGE_COMPLETE: 4, + REQUEST: 5, + RESPONSE: 6, + RESET: 7, + METHOD: 8, + URL: 9, + PROTOCOL: 10, + VERSION: 11, + STATUS: 12, + REASON: 13, + HEADER_NAME: 14, + HEADER_VALUE: 15, + HEADERS: 16, + CONNECT: 17, + UPGRADE: 18, + CHUNK_LENGTH: 19, + CHUNK_EXTENSION_NAME: 20, + CHUNK_EXTENSION_VALUE: 21, + CHUNK: 22, + BODY: 23, + DATA: 24, + TRAILER_NAME: 25, + TRAILER_VALUE: 26, + TRAILERS: 27, + STATE_CHANGE: 28, + 0: 'END', + 1: 'ERROR', + 2: 'FINISH', + 3: 'MESSAGE_START', + 4: 'MESSAGE_COMPLETE', + 5: 'REQUEST', + 6: 'RESPONSE', + 7: 'RESET', + 8: 'METHOD', + 9: 'URL', + 10: 'PROTOCOL', + 11: 'VERSION', + 12: 'STATUS', + 13: 'REASON', + 14: 'HEADER_NAME', + 15: 'HEADER_VALUE', + 16: 'HEADERS', + 17: 'CONNECT', + 18: 'UPGRADE', + 19: 'CHUNK_LENGTH', + 20: 'CHUNK_EXTENSION_NAME', + 21: 'CHUNK_EXTENSION_VALUE', + 22: 'CHUNK', + 23: 'BODY', + 24: 'DATA', + 25: 'TRAILER_NAME', + 26: 'TRAILER_VALUE', + 27: 'TRAILERS', + 28: 'STATE_CHANGE' +}) - if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { - util.destroy(socket, new ResponseExceededMaxSizeError()) - return -1 - } +const EventActives = Object.freeze({ + NONE: 0n, + ON_ERROR: 1n, + ON_FINISH: 2n, + ON_MESSAGE_START: 4n, + ON_MESSAGE_COMPLETE: 8n, + ON_REQUEST: 16n, + ON_RESPONSE: 32n, + ON_RESET: 64n, + ON_METHOD: 128n, + ON_URL: 256n, + ON_PROTOCOL: 512n, + ON_VERSION: 1024n, + ON_STATUS: 2048n, + ON_REASON: 4096n, + ON_HEADER_NAME: 8192n, + ON_HEADER_VALUE: 16384n, + ON_HEADERS: 32768n, + ON_CONNECT: 65536n, + ON_UPGRADE: 131072n, + ON_CHUNK_LENGTH: 262144n, + ON_CHUNK_EXTENSION_NAME: 524288n, + ON_CHUNK_EXTENSION_VALUE: 1048576n, + ON_CHUNK: 2097152n, + ON_BODY: 4194304n, + ON_DATA: 8388608n, + ON_TRAILER_NAME: 16777216n, + ON_TRAILER_VALUE: 33554432n, + ON_TRAILERS: 67108864n, + ON_STATE_CHANGE: 134217728n, + ALL: 268435455n, + 0n: 'NONE', + 1n: 'ON_ERROR', + 2n: 'ON_FINISH', + 4n: 'ON_MESSAGE_START', + 8n: 'ON_MESSAGE_COMPLETE', + 16n: 'ON_REQUEST', + 32n: 'ON_RESPONSE', + 64n: 'ON_RESET', + 128n: 'ON_METHOD', + 256n: 'ON_URL', + 512n: 'ON_PROTOCOL', + 1024n: 'ON_VERSION', + 2048n: 'ON_STATUS', + 4096n: 'ON_REASON', + 8192n: 'ON_HEADER_NAME', + 16384n: 'ON_HEADER_VALUE', + 32768n: 'ON_HEADERS', + 65536n: 'ON_CONNECT', + 131072n: 'ON_UPGRADE', + 262144n: 'ON_CHUNK_LENGTH', + 524288n: 'ON_CHUNK_EXTENSION_NAME', + 1048576n: 'ON_CHUNK_EXTENSION_VALUE', + 2097152n: 'ON_CHUNK', + 4194304n: 'ON_BODY', + 8388608n: 'ON_DATA', + 16777216n: 'ON_TRAILER_NAME', + 33554432n: 'ON_TRAILER_VALUE', + 67108864n: 'ON_TRAILERS', + 134217728n: 'ON_STATE_CHANGE', + 268435455n: 'ALL' +}) - this.bytesRead += buf.length +const States = Object.freeze({ + START: 0, + FINISH: 1, + ERROR: 2, + REQUEST_LINE: 3, + STATUS_LINE: 4, + HTTP2_PREFACE: 5, + HEADER: 6, + BODY_DECISION: 7, + BODY_VIA_CONTENT_LENGTH: 8, + BODY_WITH_NO_LENGTH: 9, + CHUNK_HEADER: 10, + CHUNK_EXTENSIONS: 11, + CHUNK_DATA: 12, + TRAILER: 13, + TUNNEL: 14, + 0: 'START', + 1: 'FINISH', + 2: 'ERROR', + 3: 'REQUEST_LINE', + 4: 'STATUS_LINE', + 5: 'HTTP2_PREFACE', + 6: 'HEADER', + 7: 'BODY_DECISION', + 8: 'BODY_VIA_CONTENT_LENGTH', + 9: 'BODY_WITH_NO_LENGTH', + 10: 'CHUNK_HEADER', + 11: 'CHUNK_EXTENSIONS', + 12: 'CHUNK_DATA', + 13: 'TRAILER', + 14: 'TUNNEL' +}) - if (request.onData(buf) === false) { - return constants.ERROR.PAUSED - } - } +const ParserFields = Object.freeze({ + MAX_START_LINE_LENGTH: 0, + MAX_HEADER_LENGTH: 4, + MAX_BODY_PAYLOAD: 8, + AUTODETECT: 16, + IS_REQUEST: 17, + SUSPEND_AFTER_HEADERS: 18, + MANAGE_UNCONSUMED: 19, + CONTINUE_WITHOUT_DATA: 20, + IS_CONNECT: 21, + SKIP_BODY: 22, + DEBUG: 23, + PARSED: 24, + POSITION: 32, + STATE: 36, + PAUSED: 37, + ERROR_CODE: 38, + CONTENT_LENGTH: 40, + CHUNK_SIZE: 48, + REMAINING_CONTENT_LENGTH: 56, + REMAINING_CHUNK_SIZE: 64, + STATUS: 72, + METHOD: 76, + HAS_CONTENT_LENGTH: 77, + HAS_TRANSFER_ENCODING: 78, + HAS_CHUNKED_TRANSFER_ENCODING: 79, + HAS_CONNECTION_CLOSE: 80, + HAS_CONNECTION_UPGRADE: 81, + HAS_UPGRADE: 82, + HAS_TRAILERS: 83, + ACTIVE_CALLBACKS: 88, + ACTIVE_EVENTS: 96, + PTR: 104, + ERROR_DESCRIPTION: 108, + UNCONSUMED: 364, + UNCONSUMED_LEN: 368, + ERROR_DESCRIPTION_LEN: 372, + EVENTS: 376, + 0: 'MAX_START_LINE_LENGTH', + 4: 'MAX_HEADER_LENGTH', + 8: 'MAX_BODY_PAYLOAD', + 16: 'AUTODETECT', + 17: 'IS_REQUEST', + 18: 'SUSPEND_AFTER_HEADERS', + 19: 'MANAGE_UNCONSUMED', + 20: 'CONTINUE_WITHOUT_DATA', + 21: 'IS_CONNECT', + 22: 'SKIP_BODY', + 23: 'DEBUG', + 24: 'PARSED', + 32: 'POSITION', + 36: 'STATE', + 37: 'PAUSED', + 38: 'ERROR_CODE', + 40: 'CONTENT_LENGTH', + 48: 'CHUNK_SIZE', + 56: 'REMAINING_CONTENT_LENGTH', + 64: 'REMAINING_CHUNK_SIZE', + 72: 'STATUS', + 76: 'METHOD', + 77: 'HAS_CONTENT_LENGTH', + 78: 'HAS_TRANSFER_ENCODING', + 79: 'HAS_CHUNKED_TRANSFER_ENCODING', + 80: 'HAS_CONNECTION_CLOSE', + 81: 'HAS_CONNECTION_UPGRADE', + 82: 'HAS_UPGRADE', + 83: 'HAS_TRAILERS', + 88: 'ACTIVE_CALLBACKS', + 96: 'ACTIVE_EVENTS', + 104: 'PTR', + 108: 'ERROR_DESCRIPTION', + 364: 'UNCONSUMED', + 368: 'UNCONSUMED_LEN', + 372: 'ERROR_DESCRIPTION_LEN', + 376: 'EVENTS' +}) - onMessageComplete () { - const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this +function isAutodetect (parser) { + return this.is_autodetect(parser) !== 0 +} - if (socket.destroyed && (!statusCode || shouldKeepAlive)) { - return -1 - } +function isRequest (parser) { + return this.is_request(parser) !== 0 +} - if (upgrade) { - return - } +function isPaused (parser) { + return this.is_paused(parser) !== 0 +} - assert(statusCode >= 100) - assert((this.headers.length & 1) === 0) +function shouldManageUnconsumed (parser) { + return this.should_manage_unconsumed(parser) !== 0 +} - const request = client[kQueue][client[kRunningIdx]] - assert(request) +function shouldSuspendAfterHeaders (parser) { + return this.should_suspend_after_headers(parser) !== 0 +} - this.statusCode = null - this.statusText = '' - this.bytesRead = 0 - this.contentLength = '' - this.keepAlive = '' - this.connection = '' +function getMaxStartLineLength (parser) { + return this.get_max_start_line_length(parser) >>> 0 +} - this.headers = [] - this.headersSize = 0 +function getMaxHeaderLength (parser) { + return this.get_max_header_length(parser) >>> 0 +} - if (statusCode < 200) { - return - } +function getMaxBodyPayload (parser) { + return BigInt.asUintN(64, this.get_max_body_payload(parser)) +} - /* istanbul ignore next: should be handled by llhttp? */ - if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { - util.destroy(socket, new ResponseContentLengthMismatchError()) - return -1 - } +function shouldContinueWithoutData (parser) { + return this.should_continue_without_data(parser) !== 0 +} - request.onComplete(headers) +function isConnect (parser) { + return this.is_connect(parser) !== 0 +} - client[kQueue][client[kRunningIdx]++] = null +function isDebug (parser) { + return this.is_debug(parser) !== 0 +} - if (socket[kWriting]) { - assert(client[kRunning] === 0) - // Response completed before request. - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (!shouldKeepAlive) { - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (socket[kReset] && client[kRunning] === 0) { - // Destroy socket once all requests have completed. - // The request at the tail of the pipeline is the one - // that requested reset and no further requests should - // have been queued since then. - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (client[kPipelining] == null || client[kPipelining] === 1) { - // We must wait a full event loop cycle to reuse this socket to make sure - // that non-spec compliant servers are not closing the connection even if they - // said they won't. - setImmediate(() => client[kResume]()) - } else { - client[kResume]() - } - } +function shouldSkipBody (parser) { + return this.should_skip_body(parser) !== 0 } -function onParserTimeout (parser) { - const { socket, timeoutType, client, paused } = parser.deref() +function getState (parser) { + return this.get_state(parser) >>> 0 +} - /* istanbul ignore else */ - if (timeoutType === TIMEOUT_HEADERS) { - if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { - assert(!paused, 'cannot be paused while waiting for headers') - util.destroy(socket, new HeadersTimeoutError()) - } - } else if (timeoutType === TIMEOUT_BODY) { - if (!paused) { - util.destroy(socket, new BodyTimeoutError()) - } - } else if (timeoutType === TIMEOUT_KEEP_ALIVE) { - assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) - util.destroy(socket, new InformationalError('socket idle timeout')) - } +function getPosition (parser) { + return this.get_position(parser) >>> 0 } -async function connectH1 (client, socket) { - client[kSocket] = socket +function getParsed (parser) { + return BigInt.asUintN(64, this.get_parsed(parser)) +} - if (!llhttpInstance) { - llhttpInstance = await llhttpPromise - llhttpPromise = null - } +function getErrorCode (parser) { + return this.get_error_code(parser) >>> 0 +} - socket[kNoRef] = false - socket[kWriting] = false - socket[kReset] = false - socket[kBlocking] = false - socket[kParser] = new Parser(client, socket, llhttpInstance) +function getMethod (parser) { + return this.get_method(parser) >>> 0 +} - addListener(socket, 'error', function (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') +function getStatus (parser) { + return this.get_status(parser) >>> 0 +} - const parser = this[kParser] +function hasConnectionClose (parser) { + return this.has_connection_close(parser) !== 0 +} - // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded - // to the user. - if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so for as a valid response. - parser.onMessageComplete() - return - } +function hasConnectionUpgrade (parser) { + return this.has_connection_upgrade(parser) !== 0 +} - this[kError] = err +function getContentLength (parser) { + return BigInt.asUintN(64, this.get_content_length(parser)) +} - this[kClient][kOnError](err) - }) - addListener(socket, 'readable', function () { - const parser = this[kParser] +function getChunkSize (parser) { + return BigInt.asUintN(64, this.get_chunk_size(parser)) +} - if (parser) { - parser.readMore() - } - }) - addListener(socket, 'end', function () { - const parser = this[kParser] +function getRemainingContentLength (parser) { + return BigInt.asUintN(64, this.get_remaining_content_length(parser)) +} - if (parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete() - return - } +function getRemainingChunkSize (parser) { + return BigInt.asUintN(64, this.get_remaining_chunk_size(parser)) +} - util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) - }) - addListener(socket, 'close', function () { - const client = this[kClient] - const parser = this[kParser] +function hasContentLength (parser) { + return this.has_content_length(parser) !== 0 +} - if (parser) { - if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete() - } +function hasTransferEncoding (parser) { + return this.has_transfer_encoding(parser) !== 0 +} - this[kParser].destroy() - this[kParser] = null - } +function hasChunkedTransferEncoding (parser) { + return this.has_chunked_transfer_encoding(parser) !== 0 +} - const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) +function hasUpgrade (parser) { + return this.has_upgrade(parser) !== 0 +} - client[kSocket] = null - client[kHTTPContext] = null // TODO (fix): This is hacky... +function hasTrailers (parser) { + return this.has_trailers(parser) !== 0 +} - if (client.destroyed) { - assert(client[kPending] === 0) +function getErrorDescription (parser) { + const raw = this.get_error_description_raw(parser) + const len = Number(BigInt.asUintN(32, raw)) + const ptr = Number(raw >> 32n) + return textDecoder.decode(new Uint8Array(this.memory.buffer, ptr, len)) +} - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - util.errorRequest(client, request, err) - } - } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { - // Fail head of pipeline. - const request = client[kQueue][client[kRunningIdx]] - client[kQueue][client[kRunningIdx]++] = null +function setShouldAutodetect (parser, value) { + this.set_should_autodetect(parser, value) +} - util.errorRequest(client, request, err) - } +function setShouldContinueWithoutData (parser, value) { + this.set_should_continue_without_data(parser, value) +} - client[kPendingIdx] = client[kRunningIdx] +function setIsRequest (parser, value) { + this.set_is_request(parser, value) +} - assert(client[kRunning] === 0) +function setIsConnect (parser, value) { + this.set_is_connect(parser, value) +} - client.emit('disconnect', client[kUrl], [client], err) +function setDebug (parser, value) { + this.set_debug(parser, value) +} - client[kResume]() - }) +function setShouldManageUnconsumed (parser, value) { + this.set_should_manage_unconsumed(parser, value) +} - let closed = false - socket.on('close', () => { - closed = true - }) +function setShouldSuspendAfterHeaders (parser, value) { + this.set_should_suspend_after_headers(parser, value) +} - return { - version: 'h1', - defaultPipelining: 1, - write (...args) { - return writeH1(client, ...args) - }, - resume () { - resumeH1(client) - }, - destroy (err, callback) { - if (closed) { - queueMicrotask(callback) - } else { - socket.destroy(err).on('close', callback) - } - }, - get destroyed () { - return socket.destroyed - }, - busy (request) { - if (socket[kWriting] || socket[kReset] || socket[kBlocking]) { - return true - } +function setMaxStartLineLength (parser, value) { + this.set_max_start_line_length(parser, value) +} - if (request) { - if (client[kRunning] > 0 && !request.idempotent) { - // Non-idempotent request cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return true - } +function setMaxHeaderLength (parser, value) { + this.set_max_header_length(parser, value) +} - if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { - // Don't dispatch an upgrade until all preceding requests have completed. - // A misbehaving server might upgrade the connection before all pipelined - // request has completed. - return true - } +function setMaxBodyPayload (parser, value) { + this.set_max_body_payload(parser, value) +} - if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && - (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) { - // Request with stream or iterator body can error while other requests - // are inflight and indirectly error those as well. - // Ensure this doesn't happen by waiting for inflight - // to complete before dispatching. +function setShouldSkipBody (parser, value) { + this.set_should_skip_body(parser, value) +} - // Request with stream or iterator body cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return true - } - } +function setActiveCallbacks (parser, value) { + this.set_active_callbacks(parser, value) +} - return false - } - } +function setActiveEvents (parser, value) { + this.set_active_events(parser, value) } -function resumeH1 (client) { - const socket = client[kSocket] +function simpleCreate (spans, create) { + const parser = create() + spans[parser] = [] + this.setActiveCallbacks(parser, this.CALLBACK_ACTIVE_ALL) + return parser +} - if (socket && !socket.destroyed) { - if (client[kSize] === 0) { - if (!socket[kNoRef] && socket.unref) { - socket.unref() - socket[kNoRef] = true - } - } else if (socket[kNoRef] && socket.ref) { - socket.ref() - socket[kNoRef] = false - } +function simpleDestroy (spans, destroy, parser) { + spans[parser] = undefined + destroy(parser) +} - if (client[kSize] === 0) { - if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) { - socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE) - } - } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { - if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { - const request = client[kQueue][client[kRunningIdx]] - const headersTimeout = request.headersTimeout != null - ? request.headersTimeout - : client[kHeadersTimeout] - socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) - } +function noop () {} + +function setup (env = {}) { + let { logger: logOption, ...instanceEnvironment } = env + let logger = noop + const context = {} + + if (logOption) { + if (typeof logOption !== 'function') { + logOption = console.log } + + logger = log.bind(context, logOption) } -} -// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 -function shouldSendContentLength (method) { - return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' -} + // Create the WASM instance + /* eslint-disable-next-line no-undef */ + const instance = new WebAssembly.Instance(wasmModule, { + env: { + logger, + on_error: noop, + on_finish: noop, + on_message_start: noop, + on_message_complete: noop, + on_request: noop, + on_response: noop, + on_reset: noop, + on_method: noop, + on_url: noop, + on_protocol: noop, + on_version: noop, + on_status: noop, + on_reason: noop, + on_header_name: noop, + on_header_value: noop, + on_headers: noop, + on_connect: noop, + on_upgrade: noop, + on_chunk_length: noop, + on_chunk_extension_name: noop, + on_chunk_extension_value: noop, + on_chunk: noop, + on_body: noop, + on_data: noop, + on_trailer_name: noop, + on_trailer_value: noop, + on_trailers: noop, + on_state_change: noop, + ...instanceEnvironment + } + }) -function writeH1 (client, request) { - const { method, path, host, upgrade, blocking, reset } = request + const wasm = instance.exports + context.memory = wasm.memory - let { body, headers, contentLength } = request + const milo = { + version: { + raw: '0.9.0', + major: 0, + minor: 9, + patch: 0, + prerelease: '' + }, + METHOD_OTHER: 0, + METHOD_GET: 1, + METHOD_HEAD: 2, + METHOD_POST: 3, + METHOD_PUT: 4, + METHOD_DELETE: 5, + METHOD_CONNECT: 6, + METHOD_OPTIONS: 7, + METHOD_TRACE: 8, + METHOD_PATCH: 9, + METHOD_PRI: 10, + CALLBACK_ON_ERROR: 0, + CALLBACK_ON_FINISH: 1, + CALLBACK_ON_MESSAGE_START: 2, + CALLBACK_ON_MESSAGE_COMPLETE: 3, + CALLBACK_ON_REQUEST: 4, + CALLBACK_ON_RESPONSE: 5, + CALLBACK_ON_RESET: 6, + CALLBACK_ON_METHOD: 7, + CALLBACK_ON_URL: 8, + CALLBACK_ON_PROTOCOL: 9, + CALLBACK_ON_VERSION: 10, + CALLBACK_ON_STATUS: 11, + CALLBACK_ON_REASON: 12, + CALLBACK_ON_HEADER_NAME: 13, + CALLBACK_ON_HEADER_VALUE: 14, + CALLBACK_ON_HEADERS: 15, + CALLBACK_ON_CONNECT: 16, + CALLBACK_ON_UPGRADE: 17, + CALLBACK_ON_CHUNK_LENGTH: 18, + CALLBACK_ON_CHUNK_EXTENSION_NAME: 19, + CALLBACK_ON_CHUNK_EXTENSION_VALUE: 20, + CALLBACK_ON_CHUNK: 21, + CALLBACK_ON_BODY: 22, + CALLBACK_ON_DATA: 23, + CALLBACK_ON_TRAILER_NAME: 24, + CALLBACK_ON_TRAILER_VALUE: 25, + CALLBACK_ON_TRAILERS: 26, + CALLBACK_ON_STATE_CHANGE: 27, + EVENT_END: 0, + EVENT_ERROR: 1, + EVENT_FINISH: 2, + EVENT_MESSAGE_START: 3, + EVENT_MESSAGE_COMPLETE: 4, + EVENT_REQUEST: 5, + EVENT_RESPONSE: 6, + EVENT_RESET: 7, + EVENT_METHOD: 8, + EVENT_URL: 9, + EVENT_PROTOCOL: 10, + EVENT_VERSION: 11, + EVENT_STATUS: 12, + EVENT_REASON: 13, + EVENT_HEADER_NAME: 14, + EVENT_HEADER_VALUE: 15, + EVENT_HEADERS: 16, + EVENT_CONNECT: 17, + EVENT_UPGRADE: 18, + EVENT_CHUNK_LENGTH: 19, + EVENT_CHUNK_EXTENSION_NAME: 20, + EVENT_CHUNK_EXTENSION_VALUE: 21, + EVENT_CHUNK: 22, + EVENT_BODY: 23, + EVENT_DATA: 24, + EVENT_TRAILER_NAME: 25, + EVENT_TRAILER_VALUE: 26, + EVENT_TRAILERS: 27, + EVENT_STATE_CHANGE: 28, + CALLBACK_ACTIVE_NONE: 0n, + EVENT_ACTIVE_NONE: 0n, + CALLBACK_ACTIVE_ON_ERROR: 1n, + EVENT_ACTIVE_ON_ERROR: 1n, + CALLBACK_ACTIVE_ON_FINISH: 2n, + EVENT_ACTIVE_ON_FINISH: 2n, + CALLBACK_ACTIVE_ON_MESSAGE_START: 4n, + EVENT_ACTIVE_ON_MESSAGE_START: 4n, + CALLBACK_ACTIVE_ON_MESSAGE_COMPLETE: 8n, + EVENT_ACTIVE_ON_MESSAGE_COMPLETE: 8n, + CALLBACK_ACTIVE_ON_REQUEST: 16n, + EVENT_ACTIVE_ON_REQUEST: 16n, + CALLBACK_ACTIVE_ON_RESPONSE: 32n, + EVENT_ACTIVE_ON_RESPONSE: 32n, + CALLBACK_ACTIVE_ON_RESET: 64n, + EVENT_ACTIVE_ON_RESET: 64n, + CALLBACK_ACTIVE_ON_METHOD: 128n, + EVENT_ACTIVE_ON_METHOD: 128n, + CALLBACK_ACTIVE_ON_URL: 256n, + EVENT_ACTIVE_ON_URL: 256n, + CALLBACK_ACTIVE_ON_PROTOCOL: 512n, + EVENT_ACTIVE_ON_PROTOCOL: 512n, + CALLBACK_ACTIVE_ON_VERSION: 1024n, + EVENT_ACTIVE_ON_VERSION: 1024n, + CALLBACK_ACTIVE_ON_STATUS: 2048n, + EVENT_ACTIVE_ON_STATUS: 2048n, + CALLBACK_ACTIVE_ON_REASON: 4096n, + EVENT_ACTIVE_ON_REASON: 4096n, + CALLBACK_ACTIVE_ON_HEADER_NAME: 8192n, + EVENT_ACTIVE_ON_HEADER_NAME: 8192n, + CALLBACK_ACTIVE_ON_HEADER_VALUE: 16384n, + EVENT_ACTIVE_ON_HEADER_VALUE: 16384n, + CALLBACK_ACTIVE_ON_HEADERS: 32768n, + EVENT_ACTIVE_ON_HEADERS: 32768n, + CALLBACK_ACTIVE_ON_CONNECT: 65536n, + EVENT_ACTIVE_ON_CONNECT: 65536n, + CALLBACK_ACTIVE_ON_UPGRADE: 131072n, + EVENT_ACTIVE_ON_UPGRADE: 131072n, + CALLBACK_ACTIVE_ON_CHUNK_LENGTH: 262144n, + EVENT_ACTIVE_ON_CHUNK_LENGTH: 262144n, + CALLBACK_ACTIVE_ON_CHUNK_EXTENSION_NAME: 524288n, + EVENT_ACTIVE_ON_CHUNK_EXTENSION_NAME: 524288n, + CALLBACK_ACTIVE_ON_CHUNK_EXTENSION_VALUE: 1048576n, + EVENT_ACTIVE_ON_CHUNK_EXTENSION_VALUE: 1048576n, + CALLBACK_ACTIVE_ON_CHUNK: 2097152n, + EVENT_ACTIVE_ON_CHUNK: 2097152n, + CALLBACK_ACTIVE_ON_BODY: 4194304n, + EVENT_ACTIVE_ON_BODY: 4194304n, + CALLBACK_ACTIVE_ON_DATA: 8388608n, + EVENT_ACTIVE_ON_DATA: 8388608n, + CALLBACK_ACTIVE_ON_TRAILER_NAME: 16777216n, + EVENT_ACTIVE_ON_TRAILER_NAME: 16777216n, + CALLBACK_ACTIVE_ON_TRAILER_VALUE: 33554432n, + EVENT_ACTIVE_ON_TRAILER_VALUE: 33554432n, + CALLBACK_ACTIVE_ON_TRAILERS: 67108864n, + EVENT_ACTIVE_ON_TRAILERS: 67108864n, + CALLBACK_ACTIVE_ON_STATE_CHANGE: 134217728n, + EVENT_ACTIVE_ON_STATE_CHANGE: 134217728n, + CALLBACK_ACTIVE_ALL: 268435455n, + EVENT_ACTIVE_ALL: 268435455n, + ERROR_NONE: 0, + ERROR_USER: 1, + ERROR_CALLBACK_ERROR: 2, + ERROR_UNEXPECTED_STATE: 3, + ERROR_UNEXPECTED_DATA: 4, + ERROR_UNEXPECTED_EOF: 5, + ERROR_UNEXPECTED_CHARACTER: 6, + ERROR_UNEXPECTED_CONTENT_LENGTH: 7, + ERROR_UNEXPECTED_TRANSFER_ENCODING: 8, + ERROR_UNEXPECTED_CONTENT: 9, + ERROR_UNEXPECTED_TRAILERS: 10, + ERROR_INVALID_VERSION: 11, + ERROR_INVALID_STATUS: 12, + ERROR_INVALID_CONTENT_LENGTH: 13, + ERROR_INVALID_TRANSFER_ENCODING: 14, + ERROR_INVALID_CHUNK_SIZE: 15, + ERROR_MISSING_CONNECTION_UPGRADE: 16, + ERROR_UNSUPPORTED_HTTP_VERSION: 17, + STATE_START: 0, + STATE_FINISH: 1, + STATE_ERROR: 2, + STATE_REQUEST_LINE: 3, + STATE_STATUS_LINE: 4, + STATE_HTTP2_PREFACE: 5, + STATE_HEADER: 6, + STATE_BODY_DECISION: 7, + STATE_BODY_VIA_CONTENT_LENGTH: 8, + STATE_BODY_WITH_NO_LENGTH: 9, + STATE_CHUNK_HEADER: 10, + STATE_CHUNK_EXTENSIONS: 11, + STATE_CHUNK_DATA: 12, + STATE_TRAILER: 13, + STATE_TUNNEL: 14, + PARSER_FIELD_MAX_START_LINE_LENGTH: 0, + PARSER_FIELD_MAX_HEADER_LENGTH: 4, + PARSER_FIELD_MAX_BODY_PAYLOAD: 8, + PARSER_FIELD_AUTODETECT: 16, + PARSER_FIELD_IS_REQUEST: 17, + PARSER_FIELD_SUSPEND_AFTER_HEADERS: 18, + PARSER_FIELD_MANAGE_UNCONSUMED: 19, + PARSER_FIELD_CONTINUE_WITHOUT_DATA: 20, + PARSER_FIELD_IS_CONNECT: 21, + PARSER_FIELD_SKIP_BODY: 22, + PARSER_FIELD_DEBUG: 23, + PARSER_FIELD_PARSED: 24, + PARSER_FIELD_POSITION: 32, + PARSER_FIELD_STATE: 36, + PARSER_FIELD_PAUSED: 37, + PARSER_FIELD_ERROR_CODE: 38, + PARSER_FIELD_CONTENT_LENGTH: 40, + PARSER_FIELD_CHUNK_SIZE: 48, + PARSER_FIELD_REMAINING_CONTENT_LENGTH: 56, + PARSER_FIELD_REMAINING_CHUNK_SIZE: 64, + PARSER_FIELD_STATUS: 72, + PARSER_FIELD_METHOD: 76, + PARSER_FIELD_HAS_CONTENT_LENGTH: 77, + PARSER_FIELD_HAS_TRANSFER_ENCODING: 78, + PARSER_FIELD_HAS_CHUNKED_TRANSFER_ENCODING: 79, + PARSER_FIELD_HAS_CONNECTION_CLOSE: 80, + PARSER_FIELD_HAS_CONNECTION_UPGRADE: 81, + PARSER_FIELD_HAS_UPGRADE: 82, + PARSER_FIELD_HAS_TRAILERS: 83, + PARSER_FIELD_ACTIVE_CALLBACKS: 88, + PARSER_FIELD_ACTIVE_EVENTS: 96, + PARSER_FIELD_PTR: 104, + PARSER_FIELD_ERROR_DESCRIPTION: 108, + PARSER_FIELD_UNCONSUMED: 364, + PARSER_FIELD_UNCONSUMED_LEN: 368, + PARSER_FIELD_ERROR_DESCRIPTION_LEN: 372, + PARSER_FIELD_EVENTS: 376, + Errors, + Methods, + Callbacks, + CallbackActives, + Events, + EventActives, + States, + ParserFields, + isAutodetect: isAutodetect.bind(wasm), + isRequest: isRequest.bind(wasm), + isPaused: isPaused.bind(wasm), + shouldManageUnconsumed: shouldManageUnconsumed.bind(wasm), + shouldSuspendAfterHeaders: shouldSuspendAfterHeaders.bind(wasm), + getMaxStartLineLength: getMaxStartLineLength.bind(wasm), + getMaxHeaderLength: getMaxHeaderLength.bind(wasm), + getMaxBodyPayload: getMaxBodyPayload.bind(wasm), + shouldContinueWithoutData: shouldContinueWithoutData.bind(wasm), + isConnect: isConnect.bind(wasm), + isDebug: isDebug.bind(wasm), + shouldSkipBody: shouldSkipBody.bind(wasm), + getState: getState.bind(wasm), + getPosition: getPosition.bind(wasm), + getParsed: getParsed.bind(wasm), + getErrorCode: getErrorCode.bind(wasm), + getMethod: getMethod.bind(wasm), + getStatus: getStatus.bind(wasm), + hasConnectionClose: hasConnectionClose.bind(wasm), + hasConnectionUpgrade: hasConnectionUpgrade.bind(wasm), + getContentLength: getContentLength.bind(wasm), + getChunkSize: getChunkSize.bind(wasm), + getRemainingContentLength: getRemainingContentLength.bind(wasm), + getRemainingChunkSize: getRemainingChunkSize.bind(wasm), + hasContentLength: hasContentLength.bind(wasm), + hasTransferEncoding: hasTransferEncoding.bind(wasm), + hasChunkedTransferEncoding: hasChunkedTransferEncoding.bind(wasm), + hasUpgrade: hasUpgrade.bind(wasm), + hasTrailers: hasTrailers.bind(wasm), + getErrorDescription: getErrorDescription.bind(wasm), + setShouldAutodetect: setShouldAutodetect.bind(wasm), + setShouldContinueWithoutData: setShouldContinueWithoutData.bind(wasm), + setIsRequest: setIsRequest.bind(wasm), + setIsConnect: setIsConnect.bind(wasm), + setDebug: setDebug.bind(wasm), + setShouldManageUnconsumed: setShouldManageUnconsumed.bind(wasm), + setShouldSuspendAfterHeaders: setShouldSuspendAfterHeaders.bind(wasm), + setMaxStartLineLength: setMaxStartLineLength.bind(wasm), + setMaxHeaderLength: setMaxHeaderLength.bind(wasm), + setMaxBodyPayload: setMaxBodyPayload.bind(wasm), + setShouldSkipBody: setShouldSkipBody.bind(wasm), + setActiveCallbacks: setActiveCallbacks.bind(wasm), + setActiveEvents: setActiveEvents.bind(wasm), + memory: wasm.memory, + alloc: alloc.bind(wasm), + dealloc: dealloc.bind(wasm), + create: create.bind(wasm), + destroy: destroy.bind(wasm), + parse: parse.bind(wasm), + fail: fail.bind(wasm), + hasDebug: hasDebug.bind(wasm), + clear: wasm.clear, + complete: wasm.complete, + finish: wasm.finish, + pause: wasm.pause, + reset: wasm.reset, + resume: wasm.resume + } + + return milo +} + +function simple () { + const spans = {} + + const milo = setup({/* REPLACE: callbacks:simple */}) + + milo.spans = spans + milo.create = simpleCreate.bind(milo, spans, milo.create) + milo.destroy = simpleDestroy.bind(milo, spans, milo.destroy) + + return milo +} + +module.exports = { wasmModule, noop, setup, simple } - // https://tools.ietf.org/html/rfc7231#section-4.3.1 - // https://tools.ietf.org/html/rfc7231#section-4.3.2 - // https://tools.ietf.org/html/rfc7231#section-4.3.5 - // Sending a payload body on a request that does not - // expect it can cause undefined behavior on some - // servers and corrupt connection state. Do not - // re-use the connection for further requests. +/***/ }), - const expectsPayload = ( - method === 'PUT' || - method === 'POST' || - method === 'PATCH' || - method === 'QUERY' || - method === 'PROPFIND' || - method === 'PROPPATCH' +/***/ 9545: +/***/ ((module) => { + +const wasmModule = new WebAssembly.Module( + Buffer.from( + 'AGFzbQEAAAABQgtgA39/fwBgAX8Bf2ACf38AYAF/AGABfwF+YAJ/fgBgBH9/f38AYAABf2AIf39/f39/f3wAYAN/f38Bf2ACf38BfwKUBBwDZW52CG9uX2Vycm9yAAADZW52Cm9uX2hlYWRlcnMACANlbnYJb25fZmluaXNoAAADZW52EG9uX21lc3NhZ2Vfc3RhcnQAAANlbnYTb25fbWVzc2FnZV9jb21wbGV0ZQAAA2Vudgpvbl9yZXF1ZXN0AAADZW52C29uX3Jlc3BvbnNlAAADZW52CG9uX3Jlc2V0AAADZW52CW9uX21ldGhvZAAAA2VudgZvbl91cmwAAANlbnYLb25fcHJvdG9jb2wAAANlbnYKb25fdmVyc2lvbgAAA2Vudglvbl9zdGF0dXMAAANlbnYJb25fcmVhc29uAAADZW52Dm9uX2hlYWRlcl9uYW1lAAADZW52D29uX2hlYWRlcl92YWx1ZQAAA2Vudgpvbl9jb25uZWN0AAADZW52Cm9uX3VwZ3JhZGUAAANlbnYPb25fY2h1bmtfbGVuZ3RoAAADZW52F29uX2NodW5rX2V4dGVuc2lvbl9uYW1lAAADZW52GG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQAAA2Vudghvbl9jaHVuawAAA2Vudgdvbl9ib2R5AAADZW52B29uX2RhdGEAAANlbnYPb25fdHJhaWxlcl9uYW1lAAADZW52EG9uX3RyYWlsZXJfdmFsdWUAAANlbnYLb25fdHJhaWxlcnMAAANlbnYPb25fc3RhdGVfY2hhbmdlAAADQkEGAAEDAwcCAwYDBAQBBAQBAQEEAQQEAQEBAQEBAQEBAQEBAQEHCQMCAwUFAgICBQICAgICAgIBAQEBCgECAwICAgUDAQARBgkBfwFBgIDAAAsHnQg5Bm1lbW9yeQIABWFsbG9jAB4FY2xlYXIAHwhjb21wbGV0ZQAgBmNyZWF0ZQAhB2RlYWxsb2MAIgdkZXN0cm95ACMEZmFpbAAkBmZpbmlzaAAlDmdldF9jaHVua19zaXplACYSZ2V0X2NvbnRlbnRfbGVuZ3RoACcOZ2V0X2Vycm9yX2NvZGUAKBlnZXRfZXJyb3JfZGVzY3JpcHRpb25fcmF3ACkUZ2V0X21heF9ib2R5X3BheWxvYWQAKhVnZXRfbWF4X2hlYWRlcl9sZW5ndGgAKxlnZXRfbWF4X3N0YXJ0X2xpbmVfbGVuZ3RoACwKZ2V0X21ldGhvZAAtCmdldF9wYXJzZWQALgxnZXRfcG9zaXRpb24ALxhnZXRfcmVtYWluaW5nX2NodW5rX3NpemUAMBxnZXRfcmVtYWluaW5nX2NvbnRlbnRfbGVuZ3RoADEJZ2V0X3N0YXRlADIKZ2V0X3N0YXR1cwAzHWhhc19jaHVua2VkX3RyYW5zZmVyX2VuY29kaW5nADQUaGFzX2Nvbm5lY3Rpb25fY2xvc2UANRZoYXNfY29ubmVjdGlvbl91cGdyYWRlADYSaGFzX2NvbnRlbnRfbGVuZ3RoADcMaGFzX3RyYWlsZXJzADgVaGFzX3RyYW5zZmVyX2VuY29kaW5nADkLaGFzX3VwZ3JhZGUAOg1pc19hdXRvZGV0ZWN0ADsKaXNfY29ubmVjdAA8CGlzX2RlYnVnAD0JaXNfcGF1c2VkAD4KaXNfcmVxdWVzdAA/Dm1pbG9faGFzX2RlYnVnAEAFcGFyc2UAQQVwYXVzZQBCBXJlc2V0AEMGcmVzdW1lAEQUc2V0X2FjdGl2ZV9jYWxsYmFja3MARRFzZXRfYWN0aXZlX2V2ZW50cwBGCXNldF9kZWJ1ZwBHDnNldF9pc19jb25uZWN0AEgOc2V0X2lzX3JlcXVlc3QASRRzZXRfbWF4X2JvZHlfcGF5bG9hZABKFXNldF9tYXhfaGVhZGVyX2xlbmd0aABLGXNldF9tYXhfc3RhcnRfbGluZV9sZW5ndGgATBVzZXRfc2hvdWxkX2F1dG9kZXRlY3QATSBzZXRfc2hvdWxkX2NvbnRpbnVlX3dpdGhvdXRfZGF0YQBOHHNldF9zaG91bGRfbWFuYWdlX3VuY29uc3VtZWQATxRzZXRfc2hvdWxkX3NraXBfYm9keQBQIHNldF9zaG91bGRfc3VzcGVuZF9hZnRlcl9oZWFkZXJzAFEcc2hvdWxkX2NvbnRpbnVlX3dpdGhvdXRfZGF0YQBSGHNob3VsZF9tYW5hZ2VfdW5jb25zdW1lZABTEHNob3VsZF9za2lwX2JvZHkAVBxzaG91bGRfc3VzcGVuZF9hZnRlcl9oZWFkZXJzAFUKoLQCQdgDAgJ/BXsCQCACIANPDQAgAS0AACEBIAMgAmsiBUEPTQRAIANBAWsDQCAB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QgBSBEAgBUEQakGBgARJDQEMGQsgA0EBOgAUIANCADcDOCAFQV5IDRgMAwsgAygCICEBIAMoAvgCIAVqQRc6AAAgAygC+AIgBWpBAWogACABajYAACADKAL4AiAFakEFakEANgAAIANBAToAFCADQgA3AzggBUEJaiEFDAILIAMoAiAhASADKAL4AiAFakEYOgAAIAMoAvgCIAVqQQFqIAE2AAAgAygC+AIgBWpBBWogADYAACAFQQlqIQULIAMgAykDOCAvfTcDOEEAIQcMAwsCQCAXRQ0AIDRCAFIEQCAFQXBIDRYgAygCICECIAMoAvgCIAVqIgFBBDoAACABQQVqQQA2AAAgAUEBaiAAIAJqNgAAIAVBCWohBQsgM1ANACAFQXBIDRUgAygCICECIAMoAvgCIAVqIgFBBzoAACABQQVqQQA2AAAgAUEBaiAAIAJqNgAAIAVBCWohBQsgA0EAOgAWIANBADoAFAJAAkAgAy0AUkEBRgRAIAMtABFBAXENAQsgAy0AUA0BIAMtACRBAkcNAkEAIQcMBAtBACEHIAMtACRBAkYNAyADQQ46ACQMAwsgGUUNASAFQXBIDRQgAygCICECIAMoAvgCIAVqIgFBAjoAACABQQVqQQA2AAAgAUEBaiACNgAAIAVBCWohBQwBC0EAIQcgA0EAOgAkDAELQQAhByADLQAkQQJGDQAgA0EBOgAkCyADIAMoAiAgAGo2AiAgACAJSw0NIAsgAGshCyAAIARqIQQgCSAAayEJDAkLIANBAToAFCAFQd//A2tB//97SQ0QAkAgF0UNACA0QgBSBEAgBUFwSA0SIAMoAiAhASADKAL4AiAFaiIAQQQ6AAAgAEEFakEANgAAIABBAWogATYAACAFQQlqIQULIDNQDQAgBUFwSA0RIAMoAiAhASADKAL4AiAFaiIAQQc6AAAgAEEFakEANgAAIABBAWogATYAACAFQQlqIQULIANBADoAFiADQQA6ABQLIAMtAFBBAUcNASAZBEAgBUFwSA0QIAMoAiAhASADKAL4AiAFaiIAQQI6AAAgAEEFakEANgAAIABBAWogATYAACAFQQlqIQULIANBAToAJAtBACEHDAYLQQAhByADQQA6ACQMBQsgAygCACALSwRAQQEhEQwNCyADQQY6ACYgA0ECOgAkIANBu4rAAP0AAAD9CwBsIANBy4rAACgAADYAfAtBgAEhC0EUDAoLIAMoAgAgC0sEQEEBIREMCwsgA0EGOgAmIANBAjoAJCADQaWIwAD9AAAA/QsAbCADQbKIwAApAAA3AHkLQYEBIQtBFQwIC0EAIQcgAy0AJEECRg0AIANBBDoAJAtBASERIAdBAXENByADLQAlQQFxRQ0ACwwGCwALIAMoAvgCQQA6AAAMBQsAC0H5ACELQQ0MAQsgA0EGOgAmIANBAjoAJCADQZaIwAApAAA3AGwgA0GdiMAAKQAANwBzQfsAIQtBDws6APQCQQAhESADIAtqQQA6AAALIAMgAykDGCADKAIgIgutfDcDGAJAIAMtABNFDQAgAygC8AIiAARAIAMoAuwCIAAQWAsgA0IANwLsAiALIBRPDQACQAJAIAlFBEBBASEADAELIAlBARBWIgBFDQEgCUUNACAAIAQgCfwKAAALIAMgADYC7AIgAyAJNgLwAgwBCwALAkACQCAuQgGDUCARcgRAICBFDQEMAgsgBUH6/wNrQf//e0kNACADKAL4AiAFaiIAQQE6AAAgAEEBaiADKAIgNgAAIABBBWogAy0AJjoAACAFQQZqIQULIAMoAvgCIAVqQQA6AAALAkAgAykDWCIuUA0AIC5CAYMhLyAuQoCAAoMhMCAuQgKDITEgLkIEgyEzIC5CCIMhNCAuQhCDITUgLkIggyE2IC5CwACDITcgLkKAAYMhMiAuQoACgyE5IC5CgASDITogLkKACIMhOyAuQoAQgyE8IC5CgCCDIT0gLkKAwACDIT4gLkKAgAGDIT8gLkKAgASDIUAgLkKAgAiDIUEgLkKAgBCDIUIgLkKAgCCDIUMgLkKAgMAAgyFEIC5CgICAAYMhRSAuQoCAgAKDIUYgLkKAgIAEgyFHIC5CgICACIMhOCAuQoCAgBCDIUggLkKAgIAggyFJIC5CgICAwACDIS4gAygCaCECIAMoAvgCIQZBACEEA0ACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBCAGaiIALQAAQQFrDhwAAgMEBQYHCAkKCwwNDg8BEBESExQVFhcYGRobHwtBBiEBIC9QDRsgAiAAQQFqKAAAQQAQACAEQQZqIQQMHQtBEyEBIDBQDRogAiAAQQFqKAAAIABBBWovAAAgAEEHai0AAEEARyAAQQhqLQAAQQBHIABBCWotAABBAEcgAEEKai0AACAAQQtqKQAAuhABIARBE2ohBAwcC0EJIQEgMVANGSACIABBAWooAAAgAEEFaigAABACIARBCWohBAwbC0EJIQEgM1ANGCACIABBAWooAAAgAEEFaigAABADIARBCWohBAwaC0EJIQEgNFANFyACIABBAWooAAAgAEEFaigAABAEIARBCWohBAwZC0EJIQEgNVANFiACIABBAWooAAAgAEEFaigAABAFIARBCWohBAwYC0EJIQEgNlANFSACIABBAWooAAAgAEEFaigAABAGIARBCWohBAwXC0EJIQEgN1ANFCACIABBAWooAAAgAEEFaigAABAHIARBCWohBAwWC0EJIQEgMlANEyACIABBAWooAAAgAEEFaigAABAIIARBCWohBAwVC0EJIQEgOVANEiACIABBAWooAAAgAEEFaigAABAJIARBCWohBAwUC0EJIQEgOlANESACIABBAWooAAAgAEEFaigAABAKIARBCWohBAwTC0EJIQEgO1ANECACIABBAWooAAAgAEEFaigAABALIARBCWohBAwSC0EJIQEgPFANDyACIABBAWooAAAgAEEFaigAABAMIARBCWohBAwRC0EJIQEgPVANDiACIABBAWooAAAgAEEFaigAABANIARBCWohBAwQC0EJIQEgPlANDSACIABBAWooAAAgAEEFaigAABAOIARBCWohBAwPC0EJIQEgP1ANDCACIABBAWooAAAgAEEFaigAABAPIARBCWohBAwOC0EJIQEgQFANCyACIABBAWooAAAgAEEFaigAABAQIARBCWohBAwNC0EJIQEgQVANCiACIABBAWooAAAgAEEFaigAABARIARBCWohBAwMC0EJIQEgQlANCSACIABBAWooAAAgAEEFaigAABASIARBCWohBAwLC0EJIQEgQ1ANCCACIABBAWooAAAgAEEFaigAABATIARBCWohBAwKC0EJIQEgRFANByACIABBAWooAAAgAEEFaigAABAUIARBCWohBAwJC0EJIQEgRVANBiACIABBAWooAAAgAEEFaigAABAVIARBCWohBAwIC0EJIQEgRlANBSACIABBAWooAAAgAEEFaigAABAWIARBCWohBAwHC0EJIQEgR1ANBCAC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AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEGJhMAACwEBAEGghMAAC+ABAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQaGGwAALXgEAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAQYCIwAALtBBVbmV4cGVjdGVkIGVuZCBvZiBkYXRhVW5leHBlY3RlZCBkYXRhUmVxdWVzdCBsaW5lIHRvbyBsb25nSW52YWxpZCBtZXRob2QgY2hhcmFjdGVySW52YWxpZCBVUkwgY2hhcmFjdGVyUFJJIGlzIG9ubHkgdmFsaWQgd2l0aCBIVFRQLzIuMFVuc3VwcG9ydGVkIEhUVFAgdmVyc2lvbkludmFsaWQgcHJvdG9jb2xJbnZhbGlkIHByb3RvY29sIG5hbWVFeHBlY3RlZCAvIGFmdGVyIHRoZSBwcm90b2NvbCBuYW1lRXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgVVJMRXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kUmVxdWVzdCBsaW5lIHRvbyBzaG9ydEV4cGVjdGVkIENSTEZTdGF0dXMgbGluZSB0b28gbG9uZ0ludmFsaWQgSFRUUCByZXNwb25zZSBzdGF0dXNJbnZhbGlkIHN0YXR1cyByZWFzb24gY2hhcmFjdGVyRXhwZWN0ZWQgYSBzcGFjZSBhZnRlciBIVFRQIHJlc3BvbnNlIHN0YXR1c0V4cGVjdGVkIHNwYWNlIGFmdGVyIHByb3RvY29sU3RhdHVzIGxpbmUgdG9vIHNob3J0TWFsZm9ybWVkIEhUVFAvMi4wIHByZWZhY2VVbmV4cGVjdGVkIENvbnRlbnQtTGVuZ3RoIGhlYWRlciBmb3IgYSByZXNwb25zZSB3aXRob3V0IGJvZHlFeHBlY3RlZCBDb250ZW50LUxlbmd0aCBoZWFkZXIgdmFsdWVJbnZhbGlkIENvbnRlbnQtTGVuZ3RoIGhlYWRlckludmFsaWQgZHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoIGhlYWRlclVuZXhwZWN0ZWQgQ29udGVudC1MZW5ndGggaGVhZGVyIHdoZW4gVHJhbnNmZXItRW5jb2RpbmcgaGVhZGVyIGlzIHByZXNlbnRVbmV4cGVjdGVkIFRyYW5zZmVyLUVuY29kaW5nIGhlYWRlciBmb3IgYSByZXNwb25zZSB3aXRob3V0IGJvZHlFeHBlY3RlZCBUcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgdmFsdWVUaGUgdmFsdWUgImNodW5rZWQiIGluIHRoZSBUcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgbXVzdCBiZSB0aGUgbGFzdCBwcm92aWRlZCBhbmQgY2FuIGJlIHByb3ZpZGVkIG9ubHkgb25jZVRoZSB2YWx1ZSAiY2h1bmtlZCIgaW4gdGhlIFRyYW5zZmVyLUVuY29kaW5nIGhlYWRlciBtdXN0IGJlIHRoZSBsYXN0IHByb3ZpZGVkVW5leHBlY3RlZCBUcmFuc2Zlci1FbmNvZGluZyBoZWFkZXIgd2hlbiBDb250ZW50LUxlbmd0aCBoZWFkZXIgaXMgcHJlc2VudEV4cGVjdGVkIENvbm5lY3Rpb24gaGVhZGVyIHZhbHVlSW52YWxpZCBDb25uZWN0aW9uIGhlYWRlciB2YWx1ZUV4cGVjdGVkIFRyYWlsZXIgaGVhZGVyIHZhbHVlRXhwZWN0ZWQgVXBncmFkZSBoZWFkZXIgdmFsdWVJbnZhbGlkIFVwZ3JhZGUgaGVhZGVyIHZhbHVlSW52YWxpZCBoZWFkZXIgZmllbGQgbmFtZSBjaGFyYWN0ZXJJbnZhbGlkIGhlYWRlciBmaWVsZCB2YWx1ZSBjaGFyYWN0ZXJIZWFkZXIgbGluZSB0b28gbG9uZ01pc3NpbmcgQ29ubmVjdGlvbiBoZWFkZXIgc2V0IHRvICJ1cGdyYWRlIiB3aGVuIHVzaW5nIHRoZSBVcGdyYWRlIGhlYWRlclRyYWlsZXJzIGFyZSBub3QgYWxsb3dlZCB3aGVuIG5vdCB1c2luZyBjaHVua2VkIHRyYW5zZmVyIGVuY29kaW5nVW5leHBlY3RlZCBjb250ZW50IGZvciB0aGUgcmVxdWVzdCAoR0VUIG9yIEhFQUQpVHJhbnNmZXItRW5jb2RpbmcgbGFzdCBoZWFkZXIgdmFsdWUgbXVzdCBiZSAiY2h1bmtlZCIgaWYgdGhlIGhlYWRlciBpcyBwcmVzZW50Q2h1bmsgaGVhZGVyIHRvbyBsb25nSW52YWxpZCBjaHVuayBsZW5ndGggY2hhcmFjdGVySW52YWxpZCBjaHVuayBsZW5ndGggc2l6ZUV4cGVjdGVkIGNodW5rIGV4dGVuc2lvbiBuYW1lSW52YWxpZCBjaHVuayBleHRlbnNpb24gbmFtZSBjaGFyYWN0ZXJFeHBlY3RlZCBjbG9zaW5nIHF1b3RlIGZvciBjaHVuayBleHRlbnNpb24gdmFsdWVJbnZhbGlkIGNodW5rIGV4dGVuc2lvbiBxdW90ZWQgdmFsdWUgY2hhcmFjdGVyRXhwZWN0ZWQgY2h1bmsgZXh0ZW5zaW9uIHZhbHVlSW52YWxpZCBjaHVuayBleHRlbnNpb24gdmFsdWUgY2hhcmFjdGVySW52YWxpZCBjaHVuayBleHRlbnNpb24gY2hhcmFjdGVyIGFmdGVyIHZhbHVlRXhwZWN0ZWQgQ1JMRiBhZnRlciBjaHVuayBkYXRhSW52YWxpZCB0cmFpbGVyIGZpZWxkIG5hbWUgY2hhcmFjdGVySW52YWxpZCB0cmFpbGVyIGZpZWxkIHZhbHVlIGNoYXJhY3RlclRyYWlsZXIgbGluZSB0b28gbG9uZ0ludmFsaWQgc3RhdGU=', + 'base64' ) +) - if (util.isFormDataLike(body)) { - if (!extractBody) { - extractBody = (__nccwpck_require__(4492).extractBody) - } +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() - const [bodyStream, contentType] = extractBody(body) - if (request.contentType == null) { - headers.push('content-type', contentType) - } - body = bodyStream.stream - contentLength = bodyStream.length - } else if (util.isBlobLike(body) && request.contentType == null && body.type) { - headers.push('content-type', body.type) - } +function log (logger, raw) { + const len = Number(BigInt.asUintN(32, raw)) + const ptr = Number(raw >> 32n) - if (body && typeof body.read === 'function') { - // Try to read EOF in order to get length. - body.read(0) - } + logger(textDecoder.decode(new Uint8Array(this.memory.buffer, ptr, len))) +} - const bodyLength = util.bodyLength(body) +function alloc (len) { + return this.alloc(len) >>> 0 +} - contentLength = bodyLength ?? contentLength +function dealloc (ptr, len) { + return this.dealloc(ptr, len) +} - if (contentLength === null) { - contentLength = request.contentLength - } +function create () { + return this.create() >>> 0 +} - if (contentLength === 0 && !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // 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. +function destroy (parser) { + this.destroy(parser) +} - contentLength = null - } +function parse (parser, data, limit) { + return this.parse(parser, data, limit) >>> 0 +} - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - util.errorRequest(client, request, new RequestContentLengthMismatchError()) - return false - } +function fail (parser, code, description) { + const len = description.length + const ptr = this.alloc(len) + const buffer = new Uint8Array(this.memory.buffer, ptr, len) + textEncoder.encodeInto(description, buffer) - process.emitWarning(new RequestContentLengthMismatchError()) - } + this.fail(parser, code, ptr, len) + this.dealloc(ptr, len) +} - const socket = client[kSocket] +function hasDebug () { + return this.milo_has_debug() !== 0 +} - const abort = (err) => { - if (request.aborted || request.completed) { - return - } +const Errors = Object.freeze({ + NONE: 0, + USER: 1, + CALLBACK_ERROR: 2, + UNEXPECTED_STATE: 3, + UNEXPECTED_DATA: 4, + UNEXPECTED_EOF: 5, + UNEXPECTED_CHARACTER: 6, + UNEXPECTED_CONTENT_LENGTH: 7, + UNEXPECTED_TRANSFER_ENCODING: 8, + UNEXPECTED_CONTENT: 9, + UNEXPECTED_TRAILERS: 10, + INVALID_VERSION: 11, + INVALID_STATUS: 12, + INVALID_CONTENT_LENGTH: 13, + INVALID_TRANSFER_ENCODING: 14, + INVALID_CHUNK_SIZE: 15, + MISSING_CONNECTION_UPGRADE: 16, + UNSUPPORTED_HTTP_VERSION: 17, + 0: 'NONE', + 1: 'USER', + 2: 'CALLBACK_ERROR', + 3: 'UNEXPECTED_STATE', + 4: 'UNEXPECTED_DATA', + 5: 'UNEXPECTED_EOF', + 6: 'UNEXPECTED_CHARACTER', + 7: 'UNEXPECTED_CONTENT_LENGTH', + 8: 'UNEXPECTED_TRANSFER_ENCODING', + 9: 'UNEXPECTED_CONTENT', + 10: 'UNEXPECTED_TRAILERS', + 11: 'INVALID_VERSION', + 12: 'INVALID_STATUS', + 13: 'INVALID_CONTENT_LENGTH', + 14: 'INVALID_TRANSFER_ENCODING', + 15: 'INVALID_CHUNK_SIZE', + 16: 'MISSING_CONNECTION_UPGRADE', + 17: 'UNSUPPORTED_HTTP_VERSION' +}) - util.errorRequest(client, request, err || new RequestAbortedError()) +const Methods = Object.freeze({ + OTHER: 0, + GET: 1, + HEAD: 2, + POST: 3, + PUT: 4, + DELETE: 5, + CONNECT: 6, + OPTIONS: 7, + TRACE: 8, + PATCH: 9, + PRI: 10, + 0: 'OTHER', + 1: 'GET', + 2: 'HEAD', + 3: 'POST', + 4: 'PUT', + 5: 'DELETE', + 6: 'CONNECT', + 7: 'OPTIONS', + 8: 'TRACE', + 9: 'PATCH', + 10: 'PRI' +}) - util.destroy(body) - util.destroy(socket, new InformationalError('aborted')) - } +const Callbacks = Object.freeze({ + ON_ERROR: 0, + ON_FINISH: 1, + ON_MESSAGE_START: 2, + ON_MESSAGE_COMPLETE: 3, + ON_REQUEST: 4, + ON_RESPONSE: 5, + ON_RESET: 6, + ON_METHOD: 7, + ON_URL: 8, + ON_PROTOCOL: 9, + ON_VERSION: 10, + ON_STATUS: 11, + ON_REASON: 12, + ON_HEADER_NAME: 13, + ON_HEADER_VALUE: 14, + ON_HEADERS: 15, + ON_CONNECT: 16, + ON_UPGRADE: 17, + ON_CHUNK_LENGTH: 18, + ON_CHUNK_EXTENSION_NAME: 19, + ON_CHUNK_EXTENSION_VALUE: 20, + ON_CHUNK: 21, + ON_BODY: 22, + ON_DATA: 23, + ON_TRAILER_NAME: 24, + ON_TRAILER_VALUE: 25, + ON_TRAILERS: 26, + ON_STATE_CHANGE: 27, + 0: 'ON_ERROR', + 1: 'ON_FINISH', + 2: 'ON_MESSAGE_START', + 3: 'ON_MESSAGE_COMPLETE', + 4: 'ON_REQUEST', + 5: 'ON_RESPONSE', + 6: 'ON_RESET', + 7: 'ON_METHOD', + 8: 'ON_URL', + 9: 'ON_PROTOCOL', + 10: 'ON_VERSION', + 11: 'ON_STATUS', + 12: 'ON_REASON', + 13: 'ON_HEADER_NAME', + 14: 'ON_HEADER_VALUE', + 15: 'ON_HEADERS', + 16: 'ON_CONNECT', + 17: 'ON_UPGRADE', + 18: 'ON_CHUNK_LENGTH', + 19: 'ON_CHUNK_EXTENSION_NAME', + 20: 'ON_CHUNK_EXTENSION_VALUE', + 21: 'ON_CHUNK', + 22: 'ON_BODY', + 23: 'ON_DATA', + 24: 'ON_TRAILER_NAME', + 25: 'ON_TRAILER_VALUE', + 26: 'ON_TRAILERS', + 27: 'ON_STATE_CHANGE' +}) - try { - request.onConnect(abort) - } catch (err) { - util.errorRequest(client, request, err) - } +const CallbackActives = Object.freeze({ + NONE: 0n, + ON_ERROR: 1n, + ON_FINISH: 2n, + ON_MESSAGE_START: 4n, + ON_MESSAGE_COMPLETE: 8n, + ON_REQUEST: 16n, + ON_RESPONSE: 32n, + ON_RESET: 64n, + ON_METHOD: 128n, + ON_URL: 256n, + ON_PROTOCOL: 512n, + ON_VERSION: 1024n, + ON_STATUS: 2048n, + ON_REASON: 4096n, + ON_HEADER_NAME: 8192n, + ON_HEADER_VALUE: 16384n, + ON_HEADERS: 32768n, + ON_CONNECT: 65536n, + ON_UPGRADE: 131072n, + ON_CHUNK_LENGTH: 262144n, + ON_CHUNK_EXTENSION_NAME: 524288n, + ON_CHUNK_EXTENSION_VALUE: 1048576n, + ON_CHUNK: 2097152n, + ON_BODY: 4194304n, + ON_DATA: 8388608n, + ON_TRAILER_NAME: 16777216n, + ON_TRAILER_VALUE: 33554432n, + ON_TRAILERS: 67108864n, + ON_STATE_CHANGE: 134217728n, + ALL: 268435455n, + 0n: 'NONE', + 1n: 'ON_ERROR', + 2n: 'ON_FINISH', + 4n: 'ON_MESSAGE_START', + 8n: 'ON_MESSAGE_COMPLETE', + 16n: 'ON_REQUEST', + 32n: 'ON_RESPONSE', + 64n: 'ON_RESET', + 128n: 'ON_METHOD', + 256n: 'ON_URL', + 512n: 'ON_PROTOCOL', + 1024n: 'ON_VERSION', + 2048n: 'ON_STATUS', + 4096n: 'ON_REASON', + 8192n: 'ON_HEADER_NAME', + 16384n: 'ON_HEADER_VALUE', + 32768n: 'ON_HEADERS', + 65536n: 'ON_CONNECT', + 131072n: 'ON_UPGRADE', + 262144n: 'ON_CHUNK_LENGTH', + 524288n: 'ON_CHUNK_EXTENSION_NAME', + 1048576n: 'ON_CHUNK_EXTENSION_VALUE', + 2097152n: 'ON_CHUNK', + 4194304n: 'ON_BODY', + 8388608n: 'ON_DATA', + 16777216n: 'ON_TRAILER_NAME', + 33554432n: 'ON_TRAILER_VALUE', + 67108864n: 'ON_TRAILERS', + 134217728n: 'ON_STATE_CHANGE', + 268435455n: 'ALL' +}) - if (request.aborted) { - return false - } +const Events = Object.freeze({ + END: 0, + ERROR: 1, + FINISH: 2, + MESSAGE_START: 3, + MESSAGE_COMPLETE: 4, + REQUEST: 5, + RESPONSE: 6, + RESET: 7, + METHOD: 8, + URL: 9, + PROTOCOL: 10, + VERSION: 11, + STATUS: 12, + REASON: 13, + HEADER_NAME: 14, + HEADER_VALUE: 15, + HEADERS: 16, + CONNECT: 17, + UPGRADE: 18, + CHUNK_LENGTH: 19, + CHUNK_EXTENSION_NAME: 20, + CHUNK_EXTENSION_VALUE: 21, + CHUNK: 22, + BODY: 23, + DATA: 24, + TRAILER_NAME: 25, + TRAILER_VALUE: 26, + TRAILERS: 27, + STATE_CHANGE: 28, + 0: 'END', + 1: 'ERROR', + 2: 'FINISH', + 3: 'MESSAGE_START', + 4: 'MESSAGE_COMPLETE', + 5: 'REQUEST', + 6: 'RESPONSE', + 7: 'RESET', + 8: 'METHOD', + 9: 'URL', + 10: 'PROTOCOL', + 11: 'VERSION', + 12: 'STATUS', + 13: 'REASON', + 14: 'HEADER_NAME', + 15: 'HEADER_VALUE', + 16: 'HEADERS', + 17: 'CONNECT', + 18: 'UPGRADE', + 19: 'CHUNK_LENGTH', + 20: 'CHUNK_EXTENSION_NAME', + 21: 'CHUNK_EXTENSION_VALUE', + 22: 'CHUNK', + 23: 'BODY', + 24: 'DATA', + 25: 'TRAILER_NAME', + 26: 'TRAILER_VALUE', + 27: 'TRAILERS', + 28: 'STATE_CHANGE' +}) - if (method === 'HEAD') { - // https://github.com/mcollina/undici/issues/258 - // Close after a HEAD request to interop with misbehaving servers - // that may send a body in the response. +const EventActives = Object.freeze({ + NONE: 0n, + ON_ERROR: 1n, + ON_FINISH: 2n, + ON_MESSAGE_START: 4n, + ON_MESSAGE_COMPLETE: 8n, + ON_REQUEST: 16n, + ON_RESPONSE: 32n, + ON_RESET: 64n, + ON_METHOD: 128n, + ON_URL: 256n, + ON_PROTOCOL: 512n, + ON_VERSION: 1024n, + ON_STATUS: 2048n, + ON_REASON: 4096n, + ON_HEADER_NAME: 8192n, + ON_HEADER_VALUE: 16384n, + ON_HEADERS: 32768n, + ON_CONNECT: 65536n, + ON_UPGRADE: 131072n, + ON_CHUNK_LENGTH: 262144n, + ON_CHUNK_EXTENSION_NAME: 524288n, + ON_CHUNK_EXTENSION_VALUE: 1048576n, + ON_CHUNK: 2097152n, + ON_BODY: 4194304n, + ON_DATA: 8388608n, + ON_TRAILER_NAME: 16777216n, + ON_TRAILER_VALUE: 33554432n, + ON_TRAILERS: 67108864n, + ON_STATE_CHANGE: 134217728n, + ALL: 268435455n, + 0n: 'NONE', + 1n: 'ON_ERROR', + 2n: 'ON_FINISH', + 4n: 'ON_MESSAGE_START', + 8n: 'ON_MESSAGE_COMPLETE', + 16n: 'ON_REQUEST', + 32n: 'ON_RESPONSE', + 64n: 'ON_RESET', + 128n: 'ON_METHOD', + 256n: 'ON_URL', + 512n: 'ON_PROTOCOL', + 1024n: 'ON_VERSION', + 2048n: 'ON_STATUS', + 4096n: 'ON_REASON', + 8192n: 'ON_HEADER_NAME', + 16384n: 'ON_HEADER_VALUE', + 32768n: 'ON_HEADERS', + 65536n: 'ON_CONNECT', + 131072n: 'ON_UPGRADE', + 262144n: 'ON_CHUNK_LENGTH', + 524288n: 'ON_CHUNK_EXTENSION_NAME', + 1048576n: 'ON_CHUNK_EXTENSION_VALUE', + 2097152n: 'ON_CHUNK', + 4194304n: 'ON_BODY', + 8388608n: 'ON_DATA', + 16777216n: 'ON_TRAILER_NAME', + 33554432n: 'ON_TRAILER_VALUE', + 67108864n: 'ON_TRAILERS', + 134217728n: 'ON_STATE_CHANGE', + 268435455n: 'ALL' +}) - socket[kReset] = true - } +const States = Object.freeze({ + START: 0, + FINISH: 1, + ERROR: 2, + REQUEST_LINE: 3, + STATUS_LINE: 4, + HTTP2_PREFACE: 5, + HEADER: 6, + BODY_DECISION: 7, + BODY_VIA_CONTENT_LENGTH: 8, + BODY_WITH_NO_LENGTH: 9, + CHUNK_HEADER: 10, + CHUNK_EXTENSIONS: 11, + CHUNK_DATA: 12, + TRAILER: 13, + TUNNEL: 14, + 0: 'START', + 1: 'FINISH', + 2: 'ERROR', + 3: 'REQUEST_LINE', + 4: 'STATUS_LINE', + 5: 'HTTP2_PREFACE', + 6: 'HEADER', + 7: 'BODY_DECISION', + 8: 'BODY_VIA_CONTENT_LENGTH', + 9: 'BODY_WITH_NO_LENGTH', + 10: 'CHUNK_HEADER', + 11: 'CHUNK_EXTENSIONS', + 12: 'CHUNK_DATA', + 13: 'TRAILER', + 14: 'TUNNEL' +}) - if (upgrade || method === 'CONNECT') { - // On CONNECT or upgrade, block pipeline from dispatching further - // requests on this connection. +const ParserFields = Object.freeze({ + MAX_START_LINE_LENGTH: 0, + MAX_HEADER_LENGTH: 4, + MAX_BODY_PAYLOAD: 8, + AUTODETECT: 16, + IS_REQUEST: 17, + SUSPEND_AFTER_HEADERS: 18, + MANAGE_UNCONSUMED: 19, + CONTINUE_WITHOUT_DATA: 20, + IS_CONNECT: 21, + SKIP_BODY: 22, + DEBUG: 23, + PARSED: 24, + POSITION: 32, + STATE: 36, + PAUSED: 37, + ERROR_CODE: 38, + CONTENT_LENGTH: 40, + CHUNK_SIZE: 48, + REMAINING_CONTENT_LENGTH: 56, + REMAINING_CHUNK_SIZE: 64, + STATUS: 72, + METHOD: 76, + HAS_CONTENT_LENGTH: 77, + HAS_TRANSFER_ENCODING: 78, + HAS_CHUNKED_TRANSFER_ENCODING: 79, + HAS_CONNECTION_CLOSE: 80, + HAS_CONNECTION_UPGRADE: 81, + HAS_UPGRADE: 82, + HAS_TRAILERS: 83, + ACTIVE_CALLBACKS: 88, + ACTIVE_EVENTS: 96, + PTR: 104, + ERROR_DESCRIPTION: 108, + UNCONSUMED: 364, + UNCONSUMED_LEN: 368, + ERROR_DESCRIPTION_LEN: 372, + EVENTS: 376, + 0: 'MAX_START_LINE_LENGTH', + 4: 'MAX_HEADER_LENGTH', + 8: 'MAX_BODY_PAYLOAD', + 16: 'AUTODETECT', + 17: 'IS_REQUEST', + 18: 'SUSPEND_AFTER_HEADERS', + 19: 'MANAGE_UNCONSUMED', + 20: 'CONTINUE_WITHOUT_DATA', + 21: 'IS_CONNECT', + 22: 'SKIP_BODY', + 23: 'DEBUG', + 24: 'PARSED', + 32: 'POSITION', + 36: 'STATE', + 37: 'PAUSED', + 38: 'ERROR_CODE', + 40: 'CONTENT_LENGTH', + 48: 'CHUNK_SIZE', + 56: 'REMAINING_CONTENT_LENGTH', + 64: 'REMAINING_CHUNK_SIZE', + 72: 'STATUS', + 76: 'METHOD', + 77: 'HAS_CONTENT_LENGTH', + 78: 'HAS_TRANSFER_ENCODING', + 79: 'HAS_CHUNKED_TRANSFER_ENCODING', + 80: 'HAS_CONNECTION_CLOSE', + 81: 'HAS_CONNECTION_UPGRADE', + 82: 'HAS_UPGRADE', + 83: 'HAS_TRAILERS', + 88: 'ACTIVE_CALLBACKS', + 96: 'ACTIVE_EVENTS', + 104: 'PTR', + 108: 'ERROR_DESCRIPTION', + 364: 'UNCONSUMED', + 368: 'UNCONSUMED_LEN', + 372: 'ERROR_DESCRIPTION_LEN', + 376: 'EVENTS' +}) - socket[kReset] = true - } +function isAutodetect (parser) { + return this.is_autodetect(parser) !== 0 +} - if (reset != null) { - socket[kReset] = reset - } +function isRequest (parser) { + return this.is_request(parser) !== 0 +} - if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { - socket[kReset] = true - } +function isPaused (parser) { + return this.is_paused(parser) !== 0 +} - if (blocking) { - socket[kBlocking] = true - } +function shouldManageUnconsumed (parser) { + return this.should_manage_unconsumed(parser) !== 0 +} - let header = `${method} ${path} HTTP/1.1\r\n` +function shouldSuspendAfterHeaders (parser) { + return this.should_suspend_after_headers(parser) !== 0 +} - if (typeof host === 'string') { - header += `host: ${host}\r\n` - } else { - header += client[kHostHeader] - } +function getMaxStartLineLength (parser) { + return this.get_max_start_line_length(parser) >>> 0 +} - if (upgrade) { - header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` - } else if (client[kPipelining] && !socket[kReset]) { - header += 'connection: keep-alive\r\n' - } else { - header += 'connection: close\r\n' - } +function getMaxHeaderLength (parser) { + return this.get_max_header_length(parser) >>> 0 +} - if (Array.isArray(headers)) { - for (let n = 0; n < headers.length; n += 2) { - const key = headers[n + 0] - const val = headers[n + 1] +function getMaxBodyPayload (parser) { + return BigInt.asUintN(64, this.get_max_body_payload(parser)) +} - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - header += `${key}: ${val[i]}\r\n` - } - } else { - header += `${key}: ${val}\r\n` - } - } - } +function shouldContinueWithoutData (parser) { + return this.should_continue_without_data(parser) !== 0 +} - if (channels.sendHeaders.hasSubscribers) { - channels.sendHeaders.publish({ request, headers: header, socket }) - } +function isConnect (parser) { + return this.is_connect(parser) !== 0 +} - /* istanbul ignore else: assertion */ - if (!body || bodyLength === 0) { - writeBuffer(abort, null, client, request, socket, contentLength, header, expectsPayload) - } else if (util.isBuffer(body)) { - writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload) - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable(abort, body.stream(), client, request, socket, contentLength, header, expectsPayload) - } else { - writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload) - } - } else if (util.isStream(body)) { - writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload) - } else if (util.isIterable(body)) { - writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload) - } else { - assert(false) - } +function isDebug (parser) { + return this.is_debug(parser) !== 0 +} - return true +function shouldSkipBody (parser) { + return this.should_skip_body(parser) !== 0 } -function writeStream (abort, body, client, request, socket, contentLength, header, expectsPayload) { - assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') +function getState (parser) { + return this.get_state(parser) >>> 0 +} - let finished = false +function getPosition (parser) { + return this.get_position(parser) >>> 0 +} - const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }) +function getParsed (parser) { + return BigInt.asUintN(64, this.get_parsed(parser)) +} - const onData = function (chunk) { - if (finished) { - return - } +function getErrorCode (parser) { + return this.get_error_code(parser) >>> 0 +} - try { - if (!writer.write(chunk) && this.pause) { - this.pause() - } - } catch (err) { - util.destroy(this, err) - } - } - const onDrain = function () { - if (finished) { - return - } +function getMethod (parser) { + return this.get_method(parser) >>> 0 +} - if (body.resume) { - body.resume() - } - } - const onClose = function () { - // 'close' might be emitted *before* 'error' for - // broken streams. Wait a tick to avoid this case. - queueMicrotask(() => { - // It's only safe to remove 'error' listener after - // 'close'. - body.removeListener('error', onFinished) - }) +function getStatus (parser) { + return this.get_status(parser) >>> 0 +} - if (!finished) { - const err = new RequestAbortedError() - queueMicrotask(() => onFinished(err)) - } - } - const onFinished = function (err) { - if (finished) { - return - } +function hasConnectionClose (parser) { + return this.has_connection_close(parser) !== 0 +} + +function hasConnectionUpgrade (parser) { + return this.has_connection_upgrade(parser) !== 0 +} + +function getContentLength (parser) { + return BigInt.asUintN(64, this.get_content_length(parser)) +} - finished = true +function getChunkSize (parser) { + return BigInt.asUintN(64, this.get_chunk_size(parser)) +} - assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)) +function getRemainingContentLength (parser) { + return BigInt.asUintN(64, this.get_remaining_content_length(parser)) +} - socket - .off('drain', onDrain) - .off('error', onFinished) +function getRemainingChunkSize (parser) { + return BigInt.asUintN(64, this.get_remaining_chunk_size(parser)) +} - body - .removeListener('data', onData) - .removeListener('end', onFinished) - .removeListener('close', onClose) +function hasContentLength (parser) { + return this.has_content_length(parser) !== 0 +} - if (!err) { - try { - writer.end() - } catch (er) { - err = er - } - } +function hasTransferEncoding (parser) { + return this.has_transfer_encoding(parser) !== 0 +} - writer.destroy(err) +function hasChunkedTransferEncoding (parser) { + return this.has_chunked_transfer_encoding(parser) !== 0 +} - if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { - util.destroy(body, err) - } else { - util.destroy(body) - } - } +function hasUpgrade (parser) { + return this.has_upgrade(parser) !== 0 +} - body - .on('data', onData) - .on('end', onFinished) - .on('error', onFinished) - .on('close', onClose) +function hasTrailers (parser) { + return this.has_trailers(parser) !== 0 +} - if (body.resume) { - body.resume() - } +function getErrorDescription (parser) { + const raw = this.get_error_description_raw(parser) + const len = Number(BigInt.asUintN(32, raw)) + const ptr = Number(raw >> 32n) + return textDecoder.decode(new Uint8Array(this.memory.buffer, ptr, len)) +} - socket - .on('drain', onDrain) - .on('error', onFinished) +function setShouldAutodetect (parser, value) { + this.set_should_autodetect(parser, value) +} - if (body.errorEmitted ?? body.errored) { - setImmediate(() => onFinished(body.errored)) - } else if (body.endEmitted ?? body.readableEnded) { - setImmediate(() => onFinished(null)) - } +function setShouldContinueWithoutData (parser, value) { + this.set_should_continue_without_data(parser, value) +} - if (body.closeEmitted ?? body.closed) { - setImmediate(onClose) - } +function setIsRequest (parser, value) { + this.set_is_request(parser, value) } -function writeBuffer (abort, body, client, request, socket, contentLength, header, expectsPayload) { - try { - if (!body) { - if (contentLength === 0) { - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') - } else { - assert(contentLength === null, 'no body must not have content length') - socket.write(`${header}\r\n`, 'latin1') - } - } else if (util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length') +function setIsConnect (parser, value) { + this.set_is_connect(parser, value) +} - socket.cork() - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - socket.write(body) - socket.uncork() - request.onBodySent(body) +function setDebug (parser, value) { + this.set_debug(parser, value) +} - if (!expectsPayload && request.reset !== false) { - socket[kReset] = true - } - } - request.onRequestSent() +function setShouldManageUnconsumed (parser, value) { + this.set_should_manage_unconsumed(parser, value) +} - client[kResume]() - } catch (err) { - abort(err) - } +function setShouldSuspendAfterHeaders (parser, value) { + this.set_should_suspend_after_headers(parser, value) } -async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) { - assert(contentLength === body.size, 'blob body must have content length') +function setMaxStartLineLength (parser, value) { + this.set_max_start_line_length(parser, value) +} - try { - if (contentLength != null && contentLength !== body.size) { - throw new RequestContentLengthMismatchError() - } +function setMaxHeaderLength (parser, value) { + this.set_max_header_length(parser, value) +} - const buffer = Buffer.from(await body.arrayBuffer()) +function setMaxBodyPayload (parser, value) { + this.set_max_body_payload(parser, value) +} - socket.cork() - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - socket.write(buffer) - socket.uncork() +function setShouldSkipBody (parser, value) { + this.set_should_skip_body(parser, value) +} - request.onBodySent(buffer) - request.onRequestSent() +function setActiveCallbacks (parser, value) { + this.set_active_callbacks(parser, value) +} - if (!expectsPayload && request.reset !== false) { - socket[kReset] = true - } +function setActiveEvents (parser, value) { + this.set_active_events(parser, value) +} - client[kResume]() - } catch (err) { - abort(err) - } +function simpleCreate (spans, create) { + const parser = create() + spans[parser] = [] + this.setActiveCallbacks(parser, this.CALLBACK_ACTIVE_ALL) + return parser } -async function writeIterable (abort, body, client, request, socket, contentLength, header, expectsPayload) { - assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') +function simpleDestroy (spans, destroy, parser) { + spans[parser] = undefined + destroy(parser) +} - let callback = null - function onDrain () { - if (callback) { - const cb = callback - callback = null - cb() +function noop () {} + +function setup (env = {}) { + let { logger: logOption, ...instanceEnvironment } = env + let logger = noop + const context = {} + + if (logOption) { + if (typeof logOption !== 'function') { + logOption = console.log } - } - const waitForDrain = () => new Promise((resolve, reject) => { - assert(callback === null) + logger = log.bind(context, logOption) + } - if (socket[kError]) { - reject(socket[kError]) - } else { - callback = resolve + // Create the WASM instance + /* eslint-disable-next-line no-undef */ + const instance = new WebAssembly.Instance(wasmModule, { + env: { + logger, + on_error: noop, + on_finish: noop, + on_message_start: noop, + on_message_complete: noop, + on_request: noop, + on_response: noop, + on_reset: noop, + on_method: noop, + on_url: noop, + on_protocol: noop, + on_version: noop, + on_status: noop, + on_reason: noop, + on_header_name: noop, + on_header_value: noop, + on_headers: noop, + on_connect: noop, + on_upgrade: noop, + on_chunk_length: noop, + on_chunk_extension_name: noop, + on_chunk_extension_value: noop, + on_chunk: noop, + on_body: noop, + on_data: noop, + on_trailer_name: noop, + on_trailer_value: noop, + on_trailers: noop, + on_state_change: noop, + ...instanceEnvironment } }) - socket - .on('close', onDrain) - .on('drain', onDrain) + const wasm = instance.exports + context.memory = wasm.memory - const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header }) - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } + const milo = { + version: { + raw: '0.9.0', + major: 0, + minor: 9, + patch: 0, + prerelease: '' + }, + METHOD_OTHER: 0, + METHOD_GET: 1, + METHOD_HEAD: 2, + METHOD_POST: 3, + METHOD_PUT: 4, + METHOD_DELETE: 5, + METHOD_CONNECT: 6, + METHOD_OPTIONS: 7, + METHOD_TRACE: 8, + METHOD_PATCH: 9, + METHOD_PRI: 10, + CALLBACK_ON_ERROR: 0, + CALLBACK_ON_FINISH: 1, + CALLBACK_ON_MESSAGE_START: 2, + CALLBACK_ON_MESSAGE_COMPLETE: 3, + CALLBACK_ON_REQUEST: 4, + CALLBACK_ON_RESPONSE: 5, + CALLBACK_ON_RESET: 6, + CALLBACK_ON_METHOD: 7, + CALLBACK_ON_URL: 8, + CALLBACK_ON_PROTOCOL: 9, + CALLBACK_ON_VERSION: 10, + CALLBACK_ON_STATUS: 11, + CALLBACK_ON_REASON: 12, + CALLBACK_ON_HEADER_NAME: 13, + CALLBACK_ON_HEADER_VALUE: 14, + CALLBACK_ON_HEADERS: 15, + CALLBACK_ON_CONNECT: 16, + CALLBACK_ON_UPGRADE: 17, + CALLBACK_ON_CHUNK_LENGTH: 18, + CALLBACK_ON_CHUNK_EXTENSION_NAME: 19, + CALLBACK_ON_CHUNK_EXTENSION_VALUE: 20, + CALLBACK_ON_CHUNK: 21, + CALLBACK_ON_BODY: 22, + CALLBACK_ON_DATA: 23, + CALLBACK_ON_TRAILER_NAME: 24, + CALLBACK_ON_TRAILER_VALUE: 25, + CALLBACK_ON_TRAILERS: 26, + CALLBACK_ON_STATE_CHANGE: 27, + EVENT_END: 0, + EVENT_ERROR: 1, + EVENT_FINISH: 2, + EVENT_MESSAGE_START: 3, + EVENT_MESSAGE_COMPLETE: 4, + EVENT_REQUEST: 5, + EVENT_RESPONSE: 6, + EVENT_RESET: 7, + EVENT_METHOD: 8, + EVENT_URL: 9, + EVENT_PROTOCOL: 10, + EVENT_VERSION: 11, + EVENT_STATUS: 12, + EVENT_REASON: 13, + EVENT_HEADER_NAME: 14, + EVENT_HEADER_VALUE: 15, + EVENT_HEADERS: 16, + EVENT_CONNECT: 17, + EVENT_UPGRADE: 18, + EVENT_CHUNK_LENGTH: 19, + EVENT_CHUNK_EXTENSION_NAME: 20, + EVENT_CHUNK_EXTENSION_VALUE: 21, + EVENT_CHUNK: 22, + EVENT_BODY: 23, + EVENT_DATA: 24, + EVENT_TRAILER_NAME: 25, + EVENT_TRAILER_VALUE: 26, + EVENT_TRAILERS: 27, + EVENT_STATE_CHANGE: 28, + CALLBACK_ACTIVE_NONE: 0n, + EVENT_ACTIVE_NONE: 0n, + CALLBACK_ACTIVE_ON_ERROR: 1n, + EVENT_ACTIVE_ON_ERROR: 1n, + CALLBACK_ACTIVE_ON_FINISH: 2n, + EVENT_ACTIVE_ON_FINISH: 2n, + CALLBACK_ACTIVE_ON_MESSAGE_START: 4n, + EVENT_ACTIVE_ON_MESSAGE_START: 4n, + CALLBACK_ACTIVE_ON_MESSAGE_COMPLETE: 8n, + EVENT_ACTIVE_ON_MESSAGE_COMPLETE: 8n, + CALLBACK_ACTIVE_ON_REQUEST: 16n, + EVENT_ACTIVE_ON_REQUEST: 16n, + CALLBACK_ACTIVE_ON_RESPONSE: 32n, + EVENT_ACTIVE_ON_RESPONSE: 32n, + CALLBACK_ACTIVE_ON_RESET: 64n, + EVENT_ACTIVE_ON_RESET: 64n, + CALLBACK_ACTIVE_ON_METHOD: 128n, + EVENT_ACTIVE_ON_METHOD: 128n, + CALLBACK_ACTIVE_ON_URL: 256n, + EVENT_ACTIVE_ON_URL: 256n, + CALLBACK_ACTIVE_ON_PROTOCOL: 512n, + EVENT_ACTIVE_ON_PROTOCOL: 512n, + CALLBACK_ACTIVE_ON_VERSION: 1024n, + EVENT_ACTIVE_ON_VERSION: 1024n, + CALLBACK_ACTIVE_ON_STATUS: 2048n, + EVENT_ACTIVE_ON_STATUS: 2048n, + CALLBACK_ACTIVE_ON_REASON: 4096n, + EVENT_ACTIVE_ON_REASON: 4096n, + CALLBACK_ACTIVE_ON_HEADER_NAME: 8192n, + EVENT_ACTIVE_ON_HEADER_NAME: 8192n, + CALLBACK_ACTIVE_ON_HEADER_VALUE: 16384n, + EVENT_ACTIVE_ON_HEADER_VALUE: 16384n, + CALLBACK_ACTIVE_ON_HEADERS: 32768n, + EVENT_ACTIVE_ON_HEADERS: 32768n, + CALLBACK_ACTIVE_ON_CONNECT: 65536n, + EVENT_ACTIVE_ON_CONNECT: 65536n, + CALLBACK_ACTIVE_ON_UPGRADE: 131072n, + EVENT_ACTIVE_ON_UPGRADE: 131072n, + CALLBACK_ACTIVE_ON_CHUNK_LENGTH: 262144n, + EVENT_ACTIVE_ON_CHUNK_LENGTH: 262144n, + CALLBACK_ACTIVE_ON_CHUNK_EXTENSION_NAME: 524288n, + EVENT_ACTIVE_ON_CHUNK_EXTENSION_NAME: 524288n, + CALLBACK_ACTIVE_ON_CHUNK_EXTENSION_VALUE: 1048576n, + EVENT_ACTIVE_ON_CHUNK_EXTENSION_VALUE: 1048576n, + CALLBACK_ACTIVE_ON_CHUNK: 2097152n, + EVENT_ACTIVE_ON_CHUNK: 2097152n, + CALLBACK_ACTIVE_ON_BODY: 4194304n, + EVENT_ACTIVE_ON_BODY: 4194304n, + CALLBACK_ACTIVE_ON_DATA: 8388608n, + EVENT_ACTIVE_ON_DATA: 8388608n, + CALLBACK_ACTIVE_ON_TRAILER_NAME: 16777216n, + EVENT_ACTIVE_ON_TRAILER_NAME: 16777216n, + CALLBACK_ACTIVE_ON_TRAILER_VALUE: 33554432n, + EVENT_ACTIVE_ON_TRAILER_VALUE: 33554432n, + CALLBACK_ACTIVE_ON_TRAILERS: 67108864n, + EVENT_ACTIVE_ON_TRAILERS: 67108864n, + CALLBACK_ACTIVE_ON_STATE_CHANGE: 134217728n, + EVENT_ACTIVE_ON_STATE_CHANGE: 134217728n, + CALLBACK_ACTIVE_ALL: 268435455n, + EVENT_ACTIVE_ALL: 268435455n, + ERROR_NONE: 0, + ERROR_USER: 1, + ERROR_CALLBACK_ERROR: 2, + ERROR_UNEXPECTED_STATE: 3, + ERROR_UNEXPECTED_DATA: 4, + ERROR_UNEXPECTED_EOF: 5, + ERROR_UNEXPECTED_CHARACTER: 6, + ERROR_UNEXPECTED_CONTENT_LENGTH: 7, + ERROR_UNEXPECTED_TRANSFER_ENCODING: 8, + ERROR_UNEXPECTED_CONTENT: 9, + ERROR_UNEXPECTED_TRAILERS: 10, + ERROR_INVALID_VERSION: 11, + ERROR_INVALID_STATUS: 12, + ERROR_INVALID_CONTENT_LENGTH: 13, + ERROR_INVALID_TRANSFER_ENCODING: 14, + ERROR_INVALID_CHUNK_SIZE: 15, + ERROR_MISSING_CONNECTION_UPGRADE: 16, + ERROR_UNSUPPORTED_HTTP_VERSION: 17, + STATE_START: 0, + STATE_FINISH: 1, + STATE_ERROR: 2, + STATE_REQUEST_LINE: 3, + STATE_STATUS_LINE: 4, + STATE_HTTP2_PREFACE: 5, + STATE_HEADER: 6, + STATE_BODY_DECISION: 7, + STATE_BODY_VIA_CONTENT_LENGTH: 8, + STATE_BODY_WITH_NO_LENGTH: 9, + STATE_CHUNK_HEADER: 10, + STATE_CHUNK_EXTENSIONS: 11, + STATE_CHUNK_DATA: 12, + STATE_TRAILER: 13, + STATE_TUNNEL: 14, + PARSER_FIELD_MAX_START_LINE_LENGTH: 0, + PARSER_FIELD_MAX_HEADER_LENGTH: 4, + PARSER_FIELD_MAX_BODY_PAYLOAD: 8, + PARSER_FIELD_AUTODETECT: 16, + PARSER_FIELD_IS_REQUEST: 17, + PARSER_FIELD_SUSPEND_AFTER_HEADERS: 18, + PARSER_FIELD_MANAGE_UNCONSUMED: 19, + PARSER_FIELD_CONTINUE_WITHOUT_DATA: 20, + PARSER_FIELD_IS_CONNECT: 21, + PARSER_FIELD_SKIP_BODY: 22, + PARSER_FIELD_DEBUG: 23, + PARSER_FIELD_PARSED: 24, + PARSER_FIELD_POSITION: 32, + PARSER_FIELD_STATE: 36, + PARSER_FIELD_PAUSED: 37, + PARSER_FIELD_ERROR_CODE: 38, + PARSER_FIELD_CONTENT_LENGTH: 40, + PARSER_FIELD_CHUNK_SIZE: 48, + PARSER_FIELD_REMAINING_CONTENT_LENGTH: 56, + PARSER_FIELD_REMAINING_CHUNK_SIZE: 64, + PARSER_FIELD_STATUS: 72, + PARSER_FIELD_METHOD: 76, + PARSER_FIELD_HAS_CONTENT_LENGTH: 77, + PARSER_FIELD_HAS_TRANSFER_ENCODING: 78, + PARSER_FIELD_HAS_CHUNKED_TRANSFER_ENCODING: 79, + PARSER_FIELD_HAS_CONNECTION_CLOSE: 80, + PARSER_FIELD_HAS_CONNECTION_UPGRADE: 81, + PARSER_FIELD_HAS_UPGRADE: 82, + PARSER_FIELD_HAS_TRAILERS: 83, + PARSER_FIELD_ACTIVE_CALLBACKS: 88, + PARSER_FIELD_ACTIVE_EVENTS: 96, + PARSER_FIELD_PTR: 104, + PARSER_FIELD_ERROR_DESCRIPTION: 108, + PARSER_FIELD_UNCONSUMED: 364, + PARSER_FIELD_UNCONSUMED_LEN: 368, + PARSER_FIELD_ERROR_DESCRIPTION_LEN: 372, + PARSER_FIELD_EVENTS: 376, + Errors, + Methods, + Callbacks, + CallbackActives, + Events, + EventActives, + States, + ParserFields, + isAutodetect: isAutodetect.bind(wasm), + isRequest: isRequest.bind(wasm), + isPaused: isPaused.bind(wasm), + shouldManageUnconsumed: shouldManageUnconsumed.bind(wasm), + shouldSuspendAfterHeaders: shouldSuspendAfterHeaders.bind(wasm), + getMaxStartLineLength: getMaxStartLineLength.bind(wasm), + getMaxHeaderLength: getMaxHeaderLength.bind(wasm), + getMaxBodyPayload: getMaxBodyPayload.bind(wasm), + shouldContinueWithoutData: shouldContinueWithoutData.bind(wasm), + isConnect: isConnect.bind(wasm), + isDebug: isDebug.bind(wasm), + shouldSkipBody: shouldSkipBody.bind(wasm), + getState: getState.bind(wasm), + getPosition: getPosition.bind(wasm), + getParsed: getParsed.bind(wasm), + getErrorCode: getErrorCode.bind(wasm), + getMethod: getMethod.bind(wasm), + getStatus: getStatus.bind(wasm), + hasConnectionClose: hasConnectionClose.bind(wasm), + hasConnectionUpgrade: hasConnectionUpgrade.bind(wasm), + getContentLength: getContentLength.bind(wasm), + getChunkSize: getChunkSize.bind(wasm), + getRemainingContentLength: getRemainingContentLength.bind(wasm), + getRemainingChunkSize: getRemainingChunkSize.bind(wasm), + hasContentLength: hasContentLength.bind(wasm), + hasTransferEncoding: hasTransferEncoding.bind(wasm), + hasChunkedTransferEncoding: hasChunkedTransferEncoding.bind(wasm), + hasUpgrade: hasUpgrade.bind(wasm), + hasTrailers: hasTrailers.bind(wasm), + getErrorDescription: getErrorDescription.bind(wasm), + setShouldAutodetect: setShouldAutodetect.bind(wasm), + setShouldContinueWithoutData: setShouldContinueWithoutData.bind(wasm), + setIsRequest: setIsRequest.bind(wasm), + setIsConnect: setIsConnect.bind(wasm), + setDebug: setDebug.bind(wasm), + setShouldManageUnconsumed: setShouldManageUnconsumed.bind(wasm), + setShouldSuspendAfterHeaders: setShouldSuspendAfterHeaders.bind(wasm), + setMaxStartLineLength: setMaxStartLineLength.bind(wasm), + setMaxHeaderLength: setMaxHeaderLength.bind(wasm), + setMaxBodyPayload: setMaxBodyPayload.bind(wasm), + setShouldSkipBody: setShouldSkipBody.bind(wasm), + setActiveCallbacks: setActiveCallbacks.bind(wasm), + setActiveEvents: setActiveEvents.bind(wasm), + memory: wasm.memory, + alloc: alloc.bind(wasm), + dealloc: dealloc.bind(wasm), + create: create.bind(wasm), + destroy: destroy.bind(wasm), + parse: parse.bind(wasm), + fail: fail.bind(wasm), + hasDebug: hasDebug.bind(wasm), + clear: wasm.clear, + complete: wasm.complete, + finish: wasm.finish, + pause: wasm.pause, + reset: wasm.reset, + resume: wasm.resume + } + + return milo +} + +function simple () { + const spans = {} + + const milo = setup({/* REPLACE: callbacks:simple */}) + + milo.spans = spans + milo.create = simpleCreate.bind(milo, spans, milo.create) + milo.destroy = simpleDestroy.bind(milo, spans, milo.destroy) + + return milo +} + +module.exports = { wasmModule, noop, setup, simple } - if (!writer.write(chunk)) { - await waitForDrain() - } + +/***/ }), + +/***/ 7501: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { kClients } = __nccwpck_require__(6443) +const Agent = __nccwpck_require__(7405) +const { + kAgent, + kMockAgentSet, + kMockAgentGet, + kDispatches, + kIsMockActive, + kNetConnect, + kGetNetConnect, + kOptions, + kFactory, + kMockAgentRegisterCallHistory, + kMockAgentIsCallHistoryEnabled, + kMockAgentAddCallHistoryLog, + kMockAgentMockCallHistoryInstance, + kMockAgentAcceptsNonStandardSearchParameters, + kMockCallHistoryAddLog, + kIgnoreTrailingSlash +} = __nccwpck_require__(1117) +const MockClient = __nccwpck_require__(7365) +const MockPool = __nccwpck_require__(4004) +const { matchValue, normalizeSearchParams, buildAndValidateMockOptions, normalizeOrigin } = __nccwpck_require__(3397) +const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8707) +const Dispatcher = __nccwpck_require__(883) +const PendingInterceptorsFormatter = __nccwpck_require__(6142) +const { MockCallHistory } = __nccwpck_require__(431) + +class MockAgent extends Dispatcher { + constructor (opts = {}) { + super(opts) + + const mockOptions = buildAndValidateMockOptions(opts) + + this[kNetConnect] = true + this[kIsMockActive] = true + this[kMockAgentIsCallHistoryEnabled] = mockOptions.enableCallHistory ?? false + this[kMockAgentAcceptsNonStandardSearchParameters] = mockOptions.acceptNonStandardSearchParameters ?? false + this[kIgnoreTrailingSlash] = mockOptions.ignoreTrailingSlash ?? false + + // Instantiate Agent and encapsulate + if (opts?.agent && typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') } + const agent = opts?.agent ? opts.agent : new Agent(opts) + this[kAgent] = agent - writer.end() - } catch (err) { - writer.destroy(err) - } finally { - socket - .off('close', onDrain) - .off('drain', onDrain) + this[kClients] = agent[kClients] + this[kOptions] = mockOptions + + if (this[kMockAgentIsCallHistoryEnabled]) { + this[kMockAgentRegisterCallHistory]() + } } -} -class AsyncWriter { - constructor ({ abort, socket, request, contentLength, client, expectsPayload, header }) { - this.socket = socket - this.request = request - this.contentLength = contentLength - this.client = client - this.bytesWritten = 0 - this.expectsPayload = expectsPayload - this.header = header - this.abort = abort + // WebSocket and EventSource read their receive limits from the dispatcher + // they are given, so report the settings of the agent that makes real + // connections. + get webSocketOptions () { + return this[kAgent].webSocketOptions + } - socket[kWriting] = true + get eventSourceOptions () { + return this[kAgent].eventSourceOptions } - write (chunk) { - const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this + get (origin) { + // Normalize origin to handle URL objects and case-insensitive hostnames + const normalizedOrigin = normalizeOrigin(origin) + const originKey = this[kIgnoreTrailingSlash] ? normalizedOrigin.replace(/\/$/, '') : normalizedOrigin - if (socket[kError]) { - throw socket[kError] - } + let dispatcher = this[kMockAgentGet](originKey) - if (socket.destroyed) { - return false + if (!dispatcher) { + dispatcher = this[kFactory](originKey) + this[kMockAgentSet](originKey, dispatcher) } + return dispatcher + } - const len = Buffer.byteLength(chunk) - if (!len) { - return true - } + dispatch (opts, handler) { + opts.origin = normalizeOrigin(opts.origin) - // We should defer writing chunks. - if (contentLength !== null && bytesWritten + len > contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() + // Call MockAgent.get to perform additional setup before dispatching as normal + const mockDispatcher = this.get(opts.origin) + + this[kMockAgentAddCallHistoryLog](opts) + + const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters] + + const dispatchOpts = { ...opts } + + // Agent keeps HTTP/1.1-only dispatchers under a separate key. Legacy + // global dispatcher consumers use that path, so mirror the mock dispatches + // before delegating to the internal Agent. + if (dispatchOpts.allowH2 === false) { + const http1OnlyKey = `${dispatchOpts.origin}#http1-only` + if (!this[kClients].has(http1OnlyKey)) { + const http1OnlyDispatcher = this[kFactory](dispatchOpts.origin) + http1OnlyDispatcher[kDispatches] = mockDispatcher[kDispatches] + this[kMockAgentSet](http1OnlyKey, http1OnlyDispatcher) } + } - process.emitWarning(new RequestContentLengthMismatchError()) + if (acceptNonStandardSearchParameters && dispatchOpts.path) { + const [path, searchParams] = dispatchOpts.path.split('?') + const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters) + dispatchOpts.path = `${path}?${normalizedSearchParams}` } - socket.cork() + return this[kAgent].dispatch(dispatchOpts, handler) + } - if (bytesWritten === 0) { - if (!expectsPayload && request.reset !== false) { - socket[kReset] = true - } + async close () { + this.clearCallHistory() + await this[kAgent].close() + this[kClients].clear() + } - if (contentLength === null) { - socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') + deactivate () { + this[kIsMockActive] = false + } + + activate () { + this[kIsMockActive] = true + } + + enableNetConnect (matcher) { + if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { + if (Array.isArray(this[kNetConnect])) { + this[kNetConnect].push(matcher) } else { - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + this[kNetConnect] = [matcher] } + } else if (typeof matcher === 'undefined') { + this[kNetConnect] = true + } else { + throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') } + } - if (contentLength === null) { - socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') - } + disableNetConnect () { + this[kNetConnect] = false + } - this.bytesWritten += len + enableCallHistory () { + this[kMockAgentIsCallHistoryEnabled] = true + + return this + } - const ret = socket.write(chunk) + disableCallHistory () { + this[kMockAgentIsCallHistoryEnabled] = false - socket.uncork() + return this + } - request.onBodySent(chunk) + getCallHistory () { + return this[kMockAgentMockCallHistoryInstance] + } - if (!ret) { - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh() - } - } + clearCallHistory () { + if (this[kMockAgentMockCallHistoryInstance] !== undefined) { + this[kMockAgentMockCallHistoryInstance].clear() } + } - return ret + // This is required to bypass issues caused by using global symbols - see: + // https://github.com/nodejs/undici/issues/1447 + get isMockActive () { + return this[kIsMockActive] } - end () { - const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this - request.onRequestSent() + [kMockAgentRegisterCallHistory] () { + if (this[kMockAgentMockCallHistoryInstance] === undefined) { + this[kMockAgentMockCallHistoryInstance] = new MockCallHistory() + } + } - socket[kWriting] = false + [kMockAgentAddCallHistoryLog] (opts) { + if (this[kMockAgentIsCallHistoryEnabled]) { + // additional setup when enableCallHistory class method is used after mockAgent instantiation + this[kMockAgentRegisterCallHistory]() - if (socket[kError]) { - throw socket[kError] + // add call history log on every call (intercepted or not) + this[kMockAgentMockCallHistoryInstance][kMockCallHistoryAddLog](opts) } + } - if (socket.destroyed) { - return - } + [kMockAgentSet] (origin, dispatcher) { + this[kClients].set(origin, dispatcher) + } - if (bytesWritten === 0) { - if (expectsPayload) { - // 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. + [kFactory] (origin) { + const mockOptions = Object.assign({ agent: this }, this[kOptions]) + return this[kOptions] && this[kOptions].connections === 1 + ? new MockClient(origin, mockOptions) + : new MockPool(origin, mockOptions) + } - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') - } else { - socket.write(`${header}\r\n`, 'latin1') - } - } else if (contentLength === null) { - socket.write('\r\n0\r\n\r\n', 'latin1') + [kMockAgentGet] (origin) { + // First check if we can immediately find it + const dispatcher = this[kClients].get(origin) + if (dispatcher) { + return dispatcher } - if (contentLength !== null && bytesWritten !== contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() - } else { - process.emitWarning(new RequestContentLengthMismatchError()) - } + // If the origin is not a string create a dummy parent pool and return to user + if (typeof origin !== 'string') { + const dispatcher = this[kFactory]('http://localhost:9999') + this[kMockAgentSet](origin, dispatcher) + return dispatcher } - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh() + // If we match, create a pool and assign the same dispatches + for (const [keyMatcher, nonExplicitDispatcher] of Array.from(this[kClients])) { + if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { + const dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] + return dispatcher } } + } - client[kResume]() + [kGetNetConnect] () { + return this[kNetConnect] } - destroy (err) { - const { socket, client, abort } = this + pendingInterceptors () { + const mockAgentClients = this[kClients] - socket[kWriting] = false + return Array.from(mockAgentClients.entries()) + .flatMap(([origin, dispatcher]) => dispatcher[kDispatches].map(dispatch => ({ ...dispatch, origin }))) + .filter(({ pending }) => pending) + } - if (err) { - assert(client[kRunning] <= 1, 'pipeline should only contain this request') - abort(err) + assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { + const pending = this.pendingInterceptors() + + if (pending.length === 0) { + return } + + throw new UndiciError( + pending.length === 1 + ? `1 interceptor is pending:\n\n${pendingInterceptorsFormatter.format(pending)}`.trim() + : `${pending.length} interceptors are pending:\n\n${pendingInterceptorsFormatter.format(pending)}`.trim() + ) } } -module.exports = connectH1 +module.exports = MockAgent /***/ }), -/***/ 8788: +/***/ 431: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const assert = __nccwpck_require__(4589) -const { pipeline } = __nccwpck_require__(7075) -const util = __nccwpck_require__(3440) -const { - RequestContentLengthMismatchError, - RequestAbortedError, - SocketError, - InformationalError -} = __nccwpck_require__(8707) -const { - kUrl, - kReset, - kClient, - kRunning, - kPending, - kQueue, - kPendingIdx, - kRunningIdx, - kError, - kSocket, - kStrictContentLength, - kOnError, - kMaxConcurrentStreams, - kHTTP2Session, - kResume, - kSize, - kHTTPContext -} = __nccwpck_require__(6443) - -const kOpenStreams = Symbol('open streams') - -let extractBody +const { kMockCallHistoryAddLog } = __nccwpck_require__(1117) +const { InvalidArgumentError } = __nccwpck_require__(8707) -// Experimental -let h2ExperimentalWarned = false +function handleFilterCallsWithOptions (criteria, options, handler, store, allLogs) { + switch (options.operator) { + case 'OR': + store.push(...handler(criteria, allLogs)) -/** @type {import('http2')} */ -let http2 -try { - http2 = __nccwpck_require__(2467) -} catch { - // @ts-ignore - http2 = { constants: {} } + return store + case 'AND': + return handler(criteria, store) + default: + // guard -- should never happens because buildAndValidateFilterCallsOptions is called before + throw new InvalidArgumentError('options.operator must to be a case insensitive string equal to \'OR\' or \'AND\'') + } } -const { - constants: { - HTTP2_HEADER_AUTHORITY, - HTTP2_HEADER_METHOD, - HTTP2_HEADER_PATH, - HTTP2_HEADER_SCHEME, - HTTP2_HEADER_CONTENT_LENGTH, - HTTP2_HEADER_EXPECT, - HTTP2_HEADER_STATUS - } -} = http2 +function buildAndValidateFilterCallsOptions (options = {}) { + const finalOptions = {} -function parseH2Headers (headers) { - const result = [] + if ('operator' in options) { + if (typeof options.operator !== 'string' || (options.operator.toUpperCase() !== 'OR' && options.operator.toUpperCase() !== 'AND')) { + throw new InvalidArgumentError('options.operator must to be a case insensitive string equal to \'OR\' or \'AND\'') + } - for (const [name, value] of Object.entries(headers)) { - // h2 may concat the header value by array - // e.g. Set-Cookie - if (Array.isArray(value)) { - for (const subvalue of value) { - // we need to provide each header value of header name - // because the headers handler expect name-value pair - result.push(Buffer.from(name), Buffer.from(subvalue)) - } - } else { - result.push(Buffer.from(name), Buffer.from(value)) + return { + ...finalOptions, + operator: options.operator.toUpperCase() } } - return result + return finalOptions } -async function connectH2 (client, socket) { - client[kSocket] = socket +function makeFilterCalls (parameterName) { + return (parameterValue, logs = this.logs) => { + if (typeof parameterValue === 'string' || parameterValue == null) { + return logs.filter((log) => { + return log[parameterName] === parameterValue + }) + } + if (parameterValue instanceof RegExp) { + return logs.filter((log) => { + return parameterValue.test(log[parameterName]) + }) + } - if (!h2ExperimentalWarned) { - h2ExperimentalWarned = true - process.emitWarning('H2 support is experimental, expect them to change at any time.', { - code: 'UNDICI-H2' - }) + throw new InvalidArgumentError(`${parameterName} parameter should be one of string, regexp, undefined or null`) } +} +function computeUrlWithMaybeSearchParameters (requestInit) { + // path can contains query url parameters + // or query can contains query url parameters + try { + const url = new URL(requestInit.path, requestInit.origin) - const session = http2.connect(client[kUrl], { - createConnection: () => socket, - peerMaxConcurrentStreams: client[kMaxConcurrentStreams] - }) + // requestInit.path contains query url parameters + // requestInit.query is then undefined + if (url.search.length !== 0) { + return url + } - session[kOpenStreams] = 0 - session[kClient] = client - session[kSocket] = socket + // requestInit.query can be populated here + url.search = new URLSearchParams(requestInit.query).toString() - util.addListener(session, 'error', onHttp2SessionError) - util.addListener(session, 'frameError', onHttp2FrameError) - util.addListener(session, 'end', onHttp2SessionEnd) - util.addListener(session, 'goaway', onHTTP2GoAway) - util.addListener(session, 'close', function () { - const { [kClient]: client } = this - const { [kSocket]: socket } = client + return url + } catch (error) { + throw new InvalidArgumentError('An error occurred when computing MockCallHistoryLog.url', { cause: error }) + } +} + +class MockCallHistoryLog { + constructor (requestInit = {}) { + this.body = requestInit.body + this.headers = requestInit.headers + this.method = requestInit.method + + const url = computeUrlWithMaybeSearchParameters(requestInit) + + this.fullUrl = url.toString() + this.origin = url.origin + this.path = url.pathname + this.searchParams = Object.fromEntries(url.searchParams) + this.protocol = url.protocol + this.host = url.host + this.port = url.port + this.hash = url.hash + } + + toMap () { + return new Map([ + ['protocol', this.protocol], + ['host', this.host], + ['port', this.port], + ['origin', this.origin], + ['path', this.path], + ['hash', this.hash], + ['searchParams', this.searchParams], + ['fullUrl', this.fullUrl], + ['method', this.method], + ['body', this.body], + ['headers', this.headers]] + ) + } - const err = this[kSocket][kError] || this[kError] || new SocketError('closed', util.getSocketInfo(socket)) + toString () { + const options = { betweenKeyValueSeparator: '->', betweenPairSeparator: '|' } + let result = '' - client[kHTTP2Session] = null + this.toMap().forEach((value, key) => { + if (typeof value === 'string' || value === undefined || value === null) { + result = `${result}${key}${options.betweenKeyValueSeparator}${value}${options.betweenPairSeparator}` + } + if ((typeof value === 'object' && value !== null) || Array.isArray(value)) { + result = `${result}${key}${options.betweenKeyValueSeparator}${JSON.stringify(value)}${options.betweenPairSeparator}` + } + // maybe miss something for non Record / Array headers and searchParams here + }) - if (client.destroyed) { - assert(client[kPending] === 0) + // delete last betweenPairSeparator + return result.slice(0, -1) + } +} - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - util.errorRequest(client, request, err) - } - } - }) +class MockCallHistory { + logs = [] - session.unref() + calls () { + return this.logs + } - client[kHTTP2Session] = session - socket[kHTTP2Session] = session + firstCall () { + return this.logs.at(0) + } - util.addListener(socket, 'error', function (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + lastCall () { + return this.logs.at(-1) + } - this[kError] = err + nthCall (number) { + if (typeof number !== 'number') { + throw new InvalidArgumentError('nthCall must be called with a number') + } + if (!Number.isInteger(number)) { + throw new InvalidArgumentError('nthCall must be called with an integer') + } + if (Math.sign(number) !== 1) { + throw new InvalidArgumentError('nthCall must be called with a positive value. use firstCall or lastCall instead') + } - this[kClient][kOnError](err) - }) + // non zero based index. this is more human readable + return this.logs.at(number - 1) + } - util.addListener(socket, 'end', function () { - util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) - }) + filterCalls (criteria, options) { + // perf + if (this.logs.length === 0) { + return this.logs + } + if (typeof criteria === 'function') { + return this.logs.filter(criteria) + } + if (criteria instanceof RegExp) { + return this.logs.filter((log) => { + return criteria.test(log.toString()) + }) + } + if (typeof criteria === 'object' && criteria !== null) { + // no criteria - returning all logs + if (Object.keys(criteria).length === 0) { + return this.logs + } - util.addListener(socket, 'close', function () { - const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) + const finalOptions = { operator: 'OR', ...buildAndValidateFilterCallsOptions(options) } - client[kSocket] = null + let maybeDuplicatedLogsFiltered = finalOptions.operator === 'AND' ? this.logs : [] + if ('protocol' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.protocol, finalOptions, this.filterCallsByProtocol, maybeDuplicatedLogsFiltered, this.logs) + } + if ('host' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.host, finalOptions, this.filterCallsByHost, maybeDuplicatedLogsFiltered, this.logs) + } + if ('port' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.port, finalOptions, this.filterCallsByPort, maybeDuplicatedLogsFiltered, this.logs) + } + if ('origin' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.origin, finalOptions, this.filterCallsByOrigin, maybeDuplicatedLogsFiltered, this.logs) + } + if ('path' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.path, finalOptions, this.filterCallsByPath, maybeDuplicatedLogsFiltered, this.logs) + } + if ('hash' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.hash, finalOptions, this.filterCallsByHash, maybeDuplicatedLogsFiltered, this.logs) + } + if ('fullUrl' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.fullUrl, finalOptions, this.filterCallsByFullUrl, maybeDuplicatedLogsFiltered, this.logs) + } + if ('method' in criteria) { + maybeDuplicatedLogsFiltered = handleFilterCallsWithOptions(criteria.method, finalOptions, this.filterCallsByMethod, maybeDuplicatedLogsFiltered, this.logs) + } + + const uniqLogsFiltered = [...new Set(maybeDuplicatedLogsFiltered)] - if (this[kHTTP2Session] != null) { - this[kHTTP2Session].destroy(err) + return uniqLogsFiltered } - client[kPendingIdx] = client[kRunningIdx] + throw new InvalidArgumentError('criteria parameter should be one of function, regexp, or object') + } - assert(client[kRunning] === 0) + filterCallsByProtocol = makeFilterCalls.call(this, 'protocol') - client.emit('disconnect', client[kUrl], [client], err) + filterCallsByHost = makeFilterCalls.call(this, 'host') - client[kResume]() - }) + filterCallsByPort = makeFilterCalls.call(this, 'port') - let closed = false - socket.on('close', () => { - closed = true - }) + filterCallsByOrigin = makeFilterCalls.call(this, 'origin') - return { - version: 'h2', - defaultPipelining: Infinity, - write (...args) { - return writeH2(client, ...args) - }, - resume () { - resumeH2(client) - }, - destroy (err, callback) { - if (closed) { - queueMicrotask(callback) - } else { - // Destroying the socket will trigger the session close - socket.destroy(err).on('close', callback) - } - }, - get destroyed () { - return socket.destroyed - }, - busy () { - return false - } - } -} + filterCallsByPath = makeFilterCalls.call(this, 'path') -function resumeH2 (client) { - const socket = client[kSocket] + filterCallsByHash = makeFilterCalls.call(this, 'hash') - if (socket?.destroyed === false) { - if (client[kSize] === 0 && client[kMaxConcurrentStreams] === 0) { - socket.unref() - client[kHTTP2Session].unref() - } else { - socket.ref() - client[kHTTP2Session].ref() - } + filterCallsByFullUrl = makeFilterCalls.call(this, 'fullUrl') + + filterCallsByMethod = makeFilterCalls.call(this, 'method') + + clear () { + this.logs = [] } -} -function onHttp2SessionError (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + [kMockCallHistoryAddLog] (requestInit) { + const log = new MockCallHistoryLog(requestInit) + + this.logs.push(log) - this[kSocket][kError] = err - this[kClient][kOnError](err) -} + return log + } -function onHttp2FrameError (type, code, id) { - if (id === 0) { - const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) - this[kSocket][kError] = err - this[kClient][kOnError](err) + * [Symbol.iterator] () { + for (const log of this.calls()) { + yield log + } } } -function onHttp2SessionEnd () { - const err = new SocketError('other side closed', util.getSocketInfo(this[kSocket])) - this.destroy(err) - util.destroy(this[kSocket], err) -} +module.exports.MockCallHistory = MockCallHistory +module.exports.MockCallHistoryLog = MockCallHistoryLog -/** - * This is the root cause of #3011 - * We need to handle GOAWAY frames properly, and trigger the session close - * along with the socket right away - */ -function onHTTP2GoAway (code) { - // We cannot recover, so best to close the session and the socket - const err = this[kError] || new SocketError(`HTTP/2: "GOAWAY" frame received with code ${code}`, util.getSocketInfo(this)) - const client = this[kClient] - client[kSocket] = null - client[kHTTPContext] = null +/***/ }), - if (this[kHTTP2Session] != null) { - this[kHTTP2Session].destroy(err) - this[kHTTP2Session] = null - } +/***/ 7365: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - util.destroy(this[kSocket], err) +"use strict"; - // Fail head of pipeline. - if (client[kRunningIdx] < client[kQueue].length) { - const request = client[kQueue][client[kRunningIdx]] - client[kQueue][client[kRunningIdx]++] = null - util.errorRequest(client, request, err) - client[kPendingIdx] = client[kRunningIdx] - } - assert(client[kRunning] === 0) +const { promisify } = __nccwpck_require__(7975) +const Client = __nccwpck_require__(3701) +const { buildMockDispatch } = __nccwpck_require__(3397) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected, + kIgnoreTrailingSlash +} = __nccwpck_require__(1117) +const { MockInterceptor } = __nccwpck_require__(1511) +const Symbols = __nccwpck_require__(6443) +const { InvalidArgumentError } = __nccwpck_require__(8707) - client.emit('disconnect', client[kUrl], [client], err) +/** + * MockClient provides an API that extends the Client to influence the mockDispatches. + */ +class MockClient extends Client { + constructor (origin, opts) { + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } - client[kResume]() -} + super(origin, opts) -// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 -function shouldSendContentLength (method) { - return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' -} + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kIgnoreTrailingSlash] = opts.ignoreTrailingSlash ?? false + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) -function writeH2 (client, request) { - const session = client[kHTTP2Session] - const { method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request - let { body } = request + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] + } - if (upgrade) { - util.errorRequest(client, request, new Error('Upgrade not supported for H2')) - return false + get [Symbols.kConnected] () { + return this[kConnected] } - const headers = {} - for (let n = 0; n < reqHeaders.length; n += 2) { - const key = reqHeaders[n + 0] - const val = reqHeaders[n + 1] + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor( + opts && { ignoreTrailingSlash: this[kIgnoreTrailingSlash], ...opts }, + this[kDispatches] + ) + } - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - if (headers[key]) { - headers[key] += `,${val[i]}` - } else { - headers[key] = val[i] - } - } - } else { - headers[key] = val - } + cleanMocks () { + this[kDispatches] = [] } - /** @type {import('node:http2').ClientHttp2Stream} */ - let stream + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } +} - const { hostname, port } = client[kUrl] +module.exports = MockClient - headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ''}` - headers[HTTP2_HEADER_METHOD] = method - const abort = (err) => { - if (request.aborted || request.completed) { - return - } +/***/ }), - err = err || new RequestAbortedError() +/***/ 2429: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - util.errorRequest(client, request, err) +"use strict"; - if (stream != null) { - util.destroy(stream, err) - } - // We do not destroy the socket as we can continue using the session - // the stream get's destroyed and the session remains to create new streams - util.destroy(body, err) - client[kQueue][client[kRunningIdx]++] = null - client[kResume]() +const { UndiciError } = __nccwpck_require__(8707) + +const kMockNotMatchedError = Symbol.for('undici.error.UND_MOCK_ERR_MOCK_NOT_MATCHED') + +/** + * The request does not match any registered mock dispatches. + */ +class MockNotMatchedError extends UndiciError { + constructor (message) { + super(message) + this.name = 'MockNotMatchedError' + this.message = message || 'The request does not match any registered mock dispatches' + this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' } - try { - // We are already connected, streams are pending. - // We can call on connect, and wait for abort - request.onConnect(abort) - } catch (err) { - util.errorRequest(client, request, err) + static [Symbol.hasInstance] (instance) { + return instance && instance[kMockNotMatchedError] === true } - if (request.aborted) { - return false + get [kMockNotMatchedError] () { + return true } +} - if (method === 'CONNECT') { - session.ref() - // We are already connected, streams are pending, first request - // will create a new stream. We trigger a request to create the stream and wait until - // `ready` event is triggered - // We disabled endStream to allow the user to write to the stream - stream = session.request(headers, { endStream: false, signal }) +module.exports = { + MockNotMatchedError +} - if (stream.id && !stream.pending) { - request.onUpgrade(null, null, stream) - ++session[kOpenStreams] - client[kQueue][client[kRunningIdx]++] = null - } else { - stream.once('ready', () => { - request.onUpgrade(null, null, stream) - ++session[kOpenStreams] - client[kQueue][client[kRunningIdx]++] = null - }) - } - stream.once('close', () => { - session[kOpenStreams] -= 1 - if (session[kOpenStreams] === 0) session.unref() - }) +/***/ }), - return true - } +/***/ 1511: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // https://tools.ietf.org/html/rfc7540#section-8.3 - // :path and :scheme headers must be omitted when sending CONNECT +"use strict"; - headers[HTTP2_HEADER_PATH] = path - headers[HTTP2_HEADER_SCHEME] = 'https' - // https://tools.ietf.org/html/rfc7231#section-4.3.1 - // https://tools.ietf.org/html/rfc7231#section-4.3.2 - // https://tools.ietf.org/html/rfc7231#section-4.3.5 +const { getResponseData, buildKey, addMockDispatch } = __nccwpck_require__(3397) +const { + kDispatches, + kDispatchKey, + kDefaultHeaders, + kDefaultTrailers, + kContentLength, + kMockDispatch, + kIgnoreTrailingSlash +} = __nccwpck_require__(1117) +const { InvalidArgumentError } = __nccwpck_require__(8707) +const { serializePathWithQuery } = __nccwpck_require__(3440) +const { + types: { + isPromise + } +} = __nccwpck_require__(7975) - // Sending a payload body on a request that does not - // expect it can cause undefined behavior on some - // servers and corrupt connection state. Do not - // re-use the connection for further requests. +/** + * Defines the scope API for an interceptor reply + */ +class MockScope { + constructor (mockDispatch) { + this[kMockDispatch] = mockDispatch + } - const expectsPayload = ( - method === 'PUT' || - method === 'POST' || - method === 'PATCH' - ) + /** + * Delay a reply by a set amount in ms. + */ + delay (waitInMs) { + if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { + throw new InvalidArgumentError('waitInMs must be a valid integer > 0') + } - if (body && typeof body.read === 'function') { - // Try to read EOF in order to get length. - body.read(0) + this[kMockDispatch].delay = waitInMs + return this } - let contentLength = util.bodyLength(body) - - if (util.isFormDataLike(body)) { - extractBody ??= (__nccwpck_require__(4492).extractBody) + /** + * For a defined reply, never mark as consumed. + */ + persist () { + this[kMockDispatch].persist = true + return this + } - const [bodyStream, contentType] = extractBody(body) - headers['content-type'] = contentType + /** + * Allow one to define a reply for a set amount of matching requests. + */ + times (repeatTimes) { + if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { + throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') + } - body = bodyStream.stream - contentLength = bodyStream.length + this[kMockDispatch].times = repeatTimes + return this } +} + +/** + * Defines an interceptor for a Mock + */ +class MockInterceptor { + constructor (opts, mockDispatches) { + if (typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object') + } + if (typeof opts.path === 'undefined') { + throw new InvalidArgumentError('opts.path must be defined') + } + if (typeof opts.method === 'undefined') { + opts.method = 'GET' + } + // See https://github.com/nodejs/undici/issues/1245 + // As per RFC 3986, clients are not supposed to send URI + // fragments to servers when they retrieve a document, + if (typeof opts.path === 'string') { + if (opts.query) { + opts.path = serializePathWithQuery(opts.path, opts.query) + } else { + // Matches https://github.com/nodejs/undici/blob/main/lib/web/fetch/index.js#L1811 + const parsedURL = new URL(opts.path, 'data://') + opts.path = parsedURL.pathname + parsedURL.search + } + } + if (typeof opts.method === 'string') { + opts.method = opts.method.toUpperCase() + } - if (contentLength == null) { - contentLength = request.contentLength + this[kDispatchKey] = buildKey(opts) + this[kDispatches] = mockDispatches + this[kIgnoreTrailingSlash] = opts.ignoreTrailingSlash ?? false + this[kDefaultHeaders] = {} + this[kDefaultTrailers] = {} + this[kContentLength] = false } - if (contentLength === 0 || !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // 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. + createMockScopeDispatchData ({ statusCode, data, responseOptions }) { + const responseData = getResponseData(data) + const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {} + const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers } + const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers } - contentLength = null + return { statusCode, data, headers, trailers } } - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - util.errorRequest(client, request, new RequestContentLengthMismatchError()) - return false + validateReplyParameters (replyParameters) { + if (typeof replyParameters.statusCode === 'undefined') { + throw new InvalidArgumentError('statusCode must be defined') + } + if (typeof replyParameters.responseOptions !== 'object' || replyParameters.responseOptions === null) { + throw new InvalidArgumentError('responseOptions must be an object') } - - process.emitWarning(new RequestContentLengthMismatchError()) - } - - if (contentLength != null) { - assert(body, 'no body must not have content length') - headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` - } - - session.ref() - - const shouldEndStream = method === 'GET' || method === 'HEAD' || body === null - if (expectContinue) { - headers[HTTP2_HEADER_EXPECT] = '100-continue' - stream = session.request(headers, { endStream: shouldEndStream, signal }) - - stream.once('continue', writeBodyH2) - } else { - stream = session.request(headers, { - endStream: shouldEndStream, - signal - }) - writeBodyH2() } - // Increment counter as we have new streams open - ++session[kOpenStreams] + /** + * Mock an undici request with a defined reply. + */ + reply (replyOptionsCallbackOrStatusCode) { + // Values of reply aren't available right now as they + // can only be available when the reply callback is invoked. + if (typeof replyOptionsCallbackOrStatusCode === 'function') { + // Resolves the data returned by a reply options callback into + // dispatch data, validating its format along the way. + const resolveReplyCallbackData = (resolvedData) => { + // Check if it is in the right format + if (typeof resolvedData !== 'object' || resolvedData === null) { + throw new InvalidArgumentError('reply options callback must return an object') + } - stream.once('response', headers => { - const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers - request.onResponseStarted() + const replyParameters = { data: '', responseOptions: {}, ...resolvedData } + this.validateReplyParameters(replyParameters) + // Since the values can be obtained immediately we return them + // from this higher order function that will be resolved later. + return { + ...this.createMockScopeDispatchData(replyParameters) + } + } - // Due to the stream nature, it is possible we face a race condition - // where the stream has been assigned, but the request has been aborted - // the request remains in-flight and headers hasn't been received yet - // for those scenarios, best effort is to destroy the stream immediately - // as there's no value to keep it open. - if (request.aborted) { - const err = new RequestAbortedError() - util.errorRequest(client, request, err) - util.destroy(stream, err) - return - } + // We'll first wrap the provided callback in another function, + // this function will properly resolve the data from the callback + // when invoked. + const wrappedDefaultsCallback = (opts) => { + // Our reply options callback contains the parameter for statusCode, data and options. + const resolvedData = replyOptionsCallbackOrStatusCode(opts) - if (request.onHeaders(Number(statusCode), parseH2Headers(realHeaders), stream.resume.bind(stream), '') === false) { - stream.pause() - } + // An asynchronous reply options callback resolves to the reply + // parameters, so the dispatch data can only be resolved once the + // returned promise settles. + if (isPromise(resolvedData)) { + return resolvedData.then(resolveReplyCallbackData) + } - stream.on('data', (chunk) => { - if (request.onData(chunk) === false) { - stream.pause() + return resolveReplyCallbackData(resolvedData) } - }) - }) - stream.once('end', () => { - // When state is null, it means we haven't consumed body and the stream still do not have - // a state. - // Present specially when using pipeline or stream - if (stream.state?.state == null || stream.state.state < 6) { - request.onComplete([]) + // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback, { ignoreTrailingSlash: this[kIgnoreTrailingSlash] }) + return new MockScope(newMockDispatch) } - if (session[kOpenStreams] === 0) { - // Stream is closed or half-closed-remote (6), decrement counter and cleanup - // It does not have sense to continue working with the stream as we do not - // have yet RST_STREAM support on client-side - - session.unref() + // We can have either one or three parameters, if we get here, + // we should have 1-3 parameters. So we spread the arguments of + // this function to obtain the parameters, since replyData will always + // just be the statusCode. + const replyParameters = { + statusCode: replyOptionsCallbackOrStatusCode, + data: arguments[1] === undefined ? '' : arguments[1], + responseOptions: arguments[2] === undefined ? {} : arguments[2] } + this.validateReplyParameters(replyParameters) - abort(new InformationalError('HTTP/2: stream half-closed (remote)')) - client[kQueue][client[kRunningIdx]++] = null - client[kPendingIdx] = client[kRunningIdx] - client[kResume]() - }) + // Send in-already provided data like usual + const dispatchData = this.createMockScopeDispatchData(replyParameters) + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData, { ignoreTrailingSlash: this[kIgnoreTrailingSlash] }) + return new MockScope(newMockDispatch) + } - stream.once('close', () => { - session[kOpenStreams] -= 1 - if (session[kOpenStreams] === 0) { - session.unref() + /** + * Mock an undici request with a defined error. + */ + replyWithError (error) { + if (typeof error === 'undefined') { + throw new InvalidArgumentError('error must be defined') } - }) - stream.once('error', function (err) { - abort(err) - }) - - stream.once('frameError', (type, code) => { - abort(new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`)) - }) - - // stream.on('aborted', () => { - // // TODO(HTTP/2): Support aborted - // }) - - // stream.on('timeout', () => { - // // TODO(HTTP/2): Support timeout - // }) - - // stream.on('push', headers => { - // // TODO(HTTP/2): Support push - // }) - - // stream.on('trailers', headers => { - // // TODO(HTTP/2): Support trailers - // }) - - return true + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }, { ignoreTrailingSlash: this[kIgnoreTrailingSlash] }) + return new MockScope(newMockDispatch) + } - function writeBodyH2 () { - /* istanbul ignore else: assertion */ - if (!body || contentLength === 0) { - writeBuffer( - abort, - stream, - null, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ) - } else if (util.isBuffer(body)) { - writeBuffer( - abort, - stream, - body, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ) - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable( - abort, - stream, - body.stream(), - client, - request, - client[kSocket], - contentLength, - expectsPayload - ) - } else { - writeBlob( - abort, - stream, - body, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ) - } - } else if (util.isStream(body)) { - writeStream( - abort, - client[kSocket], - expectsPayload, - stream, - body, - client, - request, - contentLength - ) - } else if (util.isIterable(body)) { - writeIterable( - abort, - stream, - body, - client, - request, - client[kSocket], - contentLength, - expectsPayload - ) - } else { - assert(false) + /** + * Set default reply headers on the interceptor for subsequent replies + */ + defaultReplyHeaders (headers) { + if (typeof headers === 'undefined') { + throw new InvalidArgumentError('headers must be defined') } - } -} -function writeBuffer (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { - try { - if (body != null && util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length') - h2stream.cork() - h2stream.write(body) - h2stream.uncork() - h2stream.end() + this[kDefaultHeaders] = headers + return this + } - request.onBodySent(body) + /** + * Set default reply trailers on the interceptor for subsequent replies + */ + defaultReplyTrailers (trailers) { + if (typeof trailers === 'undefined') { + throw new InvalidArgumentError('trailers must be defined') } - if (!expectsPayload) { - socket[kReset] = true - } + this[kDefaultTrailers] = trailers + return this + } - request.onRequestSent() - client[kResume]() - } catch (error) { - abort(error) + /** + * Set reply content length header for replies on the interceptor + */ + replyContentLength () { + this[kContentLength] = true + return this } } -function writeStream (abort, socket, expectsPayload, h2stream, body, client, request, contentLength) { - assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') +module.exports.MockInterceptor = MockInterceptor +module.exports.MockScope = MockScope - // For HTTP/2, is enough to pipe the stream - const pipe = pipeline( - body, - h2stream, - (err) => { - if (err) { - util.destroy(pipe, err) - abort(err) - } else { - util.removeAllListeners(pipe) - request.onRequestSent() - if (!expectsPayload) { - socket[kReset] = true - } +/***/ }), - client[kResume]() - } - } - ) +/***/ 4004: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - util.addListener(pipe, 'data', onPipeData) +"use strict"; - function onPipeData (chunk) { - request.onBodySent(chunk) - } -} -async function writeBlob (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { - assert(contentLength === body.size, 'blob body must have content length') +const { promisify } = __nccwpck_require__(7975) +const Pool = __nccwpck_require__(628) +const { buildMockDispatch } = __nccwpck_require__(3397) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected, + kIgnoreTrailingSlash +} = __nccwpck_require__(1117) +const { MockInterceptor } = __nccwpck_require__(1511) +const Symbols = __nccwpck_require__(6443) +const { InvalidArgumentError } = __nccwpck_require__(8707) - try { - if (contentLength != null && contentLength !== body.size) { - throw new RequestContentLengthMismatchError() +/** + * MockPool provides an API that extends the Pool to influence the mockDispatches. + */ +class MockPool extends Pool { + constructor (origin, opts) { + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') } - const buffer = Buffer.from(await body.arrayBuffer()) - - h2stream.cork() - h2stream.write(buffer) - h2stream.uncork() - h2stream.end() - - request.onBodySent(buffer) - request.onRequestSent() + super(origin, opts) - if (!expectsPayload) { - socket[kReset] = true - } + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kIgnoreTrailingSlash] = opts.ignoreTrailingSlash ?? false + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) - client[kResume]() - } catch (err) { - abort(err) + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] } -} -async function writeIterable (abort, h2stream, body, client, request, socket, contentLength, expectsPayload) { - assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') + get [Symbols.kConnected] () { + return this[kConnected] + } - let callback = null - function onDrain () { - if (callback) { - const cb = callback - callback = null - cb() - } + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor( + opts && { ignoreTrailingSlash: this[kIgnoreTrailingSlash], ...opts }, + this[kDispatches] + ) } - const waitForDrain = () => new Promise((resolve, reject) => { - assert(callback === null) + cleanMocks () { + this[kDispatches] = [] + } - if (socket[kError]) { - reject(socket[kError]) - } else { - callback = resolve - } - }) + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } +} - h2stream - .on('close', onDrain) - .on('drain', onDrain) +module.exports = MockPool - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } - const res = h2stream.write(chunk) - request.onBodySent(chunk) - if (!res) { - await waitForDrain() - } - } +/***/ }), - h2stream.end() +/***/ 1117: +/***/ ((module) => { - request.onRequestSent() +"use strict"; - if (!expectsPayload) { - socket[kReset] = true - } - client[kResume]() - } catch (err) { - abort(err) - } finally { - h2stream - .off('close', onDrain) - .off('drain', onDrain) - } +module.exports = { + kAgent: Symbol('agent'), + kOptions: Symbol('options'), + kFactory: Symbol('factory'), + kDispatches: Symbol('dispatches'), + kDispatchKey: Symbol('dispatch key'), + kDefaultHeaders: Symbol('default headers'), + kDefaultTrailers: Symbol('default trailers'), + kContentLength: Symbol('content length'), + kMockAgent: Symbol('mock agent'), + kMockAgentSet: Symbol('mock agent set'), + kMockAgentGet: Symbol('mock agent get'), + kMockDispatch: Symbol('mock dispatch'), + kClose: Symbol('close'), + kOriginalClose: Symbol('original agent close'), + kOriginalDispatch: Symbol('original dispatch'), + kOrigin: Symbol('origin'), + kIsMockActive: Symbol('is mock active'), + kNetConnect: Symbol('net connect'), + kGetNetConnect: Symbol('get net connect'), + kConnected: Symbol('connected'), + kIgnoreTrailingSlash: Symbol('ignore trailing slash'), + kMockAgentMockCallHistoryInstance: Symbol('mock agent mock call history name'), + kMockAgentRegisterCallHistory: Symbol('mock agent register mock call history'), + kMockAgentAddCallHistoryLog: Symbol('mock agent add call history log'), + kMockAgentIsCallHistoryEnabled: Symbol('mock agent is call history enabled'), + kMockAgentAcceptsNonStandardSearchParameters: Symbol('mock agent accepts non standard search parameters'), + kMockCallHistoryAddLog: Symbol('mock call history add log'), + kTotalDispatchCount: Symbol('total dispatch count') } -module.exports = connectH2 - /***/ }), -/***/ 3701: +/***/ 3397: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check - -const assert = __nccwpck_require__(4589) -const net = __nccwpck_require__(7030) -const http = __nccwpck_require__(7067) -const util = __nccwpck_require__(3440) -const { channels } = __nccwpck_require__(2414) -const Request = __nccwpck_require__(4655) -const DispatcherBase = __nccwpck_require__(1841) +const { MockNotMatchedError } = __nccwpck_require__(2429) const { - InvalidArgumentError, - InformationalError, - ClientDestroyedError -} = __nccwpck_require__(8707) -const buildConnector = __nccwpck_require__(9136) + kDispatches, + kMockAgent, + kOriginalDispatch, + kOrigin, + kGetNetConnect, + kTotalDispatchCount +} = __nccwpck_require__(1117) +const { serializePathWithQuery, parseHeaders } = __nccwpck_require__(3440) +const { STATUS_CODES } = __nccwpck_require__(7067) const { - kUrl, - kServerName, - kClient, - kBusy, - kConnect, - kResuming, - kRunning, - kPending, - kSize, - kQueue, - kConnected, - kConnecting, - kNeedDrain, - kKeepAliveDefaultTimeout, - kHostHeader, - kPendingIdx, - kRunningIdx, - kError, - kPipelining, - kKeepAliveTimeoutValue, - kMaxHeadersSize, - kKeepAliveMaxTimeout, - kKeepAliveTimeoutThreshold, - kHeadersTimeout, - kBodyTimeout, - kStrictContentLength, - kConnector, - kMaxRedirections, - kMaxRequests, - kCounter, - kClose, - kDestroy, - kDispatch, - kInterceptors, - kLocalAddress, - kMaxResponseSize, - kOnError, - kHTTPContext, - kMaxConcurrentStreams, - kResume -} = __nccwpck_require__(6443) -const connectH1 = __nccwpck_require__(637) -const connectH2 = __nccwpck_require__(8788) -let deprecatedInterceptorWarned = false - -const kClosedResolve = Symbol('kClosedResolve') - -const noop = () => {} + types: { + isPromise + } +} = __nccwpck_require__(7975) +const { InvalidArgumentError } = __nccwpck_require__(8707) +const requestAborted = Symbol('request aborted') -function getPipelining (client) { - return client[kPipelining] ?? client[kHTTPContext]?.defaultPipelining ?? 1 +function matchValue (match, value) { + if (typeof match === 'string') { + return match === value + } + if (match instanceof RegExp) { + return match.test(value) + } + if (typeof match === 'function') { + return match(value) === true + } + return false } -/** - * @type {import('../../types/client.js').default} - */ -class Client extends DispatcherBase { - /** - * - * @param {string|URL} url - * @param {import('../../types/client.js').Client.Options} options - */ - constructor (url, { - interceptors, - maxHeaderSize, - headersTimeout, - socketTimeout, - requestTimeout, - connectTimeout, - bodyTimeout, - idleTimeout, - keepAlive, - keepAliveTimeout, - maxKeepAliveTimeout, - keepAliveMaxTimeout, - keepAliveTimeoutThreshold, - socketPath, - pipelining, - tls, - strictContentLength, - maxCachedSessions, - maxRedirections, - connect, - maxRequestsPerClient, - localAddress, - maxResponseSize, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - // h2 - maxConcurrentStreams, - allowH2 - } = {}) { - super() +function lowerCaseEntries (headers) { + return Object.fromEntries( + Object.entries(headers).map(([headerName, headerValue]) => { + return [headerName.toLocaleLowerCase(), headerValue] + }) + ) +} - if (keepAlive !== undefined) { - throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') +/** + * @param {import('../../index').Headers|string[]|Record} headers + * @param {string} key + */ +function getHeaderByName (headers, key) { + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { + return headers[i + 1] + } } - if (socketTimeout !== undefined) { - throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') - } + return undefined + } else if (typeof headers.get === 'function') { + return headers.get(key) + } else { + return lowerCaseEntries(headers)[key.toLocaleLowerCase()] + } +} - if (requestTimeout !== undefined) { - throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') - } +/** @param {string[]} headers */ +function buildHeadersFromArray (headers) { // fetch HeadersList + const clone = headers.slice() + const entries = [] + for (let index = 0; index < clone.length; index += 2) { + entries.push([clone[index], clone[index + 1]]) + } + return Object.fromEntries(entries) +} - if (idleTimeout !== undefined) { - throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') +function matchHeaders (mockDispatch, headers) { + if (typeof mockDispatch.headers === 'function') { + if (Array.isArray(headers)) { // fetch HeadersList + headers = buildHeadersFromArray(headers) } + return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) + } + if (typeof mockDispatch.headers === 'undefined') { + return true + } + if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { + return false + } - if (maxKeepAliveTimeout !== undefined) { - throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') - } + for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { + const headerValue = getHeaderByName(headers, matchHeaderName) - if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { - throw new InvalidArgumentError('invalid maxHeaderSize') + if (!matchValue(matchHeaderValue, headerValue)) { + return false } + } + return true +} - if (socketPath != null && typeof socketPath !== 'string') { - throw new InvalidArgumentError('invalid socketPath') - } +function normalizeSearchParams (query) { + if (typeof query !== 'string') { + return query + } - if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { - throw new InvalidArgumentError('invalid connectTimeout') - } + const originalQp = new URLSearchParams(query) + const normalizedQp = new URLSearchParams() - if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveTimeout') - } + for (let [key, value] of originalQp.entries()) { + key = key.replace('[]', '') - if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + const valueRepresentsString = /^(['"]).*\1$/.test(value) + if (valueRepresentsString) { + normalizedQp.append(key, value) + continue } - if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { - throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') + if (value.includes(',')) { + const values = value.split(',') + for (const v of values) { + normalizedQp.append(key, v) + } + continue } - if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') - } + normalizedQp.append(key, value) + } - if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') - } + return normalizedQp +} - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } +function safeUrl (path) { + if (typeof path !== 'string') { + return path + } + const pathSegments = path.split('?', 3) + if (pathSegments.length !== 2) { + return path + } - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } + const qp = new URLSearchParams(pathSegments.pop()) + qp.sort() + return [...pathSegments, qp.toString()].join('?') +} - if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { - throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') - } +function matchKey (mockDispatch, { path, method, body, headers }) { + const pathMatch = matchValue(mockDispatch.path, path) + const methodMatch = matchValue(mockDispatch.method, method) + const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true + const headersMatch = matchHeaders(mockDispatch, headers) + return pathMatch && methodMatch && bodyMatch && headersMatch +} - if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { - throw new InvalidArgumentError('localAddress must be valid string IP address') - } +function getResponseData (data) { + if (Buffer.isBuffer(data)) { + return data + } else if (data instanceof Uint8Array) { + return data + } else if (data instanceof ArrayBuffer) { + return data + } else if (ArrayBuffer.isView(data)) { + // A DataView, or any non-Uint8Array typed array, is a byte container + // rather than a plain object. Buffer.from() cannot read one directly, so + // expose the bytes it covers instead of letting it reach JSON.stringify. + return new Uint8Array(data.buffer, data.byteOffset, data.byteLength) + } else if (typeof data === 'object') { + return JSON.stringify(data) + } else if (data) { + return data.toString() + } else { + return '' + } +} - if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { - throw new InvalidArgumentError('maxResponseSize must be a positive number') - } +function getMockDispatch (mockDispatches, key) { + const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path + const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath - if ( - autoSelectFamilyAttemptTimeout != null && - (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) - ) { - throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') - } + const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath) - // h2 - if (allowH2 != null && typeof allowH2 !== 'boolean') { - throw new InvalidArgumentError('allowH2 must be a valid boolean value') - } + // Match path + let matchedMockDispatches = mockDispatches + .filter(({ consumed }) => !consumed) + .filter(({ path, ignoreTrailingSlash }) => { + return ignoreTrailingSlash + ? matchValue(removeTrailingSlash(safeUrl(path)), resolvedPathWithoutTrailingSlash) + : matchValue(safeUrl(path), resolvedPath) + }) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) + } - if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { - throw new InvalidArgumentError('maxConcurrentStreams must be a positive integer, greater than 0') - } + // Match method + matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}' on path '${resolvedPath}'`) + } - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }) - } + // Match body + matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}' on path '${resolvedPath}'`) + } - if (interceptors?.Client && Array.isArray(interceptors.Client)) { - this[kInterceptors] = interceptors.Client - if (!deprecatedInterceptorWarned) { - deprecatedInterceptorWarned = true - process.emitWarning('Client.Options#interceptor is deprecated. Use Dispatcher#compose instead.', { - code: 'UNDICI-CLIENT-INTERCEPTOR-DEPRECATED' - }) - } - } else { - this[kInterceptors] = [createRedirectInterceptor({ maxRedirections })] - } + // Match headers + matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)) + if (matchedMockDispatches.length === 0) { + const headers = typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers + throw new MockNotMatchedError(`Mock dispatch not matched for headers '${headers}' on path '${resolvedPath}'`) + } - this[kUrl] = util.parseOrigin(url) - this[kConnector] = connect - this[kPipelining] = pipelining != null ? pipelining : 1 - this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize - this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout - this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout - this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 2e3 : keepAliveTimeoutThreshold - this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] - this[kServerName] = null - this[kLocalAddress] = localAddress != null ? localAddress : null - this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming - this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming - this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n` - this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 - this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3 - this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength - this[kMaxRedirections] = maxRedirections - this[kMaxRequests] = maxRequestsPerClient - this[kClosedResolve] = null - this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 - this[kMaxConcurrentStreams] = maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server - this[kHTTPContext] = null + return matchedMockDispatches[0] +} - // kQueue is built up of 3 sections separated by - // the kRunningIdx and kPendingIdx indices. - // | complete | running | pending | - // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length - // kRunningIdx points to the first running element. - // kPendingIdx points to the first pending element. - // This implements a fast queue with an amortized - // time of O(1). +function addMockDispatch (mockDispatches, key, data, opts) { + const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false, ...opts } + const replyData = typeof data === 'function' ? { callback: data } : { ...data } + const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } } + mockDispatches.push(newMockDispatch) + // Track total number of intercepts ever registered for better error messages + mockDispatches[kTotalDispatchCount] = (mockDispatches[kTotalDispatchCount] || 0) + 1 + return newMockDispatch +} - this[kQueue] = [] - this[kRunningIdx] = 0 - this[kPendingIdx] = 0 +function deleteMockDispatch (mockDispatches, key) { + const index = mockDispatches.findIndex(dispatch => { + if (!dispatch.consumed) { + return false + } + return matchKey(dispatch, key) + }) + if (index !== -1) { + mockDispatches.splice(index, 1) + } +} - this[kResume] = (sync) => resume(this, sync) - this[kOnError] = (err) => onError(this, err) +/** + * @param {string|RegExp|Function} path Path, or path matcher, to remove trailing slash from + */ +function removeTrailingSlash (path) { + // Registered path matchers may be a RegExp or a function, which have no + // trailing slash to strip; hand those back for matchValue to apply. + if (typeof path !== 'string') { + return path } - get pipelining () { - return this[kPipelining] + while (path.endsWith('/')) { + path = path.slice(0, -1) } - set pipelining (value) { - this[kPipelining] = value - this[kResume](true) + if (path.length === 0) { + path = '/' + } + + return path +} + +function buildKey (opts) { + const { path, method, body, headers, query } = opts + + return { + path, + method, + body, + headers, + query + } +} + +function generateKeyValues (data) { + const keys = Object.keys(data) + const result = [] + for (let i = 0; i < keys.length; ++i) { + const key = keys[i] + const value = data[key] + const name = Buffer.from(`${key}`) + if (Array.isArray(value)) { + for (let j = 0; j < value.length; ++j) { + result.push(name, Buffer.from(`${value[j]}`)) + } + } else { + result.push(name, Buffer.from(`${value}`)) + } } + return result +} - get [kPending] () { - return this[kQueue].length - this[kPendingIdx] - } +/** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + * @param {number} statusCode + */ +function getStatusText (statusCode) { + return STATUS_CODES[statusCode] || 'unknown' +} - get [kRunning] () { - return this[kPendingIdx] - this[kRunningIdx] +async function getResponse (body) { + const buffers = [] + for await (const data of body) { + buffers.push(data) } + return Buffer.concat(buffers).toString('utf8') +} - get [kSize] () { - return this[kQueue].length - this[kRunningIdx] - } +/** + * Mock dispatch function used to simulate undici dispatches + */ +function mockDispatch (opts, handler) { + // Get mock dispatch from built key + const key = buildKey(opts) + const mockDispatch = getMockDispatch(this[kDispatches], key) + const mockDispatches = this[kDispatches] - get [kConnected] () { - return !!this[kHTTPContext] && !this[kConnecting] && !this[kHTTPContext].destroyed - } + mockDispatch.timesInvoked++ - get [kBusy] () { - return Boolean( - this[kHTTPContext]?.busy(null) || - (this[kSize] >= (getPipelining(this) || 1)) || - this[kPending] > 0 - ) - } + const { timesInvoked, times } = mockDispatch - /* istanbul ignore: only used for test */ - [kConnect] (cb) { - connect(this) - this.once('connect', cb) - } + // If it's used up and not persistent, mark as consumed + mockDispatch.consumed = !mockDispatch.persist && timesInvoked >= times + mockDispatch.pending = timesInvoked < times - [kDispatch] (opts, handler) { - const origin = opts.origin || this[kUrl].origin - const request = new Request(origin, opts, handler) + const hasBodyHooks = typeof handler.onBodySent === 'function' || + typeof handler.onRequestSent === 'function' - this[kQueue].push(request) - if (this[kResuming]) { - // Do nothing. - } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { - // Wait a tick in case stream/iterator is ended in the same tick. - this[kResuming] = 1 - queueMicrotask(() => resume(this)) - } else { - this[kResume](true) + // Here's where we resolve a callback if a callback is present for the dispatch data. + if (mockDispatch.data.callback && (!hasBodyHooks || opts.body == null)) { + const { callback, ...responseDefaults } = mockDispatch.data + const callbackResult = callback(opts) + + // An asynchronous reply options callback resolves to the reply data, so + // the dispatch can only continue once the returned promise settles. + // A rejection cannot be thrown synchronously from the dispatch at that + // point, so it is surfaced as a response error instead. + if (isPromise(callbackResult)) { + callbackResult.then( + (resolvedData) => { + if (resolvedData == null || typeof resolvedData !== 'object') { + handler.onResponseError(null, new InvalidArgumentError('reply options callback must return an object')) + return + } + dispatchMockReply(mockDispatches, mockDispatch, key, opts, handler, { ...responseDefaults, ...resolvedData }) + }, + (error) => { + handler.onResponseError(null, error) + } + ) + return true } - if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { - this[kNeedDrain] = 2 + if (callbackResult == null || typeof callbackResult !== 'object') { + throw new InvalidArgumentError('reply options callback must return an object') } - return this[kNeedDrain] < 2 + return dispatchMockReply(mockDispatches, mockDispatch, key, opts, handler, { ...responseDefaults, ...callbackResult }) } - async [kClose] () { - // TODO: for H2 we need to gracefully flush the remaining enqueued - // request and close each stream. - return new Promise((resolve) => { - if (this[kSize]) { - this[kClosedResolve] = resolve - } else { - resolve(null) - } - }) + return dispatchMockReply(mockDispatches, mockDispatch, key, opts, handler) +} + +/** + * Replies to a request once the mock dispatch data is fully resolved + */ +function dispatchMockReply (mockDispatches, mockDispatch, key, opts, handler, resolvedResponse) { + // Parse mockDispatch data. When a reply callback has already been resolved + // in mockDispatch() (i.e. no body lifecycle hooks are involved), the resolved + // response is passed in here, leaving mockDispatch.data untouched so the + // callback can be re-invoked for persistent / times() replies. + const { data: responseData, delay } = mockDispatch + const response = resolvedResponse ?? responseData + + // If specified, trigger dispatch error + if (response.error !== null) { + deleteMockDispatch(mockDispatches, key) + handler.onResponseError(null, response.error) + return true } - async [kDestroy] (err) { - return new Promise((resolve) => { - const requests = this[kQueue].splice(this[kPendingIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - util.errorRequest(this, request, err) - } + // Track whether the request has been aborted + let aborted = false + let timer = null - const callback = () => { - if (this[kClosedResolve]) { - // TODO (fix): Should we error here with ClientDestroyedError? - this[kClosedResolve]() - this[kClosedResolve] = null - } - resolve(null) + // Create the controller early so abort can use it + const controller = { + paused: false, + rawHeaders: null, + rawTrailers: null, + pause () { + this.paused = true + }, + resume () { + this.paused = false + }, + abort: (reason) => { + if (aborted) { + return } + aborted = true - if (this[kHTTPContext]) { - this[kHTTPContext].destroy(err, callback) - this[kHTTPContext] = null - } else { - queueMicrotask(callback) + // Clear the pending delayed response if any + if (timer !== null) { + clearTimeout(timer) + timer = null } - this[kResume]() - }) + handler.onResponseError?.(controller, reason) + } } -} - -const createRedirectInterceptor = __nccwpck_require__(5092) - -function onError (client, err) { - if ( - client[kRunning] === 0 && - err.code !== 'UND_ERR_INFO' && - err.code !== 'UND_ERR_SOCKET' - ) { - // Error is not caused by running request and not a recoverable - // socket error. - assert(client[kPendingIdx] === client[kRunningIdx]) + let replyOpts = opts + const dispatches = mockDispatches - const requests = client[kQueue].splice(client[kRunningIdx]) + // Call onRequestStart to allow the handler to receive the controller + handler.onRequestStart?.(controller, null) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - util.errorRequest(client, request, err) - } - assert(client[kSize] === 0) + if (aborted) { + return true } -} - -/** - * @param {Client} client - * @returns - */ -async function connect (client) { - assert(!client[kConnecting]) - assert(!client[kHTTPContext]) - let { host, hostname, protocol, port } = client[kUrl] + const requestBody = dispatchRequestBody(opts.body, handler, controller, () => aborted) - // Resolve ipv6 - if (hostname[0] === '[') { - const idx = hostname.indexOf(']') + if (isPromise(requestBody)) { + requestBody.then((body) => { + if (body === requestAborted) { + return + } - assert(idx !== -1) - const ip = hostname.substring(1, idx) + if (body !== opts.body) { + replyOpts = { ...opts, body } + } - assert(net.isIP(ip)) - hostname = ip + sendReply() + }, (error) => controller.abort(error)) + return true } - client[kConnecting] = true + if (requestBody === requestAborted) { + return true + } - if (channels.beforeConnect.hasSubscribers) { - channels.beforeConnect.publish({ - connectParams: { - host, - hostname, - protocol, - port, - version: client[kHTTPContext]?.version, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector] - }) + if (requestBody !== opts.body) { + replyOpts = { ...opts, body: requestBody } } - try { - const socket = await new Promise((resolve, reject) => { - client[kConnector]({ - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, (err, socket) => { - if (err) { - reject(err) - } else { - resolve(socket) - } - }) - }) + sendReply() - if (client.destroyed) { - util.destroy(socket.on('error', noop), new ClientDestroyedError()) + function sendReply () { + if (response.callback) { + const { callback, ...responseDefaults } = response + let callbackResult + try { + callbackResult = callback(replyOpts) + } catch (err) { + deleteMockDispatch(mockDispatches, key) + handler.onResponseError(null, err) + return + } + + if (isPromise(callbackResult)) { + callbackResult.then( + (resolvedData) => { + if (resolvedData == null || typeof resolvedData !== 'object') { + handler.onResponseError(null, new InvalidArgumentError('reply options callback must return an object')) + return + } + handleReply(dispatches, { ...responseDefaults, ...resolvedData }) + }, + (err) => { + handler.onResponseError(null, err) + } + ) + return + } + + if (callbackResult == null || typeof callbackResult !== 'object') { + throw new InvalidArgumentError('reply options callback must return an object') + } + + handleReply(dispatches, { ...responseDefaults, ...callbackResult }) return } - assert(socket) + // Handle the request with a delay if necessary + if (typeof delay === 'number' && delay > 0) { + timer = setTimeout(() => { + timer = null + handleReply(dispatches) + }, delay) + } else { + handleReply(dispatches) + } + } - try { - client[kHTTPContext] = socket.alpnProtocol === 'h2' - ? await connectH2(client, socket) - : await connectH1(client, socket) - } catch (err) { - socket.destroy().on('error', noop) - throw err + function handleReply (mockDispatches, _response = response) { + // Don't send response if the request was aborted + if (aborted) { + return } - client[kConnecting] = false + const { statusCode, data, headers, trailers } = _response - socket[kCounter] = 0 - socket[kMaxRequests] = client[kMaxRequests] - socket[kClient] = client - socket[kError] = null + // fetch's HeadersList is a 1D string array + const optsHeaders = Array.isArray(opts.headers) + ? buildHeadersFromArray(opts.headers) + : opts.headers + const body = typeof data === 'function' + ? data({ ...replyOpts, headers: optsHeaders }) + : data - if (channels.connected.hasSubscribers) { - channels.connected.publish({ - connectParams: { - host, - hostname, - protocol, - port, - version: client[kHTTPContext]?.version, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - socket - }) + // util.types.isPromise is likely needed for jest. + if (isPromise(body)) { + // If handleReply is asynchronous, throwing an error + // in the callback will reject the promise, rather than + // synchronously throw the error, which breaks some tests. + // Rather, we wait for the callback to resolve if it is a + // promise, and then re-run handleReply with the new body. + return body.then((newData) => handleReply(mockDispatches, { ..._response, data: newData })) } - client.emit('connect', client[kUrl], [client]) - } catch (err) { - if (client.destroyed) { + + // Check again if aborted after async body resolution + if (aborted) { return } - client[kConnecting] = false - - if (channels.connectError.hasSubscribers) { - channels.connectError.publish({ - connectParams: { - host, - hostname, - protocol, - port, - version: client[kHTTPContext]?.version, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - error: err - }) - } + const responseData = getResponseData(body) + const responseHeaders = generateKeyValues(headers ?? {}) + const responseTrailers = generateKeyValues(trailers ?? {}) - if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { - assert(client[kRunning] === 0) - while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { - const request = client[kQueue][client[kPendingIdx]++] - util.errorRequest(client, request, err) - } - } else { - onError(client, err) - } + // Update the controller with response data + controller.rawHeaders = responseHeaders + controller.rawTrailers = responseTrailers - client.emit('connectionError', client[kUrl], [client], err) + handler.onResponseStart?.(controller, statusCode, parseHeaders(responseHeaders), getStatusText(statusCode)) + handler.onResponseData?.(controller, Buffer.from(responseData)) + handler.onResponseEnd?.(controller, parseHeaders(responseTrailers)) + deleteMockDispatch(mockDispatches, key) } - client[kResume]() + return true } -function emitDrain (client) { - client[kNeedDrain] = 0 - client.emit('drain', client[kUrl], [client]) -} +function dispatchRequestBody (body, handler, controller, isAborted) { + if (typeof handler.onBodySent !== 'function' && typeof handler.onRequestSent !== 'function') { + return body + } -function resume (client, sync) { - if (client[kResuming] === 2) { - return + if (body == null) { + return callOnRequestSent(handler, controller, isAborted) ? body : requestAborted + } + + if (body && typeof body[Symbol.asyncIterator] === 'function') { + return dispatchAsyncIterableBody(body, handler, controller, isAborted) } - client[kResuming] = 2 + if (isIterableBody(body)) { + const chunks = [] + + for (const chunk of body) { + if (isAborted()) { + return requestAborted + } + chunks.push(chunk) + if (!callOnBodySent(handler, controller, chunk) || isAborted()) { + return requestAborted + } + } + + return callOnRequestSent(handler, controller, isAborted) ? chunks : requestAborted + } - _resume(client, sync) - client[kResuming] = 0 + if (isAborted()) { + return requestAborted + } - if (client[kRunningIdx] > 256) { - client[kQueue].splice(0, client[kRunningIdx]) - client[kPendingIdx] -= client[kRunningIdx] - client[kRunningIdx] = 0 + if (!callOnBodySent(handler, controller, body)) { + return requestAborted } + + return callOnRequestSent(handler, controller, isAborted) ? body : requestAborted } -function _resume (client, sync) { - while (true) { - if (client.destroyed) { - assert(client[kPending] === 0) - return - } +async function dispatchAsyncIterableBody (body, handler, controller, isAborted) { + const chunks = [] - if (client[kClosedResolve] && !client[kSize]) { - client[kClosedResolve]() - client[kClosedResolve] = null - return + for await (const chunk of body) { + if (isAborted()) { + return requestAborted } - - if (client[kHTTPContext]) { - client[kHTTPContext].resume() + chunks.push(chunk) + if (!callOnBodySent(handler, controller, chunk) || isAborted()) { + return requestAborted } + } - if (client[kBusy]) { - client[kNeedDrain] = 2 - } else if (client[kNeedDrain] === 2) { - if (sync) { - client[kNeedDrain] = 1 - queueMicrotask(() => emitDrain(client)) - } else { - emitDrain(client) - } - continue - } + if (!callOnRequestSent(handler, controller, isAborted)) { + return requestAborted + } - if (client[kPending] === 0) { - return + return { + async * [Symbol.asyncIterator] () { + yield * chunks } + } +} - if (client[kRunning] >= (getPipelining(client) || 1)) { - return - } +function callOnBodySent (handler, controller, chunk) { + try { + handler.onBodySent?.(chunk) + return true + } catch (error) { + controller.abort(error) + return false + } +} - const request = client[kQueue][client[kPendingIdx]] +function callOnRequestSent (handler, controller, isAborted) { + try { + handler.onRequestSent?.() + return !isAborted() + } catch (error) { + controller.abort(error) + return false + } +} - if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { - if (client[kRunning] > 0) { - return - } +function isIterableBody (body) { + return typeof body !== 'string' && + !Buffer.isBuffer(body) && + !ArrayBuffer.isView(body) && + typeof body[Symbol.iterator] === 'function' +} - client[kServerName] = request.servername - client[kHTTPContext]?.destroy(new InformationalError('servername changed'), () => { - client[kHTTPContext] = null - resume(client) - }) - } +function buildMockDispatch () { + const agent = this[kMockAgent] + const origin = this[kOrigin] + const originalDispatch = this[kOriginalDispatch] - if (client[kConnecting]) { - return + return function dispatch (opts, handler) { + if (agent.isMockActive) { + try { + mockDispatch.call(this, opts, handler) + } catch (error) { + if (error.code === 'UND_MOCK_ERR_MOCK_NOT_MATCHED') { + const netConnect = agent[kGetNetConnect]() + const totalInterceptsCount = this[kDispatches][kTotalDispatchCount] || this[kDispatches].length + const pendingInterceptsCount = this[kDispatches].filter(({ consumed }) => !consumed).length + const interceptsMessage = `, ${pendingInterceptsCount} interceptor(s) remaining out of ${totalInterceptsCount} defined` + if (netConnect === false) { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)${interceptsMessage}`) + } + if (checkNetConnect(netConnect, origin)) { + originalDispatch.call(this, '__mockAgentBodyForDispatch' in opts + ? { ...opts, body: opts.__mockAgentBodyForDispatch } + : opts, handler) + } else { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)${interceptsMessage}`) + } + } else { + throw error + } + } + } else { + originalDispatch.call(this, opts, handler) } + } +} - if (!client[kHTTPContext]) { - connect(client) - return - } +function checkNetConnect (netConnect, origin) { + const url = new URL(origin) + if (netConnect === true) { + return true + } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { + return true + } + return false +} - if (client[kHTTPContext].destroyed) { - return - } +function normalizeOrigin (origin) { + if (typeof origin !== 'string' && !(origin instanceof URL)) { + return origin + } - if (client[kHTTPContext].busy(request)) { - return - } + if (origin instanceof URL) { + return origin.origin + } - if (!request.aborted && client[kHTTPContext].write(request)) { - client[kPendingIdx]++ - } else { - client[kQueue].splice(client[kPendingIdx], 1) - } + return origin.toLowerCase() +} + +function buildAndValidateMockOptions (opts) { + const { agent, ...mockOptions } = opts + + if ('enableCallHistory' in mockOptions && typeof mockOptions.enableCallHistory !== 'boolean') { + throw new InvalidArgumentError('options.enableCallHistory must to be a boolean') + } + + if ('acceptNonStandardSearchParameters' in mockOptions && typeof mockOptions.acceptNonStandardSearchParameters !== 'boolean') { + throw new InvalidArgumentError('options.acceptNonStandardSearchParameters must to be a boolean') } + + if ('ignoreTrailingSlash' in mockOptions && typeof mockOptions.ignoreTrailingSlash !== 'boolean') { + throw new InvalidArgumentError('options.ignoreTrailingSlash must to be a boolean') + } + + return mockOptions } -module.exports = Client +module.exports = { + getResponseData, + getMockDispatch, + addMockDispatch, + deleteMockDispatch, + buildKey, + generateKeyValues, + matchValue, + getResponse, + getStatusText, + mockDispatch, + buildMockDispatch, + checkNetConnect, + buildAndValidateMockOptions, + getHeaderByName, + buildHeadersFromArray, + normalizeSearchParams, + normalizeOrigin +} /***/ }), -/***/ 1841: +/***/ 6142: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const Dispatcher = __nccwpck_require__(883) -const { - ClientDestroyedError, - ClientClosedError, - InvalidArgumentError -} = __nccwpck_require__(8707) -const { kDestroy, kClose, kClosed, kDestroyed, kDispatch, kInterceptors } = __nccwpck_require__(6443) +const { Transform } = __nccwpck_require__(7075) +const { Console } = __nccwpck_require__(7540) -const kOnDestroyed = Symbol('onDestroyed') -const kOnClosed = Symbol('onClosed') -const kInterceptedDispatch = Symbol('Intercepted Dispatch') +const PERSISTENT = process.versions.icu ? '✅' : 'Y ' +const NOT_PERSISTENT = process.versions.icu ? '❌' : 'N ' -class DispatcherBase extends Dispatcher { - constructor () { - super() +/** + * Gets the output of `console.table(…)` as a string. + */ +module.exports = class PendingInterceptorsFormatter { + constructor ({ disableColors } = {}) { + this.transform = new Transform({ + transform (chunk, _enc, cb) { + cb(null, chunk) + } + }) - this[kDestroyed] = false - this[kOnDestroyed] = null - this[kClosed] = false - this[kOnClosed] = [] + this.logger = new Console({ + stdout: this.transform, + inspectOptions: { + colors: !disableColors && !process.env.CI + } + }) } - get destroyed () { - return this[kDestroyed] - } + format (pendingInterceptors) { + const withPrettyHeaders = pendingInterceptors.map( + ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ + Method: method, + Origin: origin, + Path: path, + 'Status code': statusCode, + Persistent: persist ? PERSISTENT : NOT_PERSISTENT, + Invocations: timesInvoked, + Remaining: persist ? Infinity : times - timesInvoked + })) - get closed () { - return this[kClosed] + this.logger.table(withPrettyHeaders) + return this.transform.read().toString() } +} - get interceptors () { - return this[kInterceptors] - } - set interceptors (newInterceptors) { - if (newInterceptors) { - for (let i = newInterceptors.length - 1; i >= 0; i--) { - const interceptor = this[kInterceptors][i] - if (typeof interceptor !== 'function') { - throw new InvalidArgumentError('interceptor must be an function') - } - } - } +/***/ }), - this[kInterceptors] = newInterceptors - } +/***/ 5095: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - close (callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.close((err, data) => { - return err ? reject(err) : resolve(data) - }) - }) - } +"use strict"; - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } - if (this[kDestroyed]) { - queueMicrotask(() => callback(new ClientDestroyedError(), null)) - return - } +const Agent = __nccwpck_require__(7405) +const MockAgent = __nccwpck_require__(7501) +const { SnapshotRecorder } = __nccwpck_require__(3766) +const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8707) +const util = __nccwpck_require__(3440) +const { validateSnapshotMode } = __nccwpck_require__(9683) - if (this[kClosed]) { - if (this[kOnClosed]) { - this[kOnClosed].push(callback) - } else { - queueMicrotask(() => callback(null, null)) - } - return - } +const kSnapshotRecorder = Symbol('kSnapshotRecorder') +const kSnapshotMode = Symbol('kSnapshotMode') +const kSnapshotPath = Symbol('kSnapshotPath') +const kSnapshotLoaded = Symbol('kSnapshotLoaded') +const kRealAgent = Symbol('kRealAgent') - this[kClosed] = true - this[kOnClosed].push(callback) +// Static flag to ensure warning is only emitted once per process +let warningEmitted = false - const onClosed = () => { - const callbacks = this[kOnClosed] - this[kOnClosed] = null - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null) - } +class SnapshotAgent extends MockAgent { + constructor (opts = {}) { + // Emit experimental warning only once + if (!warningEmitted) { + process.emitWarning( + 'SnapshotAgent is experimental and subject to change', + 'ExperimentalWarning' + ) + warningEmitted = true } - // Should not error. - this[kClose]() - .then(() => this.destroy()) - .then(() => { - queueMicrotask(onClosed) - }) - } + const { + mode = 'record', + snapshotPath = null, + ...mockAgentOpts + } = opts - destroy (err, callback) { - if (typeof err === 'function') { - callback = err - err = null + super(mockAgentOpts) + + validateSnapshotMode(mode) + + // Validate snapshotPath is provided when required + if ((mode === 'playback' || mode === 'update') && !snapshotPath) { + throw new InvalidArgumentError(`snapshotPath is required when mode is '${mode}'`) + } + + this[kSnapshotMode] = mode + this[kSnapshotPath] = snapshotPath + + this[kSnapshotRecorder] = new SnapshotRecorder({ + snapshotPath: this[kSnapshotPath], + mode: this[kSnapshotMode], + maxSnapshots: opts.maxSnapshots, + autoFlush: opts.autoFlush, + flushInterval: opts.flushInterval, + matchHeaders: opts.matchHeaders, + ignoreHeaders: opts.ignoreHeaders, + excludeHeaders: opts.excludeHeaders, + matchBody: opts.matchBody, + normalizeBody: opts.normalizeBody, + matchQuery: opts.matchQuery, + normalizeQuery: opts.normalizeQuery, + caseSensitive: opts.caseSensitive, + shouldRecord: opts.shouldRecord, + shouldPlayback: opts.shouldPlayback, + excludeUrls: opts.excludeUrls + }) + this[kSnapshotLoaded] = false + + // For recording/update mode, we need a real agent to make actual requests + // For playback mode, we need a real agent if there are excluded URLs + if (this[kSnapshotMode] === 'record' || this[kSnapshotMode] === 'update' || + (this[kSnapshotMode] === 'playback' && opts.excludeUrls && opts.excludeUrls.length > 0)) { + this[kRealAgent] = new Agent(opts) } - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.destroy(err, (err, data) => { - return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) - }) + // Auto-load snapshots in playback/update mode + if ((this[kSnapshotMode] === 'playback' || this[kSnapshotMode] === 'update') && this[kSnapshotPath]) { + this.loadSnapshots().catch(() => { + // Ignore load errors - file might not exist yet }) } + } - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') + dispatch (opts, handler) { + const mode = this[kSnapshotMode] + + // Check if URL should be excluded (pass through without mocking/recording) + if (this[kSnapshotRecorder].isUrlExcluded(opts)) { + // Real agent is guaranteed by constructor when excludeUrls is configured + return this[kRealAgent].dispatch(opts, handler) } - if (this[kDestroyed]) { - if (this[kOnDestroyed]) { - this[kOnDestroyed].push(callback) + if (mode === 'playback' || mode === 'update') { + // Ensure snapshots are loaded + if (!this[kSnapshotLoaded]) { + // Need to load asynchronously, delegate to async version + return this.#asyncDispatch(opts, handler) + } + + // Try to find existing snapshot (synchronous) + const snapshot = this[kSnapshotRecorder].findSnapshot(opts) + + if (snapshot) { + // Use recorded response (synchronous) + return this.#replaySnapshot(snapshot, handler) + } else if (mode === 'update') { + // Make real request and record it (async required) + return this.#recordAndReplay(opts, handler) } else { - queueMicrotask(() => callback(null, null)) + // Playback mode but no snapshot found + const error = new UndiciError(`No snapshot found for ${opts.method || 'GET'} ${opts.path}`) + if (handler.onResponseError) { + handler.onResponseError(null, error) + return + } + throw error } - return + } else if (mode === 'record') { + // Record mode - make real request and save response (async required) + return this.#recordAndReplay(opts, handler) } + } - if (!err) { - err = new ClientDestroyedError() + /** + * Async version of dispatch for when we need to load snapshots first + */ + async #asyncDispatch (opts, handler) { + await this.loadSnapshots() + return this.dispatch(opts, handler) + } + + /** + * Records a real request and replays the response + */ + #recordAndReplay (opts, handler) { + const responseData = { + statusCode: null, + headers: {}, + trailers: {}, + body: [] } - this[kDestroyed] = true - this[kOnDestroyed] = this[kOnDestroyed] || [] - this[kOnDestroyed].push(callback) + const self = this // Capture 'this' context for use within nested handler callbacks - const onDestroyed = () => { - const callbacks = this[kOnDestroyed] - this[kOnDestroyed] = null - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null) + const recordingHandler = { + onRequestStart (controller, context) { + return handler.onRequestStart(controller, { ...context, history: this.history }) + }, + + onRequestUpgrade (controller, statusCode, headers, socket) { + return handler.onRequestUpgrade(controller, statusCode, headers, socket) + }, + + onResponseStart (controller, statusCode, headers, statusMessage) { + responseData.statusCode = statusCode + responseData.headers = headers + return handler.onResponseStart(controller, statusCode, headers, statusMessage) + }, + + onResponseData (controller, chunk) { + responseData.body.push(chunk) + return handler.onResponseData(controller, chunk) + }, + + onResponseEnd (controller, trailers) { + responseData.trailers = trailers + + // Record the interaction using captured 'self' context (fire and forget) + const responseBody = Buffer.concat(responseData.body) + self[kSnapshotRecorder].record(opts, { + statusCode: responseData.statusCode, + headers: responseData.headers, + body: responseBody, + trailers: responseData.trailers + }) + .then(() => handler.onResponseEnd(controller, trailers)) + .catch((error) => handler.onResponseError(controller, error)) + }, + + onResponseError (controller, error) { + return handler.onResponseError(controller, error) } } - // Should not error. - this[kDestroy](err).then(() => { - queueMicrotask(onDestroyed) - }) + // Use composed agent if available (includes interceptors), otherwise use real agent + const agent = this[kRealAgent] + return agent.dispatch(opts, recordingHandler) } - [kInterceptedDispatch] (opts, handler) { - if (!this[kInterceptors] || this[kInterceptors].length === 0) { - this[kInterceptedDispatch] = this[kDispatch] - return this[kDispatch](opts, handler) + /** + * Replays a recorded response + * + * @param {Object} snapshot - The recorded snapshot to replay. + * @param {Object} handler - The handler to call with the response data. + * @returns {void} + */ + #replaySnapshot (snapshot, handler) { + try { + const { response } = snapshot + + const rawHeaders = response.headers ? util.toRawHeaders(response.headers) : [] + const rawTrailers = response.trailers ? util.toRawHeaders(response.trailers) : [] + + const controller = { + rawHeaders, + rawTrailers, + pause () { }, + resume () { }, + abort (reason) { + this.aborted = true + this.reason = reason + }, + + aborted: false, + paused: false + } + + handler.onRequestStart(controller) + + handler.onResponseStart(controller, response.statusCode, response.headers, response.statusMessage) + + // Body is always stored as base64 string + const body = Buffer.from(response.body, 'base64') + handler.onResponseData(controller, body) + + handler.onResponseEnd(controller, response.trailers) + } catch (error) { + handler.onResponseError?.(null, error) } + } + + /** + * Loads snapshots from file + * + * @param {string} [filePath] - Optional file path to load snapshots from. + * @returns {Promise} - Resolves when snapshots are loaded. + */ + async loadSnapshots (filePath) { + await this[kSnapshotRecorder].loadSnapshots(filePath || this[kSnapshotPath]) + this[kSnapshotLoaded] = true - let dispatch = this[kDispatch].bind(this) - for (let i = this[kInterceptors].length - 1; i >= 0; i--) { - dispatch = this[kInterceptors][i](dispatch) + // In playback mode, set up MockAgent interceptors for all snapshots + if (this[kSnapshotMode] === 'playback') { + this.#setupMockInterceptors() } - this[kInterceptedDispatch] = dispatch - return dispatch(opts, handler) } - dispatch (opts, handler) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') + /** + * Saves snapshots to file + * + * @param {string} [filePath] - Optional file path to save snapshots to. + * @returns {Promise} - Resolves when snapshots are saved. + */ + async saveSnapshots (filePath) { + return this[kSnapshotRecorder].saveSnapshots(filePath || this[kSnapshotPath]) + } + + /** + * Sets up MockAgent interceptors based on recorded snapshots. + * + * This method creates MockAgent interceptors for each recorded snapshot, + * allowing the SnapshotAgent to fall back to MockAgent's standard intercept + * mechanism in playback mode. Each interceptor is configured to persist + * (remain active for multiple requests) and responds with the recorded + * response data. + * + * Called automatically when loading snapshots in playback mode. + * + * @returns {void} + */ + #setupMockInterceptors () { + for (const snapshot of this[kSnapshotRecorder].getSnapshots()) { + const { request, responses, response } = snapshot + const url = new URL(request.url) + + const mockPool = this.get(url.origin) + + // Handle both new format (responses array) and legacy format (response object) + const responseData = responses ? responses[0] : response + if (!responseData) continue + + mockPool.intercept({ + path: url.pathname + url.search, + method: request.method, + headers: request.headers, + body: request.body + }).reply(responseData.statusCode, responseData.body, { + headers: responseData.headers, + trailers: responseData.trailers + }).persist() } + } - try { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object.') - } + /** + * Gets the snapshot recorder + * @return {SnapshotRecorder} - The snapshot recorder instance + */ + getRecorder () { + return this[kSnapshotRecorder] + } - if (this[kDestroyed] || this[kOnDestroyed]) { - throw new ClientDestroyedError() - } + /** + * Gets the current mode + * @return {import('./snapshot-utils').SnapshotMode} - The current snapshot mode + */ + getMode () { + return this[kSnapshotMode] + } - if (this[kClosed]) { - throw new ClientClosedError() - } + /** + * Clears all snapshots + * @returns {void} + */ + clearSnapshots () { + this[kSnapshotRecorder].clear() + } - return this[kInterceptedDispatch](opts, handler) - } catch (err) { - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') - } + /** + * Resets call counts for all snapshots (useful for test cleanup) + * @returns {void} + */ + resetCallCounts () { + this[kSnapshotRecorder].resetCallCounts() + } - handler.onError(err) + /** + * Deletes a specific snapshot by request options + * @param {import('./snapshot-recorder').SnapshotRequestOptions} requestOpts - Request options to identify the snapshot + * @return {Promise} - Returns true if the snapshot was deleted, false if not found + */ + deleteSnapshot (requestOpts) { + return this[kSnapshotRecorder].deleteSnapshot(requestOpts) + } - return false + /** + * Gets information about a specific snapshot + * @returns {import('./snapshot-recorder').SnapshotInfo|null} - Snapshot information or null if not found + */ + getSnapshotInfo (requestOpts) { + return this[kSnapshotRecorder].getSnapshotInfo(requestOpts) + } + + /** + * Replaces all snapshots with new data (full replacement) + * @param {Array<{hash: string; snapshot: import('./snapshot-recorder').SnapshotEntryshotEntry}>|Record} snapshotData - New snapshot data to replace existing snapshots + * @returns {void} + */ + replaceSnapshots (snapshotData) { + this[kSnapshotRecorder].replaceSnapshots(snapshotData) + } + + /** + * Closes the agent, saving snapshots and cleaning up resources. + * + * @returns {Promise} + */ + async close () { + // In playback mode the recorder must not persist to disk. findSnapshot() + // mutates each matched snapshot's callCount, so saving on close would + // rewrite the snapshot file even though nothing new was recorded. Only + // record/update modes should write snapshots; playback just cleans up. + if (this[kSnapshotMode] === 'playback') { + this[kSnapshotRecorder].destroy() + } else { + await this[kSnapshotRecorder].close() } + await this[kRealAgent]?.close() + await super.close() } } -module.exports = DispatcherBase +module.exports = SnapshotAgent /***/ }), -/***/ 883: +/***/ 3766: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const EventEmitter = __nccwpck_require__(8474) -class Dispatcher extends EventEmitter { - dispatch () { - throw new Error('not implemented') +const { writeFile, readFile, mkdir } = __nccwpck_require__(1455) +const { dirname, resolve } = __nccwpck_require__(6760) +const { setTimeout, clearTimeout } = __nccwpck_require__(7997) +const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8707) +const { setHeader } = __nccwpck_require__(3440) +const { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = __nccwpck_require__(9683) + +/** + * @typedef {Object} SnapshotRequestOptions + * @property {string} method - HTTP method (e.g. 'GET', 'POST', etc.) + * @property {string} path - Request path + * @property {string} origin - Request origin (base URL) + * @property {import('./snapshot-utils').Headers|import('./snapshot-utils').UndiciHeaders} headers - Request headers + * @property {import('./snapshot-utils').NormalizedHeaders} _normalizedHeaders - Request headers as a lowercase object + * @property {string|Buffer} [body] - Request body (optional) + */ + +/** + * @typedef {Object} SnapshotEntryRequest + * @property {string} method - HTTP method (e.g. 'GET', 'POST', etc.) + * @property {string} url - Full URL of the request + * @property {import('./snapshot-utils').NormalizedHeaders} headers - Normalized headers as a lowercase object + * @property {string|Buffer} [body] - Request body (optional) + */ + +/** + * @typedef {Object} SnapshotEntryResponse + * @property {number} statusCode - HTTP status code of the response + * @property {import('./snapshot-utils').NormalizedHeaders} headers - Normalized response headers as a lowercase object + * @property {string} body - Response body as a base64url encoded string + * @property {Object} [trailers] - Optional response trailers + */ + +/** + * @typedef {Object} SnapshotEntry + * @property {SnapshotEntryRequest} request - The request object + * @property {Array} responses - Array of response objects + * @property {number} callCount - Number of times this snapshot has been called + * @property {string} timestamp - ISO timestamp of when the snapshot was created + */ + +/** + * @typedef {Object} SnapshotRecorderMatchOptions + * @property {Array} [matchHeaders=[]] - Headers to match (empty array means match all headers) + * @property {Array} [ignoreHeaders=[]] - Headers to ignore for matching + * @property {Array} [excludeHeaders=[]] - Headers to exclude from matching + * @property {boolean} [matchBody=true] - Whether to match request body + * @property {(body: string|Buffer|null|undefined) => string} [normalizeBody] - Function to normalize the body before matching (e.g. strip timestamps) + * @property {boolean} [matchQuery=true] - Whether to match query parameters + * @property {(query: URLSearchParams) => string} [normalizeQuery] - Function to normalize query parameters before matching (e.g. strip volatile params) + * @property {boolean} [caseSensitive=false] - Whether header matching is case-sensitive + */ + +/** + * @typedef {Object} SnapshotRecorderOptions + * @property {string} [snapshotPath] - Path to save/load snapshots + * @property {import('./snapshot-utils').SnapshotMode} [mode='record'] - Mode: 'record' or 'playback' + * @property {number} [maxSnapshots=Infinity] - Maximum number of snapshots to keep + * @property {boolean} [autoFlush=false] - Whether to automatically flush snapshots to disk + * @property {number} [flushInterval=30000] - Auto-flush interval in milliseconds (default: 30 seconds) + * @property {Array} [excludeUrls=[]] - URLs to exclude from recording + * @property {function} [shouldRecord=null] - Function to filter requests for recording + * @property {function} [shouldPlayback=null] - Function to filter requests + */ + +/** + * @typedef {Object} SnapshotFormattedRequest + * @property {string} method - HTTP method (e.g. 'GET', 'POST', etc.) + * @property {string} url - Full URL of the request (with query parameters if matchQuery is true) + * @property {import('./snapshot-utils').NormalizedHeaders} headers - Normalized headers as a lowercase object + * @property {string} body - Request body (optional, only if matchBody is true) + */ + +/** + * @typedef {Object} SnapshotInfo + * @property {string} hash - Hash key for the snapshot + * @property {SnapshotEntryRequest} request - The request object + * @property {number} responseCount - Number of responses recorded for this request + * @property {number} callCount - Number of times this snapshot has been called + * @property {string} timestamp - ISO timestamp of when the snapshot was created + */ + +/** + * Normalizes the URL string used for request matching. + * + * @param {URL} url - Parsed request URL + * @param {boolean} matchQuery - Whether to include query parameters in matching + * @param {((query: URLSearchParams) => string)|undefined} normalizeQuery - Optional normalization function + * @returns {string} - URL string for hashing + */ +function normalizeUrlForMatching (url, matchQuery, normalizeQuery) { + if (matchQuery === false) return `${url.origin}${url.pathname}` + if (normalizeQuery) { + const normalized = String(normalizeQuery(url.searchParams) ?? '') + return normalized ? `${url.origin}${url.pathname}?${normalized}` : `${url.origin}${url.pathname}` } + return url.toString() +} - close () { - throw new Error('not implemented') +/** + * Normalizes the body value used for request matching. + * + * @param {string|Buffer|null|undefined} body - Raw request body + * @param {boolean} matchBody - Whether to include the body in matching + * @param {((body: string|Buffer|null|undefined) => string)|undefined} normalizeBody - Optional normalization function + * @returns {string} - Body string for hashing + */ +function normalizeBodyForMatching (body, matchBody, normalizeBody) { + if (matchBody === false) return '' + if (normalizeBody) return String(normalizeBody(body) ?? '') + return body ? String(body) : '' +} + +/** + * Formats a request for consistent snapshot storage + * Caches normalized headers to avoid repeated processing + * + * @param {SnapshotRequestOptions} opts - Request options + * @param {import('./snapshot-utils').HeaderFilters} headerFilters - Cached header sets for performance + * @param {SnapshotRecorderMatchOptions} [matchOptions] - Matching options for headers and body + * @returns {SnapshotFormattedRequest} - Formatted request object + */ +function formatRequestKey (opts, headerFilters, matchOptions = {}) { + const url = new URL(opts.path, opts.origin) + + // Cache normalized headers if not already done + const normalized = opts._normalizedHeaders || normalizeHeaders(opts.headers) + if (!opts._normalizedHeaders) { + opts._normalizedHeaders = normalized } - destroy () { - throw new Error('not implemented') + return { + method: opts.method || 'GET', + url: normalizeUrlForMatching(url, matchOptions.matchQuery, matchOptions.normalizeQuery), + headers: filterHeadersForMatching(normalized, headerFilters, matchOptions), + body: normalizeBodyForMatching(opts.body, matchOptions.matchBody, matchOptions.normalizeBody) } +} - compose (...args) { - // So we handle [interceptor1, interceptor2] or interceptor1, interceptor2, ... - const interceptors = Array.isArray(args[0]) ? args[0] : args - let dispatch = this.dispatch.bind(this) +/** + * Filters headers based on matching configuration + * + * @param {import('./snapshot-utils').Headers} headers - Headers to filter + * @param {import('./snapshot-utils').HeaderFilters} headerFilters - Cached sets for ignore, exclude, and match headers + * @param {SnapshotRecorderMatchOptions} [matchOptions] - Matching options for headers + */ +function filterHeadersForMatching (headers, headerFilters, matchOptions = {}) { + if (!headers || typeof headers !== 'object') return {} - for (const interceptor of interceptors) { - if (interceptor == null) { - continue - } + const { + caseSensitive = false + } = matchOptions - if (typeof interceptor !== 'function') { - throw new TypeError(`invalid interceptor, expected function received ${typeof interceptor}`) - } + const filtered = {} + const { ignore, exclude, match } = headerFilters - dispatch = interceptor(dispatch) + for (const [key, value] of Object.entries(headers)) { + const headerKey = caseSensitive ? key : key.toLowerCase() - if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) { - throw new TypeError('invalid interceptor') - } + // Skip if in exclude list (for security) + if (exclude.has(headerKey)) continue + + // Skip if in ignore list (for matching) + if (ignore.has(headerKey)) continue + + // If matchHeaders is specified, only include those headers + if (match.size !== 0) { + if (!match.has(headerKey)) continue } - return new ComposedDispatcher(this, dispatch) + setHeader(filtered, headerKey, value) } + + return filtered } -class ComposedDispatcher extends Dispatcher { - #dispatcher = null - #dispatch = null +/** + * Filters headers for storage (only excludes sensitive headers) + * + * @param {import('./snapshot-utils').Headers} headers - Headers to filter + * @param {import('./snapshot-utils').HeaderFilters} headerFilters - Cached sets for ignore, exclude, and match headers + * @param {SnapshotRecorderMatchOptions} [matchOptions] - Matching options for headers + */ +function filterHeadersForStorage (headers, headerFilters, matchOptions = {}) { + if (!headers || typeof headers !== 'object') return {} - constructor (dispatcher, dispatch) { - super() - this.#dispatcher = dispatcher - this.#dispatch = dispatch - } + const { + caseSensitive = false + } = matchOptions - dispatch (...args) { - this.#dispatch(...args) - } + const filtered = {} + const { exclude: excludeSet } = headerFilters - close (...args) { - return this.#dispatcher.close(...args) + for (const [key, value] of Object.entries(headers)) { + const headerKey = caseSensitive ? key : key.toLowerCase() + + // Skip if in exclude list (for security) + if (excludeSet.has(headerKey)) continue + + setHeader(filtered, headerKey, value) } - destroy (...args) { - return this.#dispatcher.destroy(...args) + return filtered +} + +/** + * Creates a hash key for request matching + * Properly orders headers to avoid conflicts and uses crypto hashing when available + * + * @param {SnapshotFormattedRequest} formattedRequest - Request object + * @returns {string} - Base64url encoded hash of the request + */ +function createRequestHash (formattedRequest) { + const parts = [ + formattedRequest.method, + formattedRequest.url + ] + + // Process headers in a deterministic way to avoid conflicts + if (formattedRequest.headers && typeof formattedRequest.headers === 'object') { + const headerKeys = Object.keys(formattedRequest.headers).sort() + for (const key of headerKeys) { + const values = Array.isArray(formattedRequest.headers[key]) + ? formattedRequest.headers[key] + : [formattedRequest.headers[key]] + + // Add header name + parts.push(key) + + // Add all values for this header, sorted for consistency + for (const value of values.sort()) { + parts.push(String(value)) + } + } } + + // Add body + parts.push(formattedRequest.body) + + const content = parts.join('|') + + return hashId(content) } -module.exports = Dispatcher +class SnapshotRecorder { + /** @type {NodeJS.Timeout | null} */ + #flushTimeout + /** @type {import('./snapshot-utils').IsUrlExcluded} */ + #isUrlExcluded -/***/ }), + /** @type {Map} */ + #snapshots = new Map() -/***/ 3137: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** @type {string|undefined} */ + #snapshotPath -"use strict"; + /** @type {number} */ + #maxSnapshots = Infinity + /** @type {boolean} */ + #autoFlush = false -const DispatcherBase = __nccwpck_require__(1841) -const { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = __nccwpck_require__(6443) -const ProxyAgent = __nccwpck_require__(6672) -const Agent = __nccwpck_require__(7405) + /** @type {import('./snapshot-utils').HeaderFilters} */ + #headerFilters -const DEFAULT_PORTS = { - 'http:': 80, - 'https:': 443 -} + /** + * Creates a new SnapshotRecorder instance + * @param {SnapshotRecorderOptions&SnapshotRecorderMatchOptions} [options={}] - Configuration options for the recorder + */ + constructor (options = {}) { + this.#snapshotPath = options.snapshotPath + this.#maxSnapshots = options.maxSnapshots || Infinity + this.#autoFlush = options.autoFlush || false + this.flushInterval = options.flushInterval || 30000 // 30 seconds default + this._flushTimer = null -let experimentalWarned = false + // Matching configuration + /** @type {Required} */ + this.matchOptions = { + matchHeaders: options.matchHeaders || [], // empty means match all headers + ignoreHeaders: options.ignoreHeaders || [], + excludeHeaders: options.excludeHeaders || [], + matchBody: options.matchBody !== false, // default: true + normalizeBody: options.normalizeBody || undefined, + matchQuery: options.matchQuery !== false, // default: true + normalizeQuery: options.normalizeQuery || undefined, + caseSensitive: options.caseSensitive || false + } -class EnvHttpProxyAgent extends DispatcherBase { - #noProxyValue = null - #noProxyEntries = null - #opts = null + // Cache processed header sets to avoid recreating them on every request + this.#headerFilters = createHeaderFilters(this.matchOptions) + + // Request filtering callbacks + this.shouldRecord = options.shouldRecord || (() => true) // function(requestOpts) -> boolean + this.shouldPlayback = options.shouldPlayback || (() => true) // function(requestOpts) -> boolean + + // URL pattern filtering + this.#isUrlExcluded = isUrlExcludedFactory(options.excludeUrls) // Array of regex patterns or strings - constructor (opts = {}) { - super() - this.#opts = opts + // Start auto-flush timer if enabled + if (this.#autoFlush && this.#snapshotPath) { + this.#startAutoFlush() + } + } - if (!experimentalWarned) { - experimentalWarned = true - process.emitWarning('EnvHttpProxyAgent is experimental, expect them to change at any time.', { - code: 'UNDICI-EHPA' - }) + /** + * Records a request-response interaction + * @param {SnapshotRequestOptions} requestOpts - Request options + * @param {SnapshotEntryResponse} response - Response data to record + * @return {Promise} - Resolves when the recording is complete + */ + async record (requestOpts, response) { + // Check if recording should be filtered out + if (!this.shouldRecord(requestOpts)) { + return // Skip recording } - const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts + // Check URL exclusion patterns + if (this.isUrlExcluded(requestOpts)) { + return // Skip recording + } - this[kNoProxyAgent] = new Agent(agentOpts) + const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions) + const hash = createRequestHash(request) - const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY - if (HTTP_PROXY) { - this[kHttpProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTP_PROXY }) - } else { - this[kHttpProxyAgent] = this[kNoProxyAgent] + // Extract response data - always store body as base64 + const normalizedHeaders = normalizeHeaders(response.headers) + + /** @type {SnapshotEntryResponse} */ + const responseData = { + statusCode: response.statusCode, + headers: filterHeadersForStorage(normalizedHeaders, this.#headerFilters, this.matchOptions), + body: Buffer.isBuffer(response.body) + ? response.body.toString('base64') + : Buffer.from(String(response.body || '')).toString('base64'), + trailers: response.trailers } - const HTTPS_PROXY = httpsProxy ?? process.env.https_proxy ?? process.env.HTTPS_PROXY - if (HTTPS_PROXY) { - this[kHttpsProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTPS_PROXY }) + // Remove oldest snapshot if we exceed maxSnapshots limit + if (this.#snapshots.size >= this.#maxSnapshots && !this.#snapshots.has(hash)) { + const oldestKey = this.#snapshots.keys().next().value + this.#snapshots.delete(oldestKey) + } + + // Support sequential responses - if snapshot exists, add to responses array + const existingSnapshot = this.#snapshots.get(hash) + if (existingSnapshot && existingSnapshot.responses) { + existingSnapshot.responses.push(responseData) + existingSnapshot.timestamp = new Date().toISOString() } else { - this[kHttpsProxyAgent] = this[kHttpProxyAgent] + this.#snapshots.set(hash, { + request, + responses: [responseData], // Always store as array for consistency + callCount: 0, + timestamp: new Date().toISOString() + }) } - this.#parseNoProxy() + // Auto-flush if enabled + if (this.#autoFlush && this.#snapshotPath) { + this.#scheduleFlush() + } } - [kDispatch] (opts, handler) { - const url = new URL(opts.origin) - const agent = this.#getProxyAgentForUrl(url) - return agent.dispatch(opts, handler) + /** + * Checks if a URL should be excluded from recording/playback + * @param {SnapshotRequestOptions} requestOpts - Request options to check + * @returns {boolean} - True if URL is excluded + */ + isUrlExcluded (requestOpts) { + const url = new URL(requestOpts.path, requestOpts.origin).toString() + return this.#isUrlExcluded(url) } - async [kClose] () { - await this[kNoProxyAgent].close() - if (!this[kHttpProxyAgent][kClosed]) { - await this[kHttpProxyAgent].close() - } - if (!this[kHttpsProxyAgent][kClosed]) { - await this[kHttpsProxyAgent].close() + /** + * Finds a matching snapshot for the given request + * Returns the appropriate response based on call count for sequential responses + * + * @param {SnapshotRequestOptions} requestOpts - Request options to match + * @returns {SnapshotEntry&Record<'response', SnapshotEntryResponse>|undefined} - Matching snapshot response or undefined if not found + */ + findSnapshot (requestOpts) { + // Check if playback should be filtered out + if (!this.shouldPlayback(requestOpts)) { + return undefined // Skip playback } - } - async [kDestroy] (err) { - await this[kNoProxyAgent].destroy(err) - if (!this[kHttpProxyAgent][kDestroyed]) { - await this[kHttpProxyAgent].destroy(err) + // Check URL exclusion patterns + if (this.isUrlExcluded(requestOpts)) { + return undefined // Skip playback } - if (!this[kHttpsProxyAgent][kDestroyed]) { - await this[kHttpsProxyAgent].destroy(err) - } - } - #getProxyAgentForUrl (url) { - let { protocol, host: hostname, port } = url + const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions) + const hash = createRequestHash(request) + const snapshot = this.#snapshots.get(hash) - // Stripping ports in this way instead of using parsedUrl.hostname to make - // sure that the brackets around IPv6 addresses are kept. - hostname = hostname.replace(/:\d*$/, '').toLowerCase() - port = Number.parseInt(port, 10) || DEFAULT_PORTS[protocol] || 0 - if (!this.#shouldProxy(hostname, port)) { - return this[kNoProxyAgent] - } - if (protocol === 'https:') { - return this[kHttpsProxyAgent] + if (!snapshot) return undefined + + // Handle sequential responses + const currentCallCount = snapshot.callCount || 0 + const responseIndex = Math.min(currentCallCount, snapshot.responses.length - 1) + snapshot.callCount = currentCallCount + 1 + + return { + ...snapshot, + response: snapshot.responses[responseIndex] } - return this[kHttpProxyAgent] } - #shouldProxy (hostname, port) { - if (this.#noProxyChanged) { - this.#parseNoProxy() + /** + * Loads snapshots from file + * @param {string} [filePath] - Optional file path to load snapshots from + * @return {Promise} - Resolves when snapshots are loaded + */ + async loadSnapshots (filePath) { + const path = filePath || this.#snapshotPath + if (!path) { + throw new InvalidArgumentError('Snapshot path is required') } - if (this.#noProxyEntries.length === 0) { - return true // Always proxy if NO_PROXY is not set or empty. - } - if (this.#noProxyValue === '*') { - return false // Never proxy if wildcard is set. - } + try { + const data = await readFile(resolve(path), 'utf8') + const parsed = JSON.parse(data) - for (let i = 0; i < this.#noProxyEntries.length; i++) { - const entry = this.#noProxyEntries[i] - if (entry.port && entry.port !== port) { - continue // Skip if ports don't match. - } - if (!/^[.*]/.test(entry.hostname)) { - // No wildcards, so don't proxy only if there is not an exact match. - if (hostname === entry.hostname) { - return false + // Convert array format back to Map + if (Array.isArray(parsed)) { + this.#snapshots.clear() + for (const { hash, snapshot } of parsed) { + this.#snapshots.set(hash, snapshot) } } else { - // Don't proxy if the hostname ends with the no_proxy host. - if (hostname.endsWith(entry.hostname.replace(/^\*/, ''))) { - return false - } + // Legacy object format + this.#snapshots = new Map(Object.entries(parsed)) } - } - - return true - } - - #parseNoProxy () { - const noProxyValue = this.#opts.noProxy ?? this.#noProxyEnv - const noProxySplit = noProxyValue.split(/[,\s]/) - const noProxyEntries = [] - - for (let i = 0; i < noProxySplit.length; i++) { - const entry = noProxySplit[i] - if (!entry) { - continue + } catch (error) { + if (error.code === 'ENOENT') { + // File doesn't exist yet - that's ok for recording mode + this.#snapshots.clear() + } else { + throw new UndiciError(`Failed to load snapshots from ${path}`, { cause: error }) } - const parsed = entry.match(/^(.+):(\d+)$/) - noProxyEntries.push({ - hostname: (parsed ? parsed[1] : entry).toLowerCase(), - port: parsed ? Number.parseInt(parsed[2], 10) : 0 - }) } - - this.#noProxyValue = noProxyValue - this.#noProxyEntries = noProxyEntries } - get #noProxyChanged () { - if (this.#opts.noProxy !== undefined) { - return false + /** + * Saves snapshots to file + * + * @param {string} [filePath] - Optional file path to save snapshots + * @returns {Promise} - Resolves when snapshots are saved + */ + async saveSnapshots (filePath) { + const path = filePath || this.#snapshotPath + if (!path) { + throw new InvalidArgumentError('Snapshot path is required') } - return this.#noProxyValue !== this.#noProxyEnv - } - - get #noProxyEnv () { - return process.env.no_proxy ?? process.env.NO_PROXY ?? '' - } -} -module.exports = EnvHttpProxyAgent + const resolvedPath = resolve(path) + // Ensure directory exists + await mkdir(dirname(resolvedPath), { recursive: true }) -/***/ }), + // Convert Map to serializable format + const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({ + hash, + snapshot + })) -/***/ 4660: -/***/ ((module) => { + await writeFile(resolvedPath, JSON.stringify(data, null, 2), { flush: true }) + } -"use strict"; -/* eslint-disable */ + /** + * Clears all recorded snapshots + * @returns {void} + */ + clear () { + this.#snapshots.clear() + } + /** + * Gets all recorded snapshots + * @return {Array} - Array of all recorded snapshots + */ + getSnapshots () { + return Array.from(this.#snapshots.values()) + } + /** + * Gets snapshot count + * @return {number} - Number of recorded snapshots + */ + size () { + return this.#snapshots.size + } -// Extracted from node/lib/internal/fixed_queue.js + /** + * Resets call counts for all snapshots (useful for test cleanup) + * @returns {void} + */ + resetCallCounts () { + for (const snapshot of this.#snapshots.values()) { + snapshot.callCount = 0 + } + } -// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. -const kSize = 2048; -const kMask = kSize - 1; + /** + * Deletes a specific snapshot by request options + * @param {SnapshotRequestOptions} requestOpts - Request options to match + * @returns {boolean} - True if snapshot was deleted, false if not found + */ + deleteSnapshot (requestOpts) { + const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions) + const hash = createRequestHash(request) + return this.#snapshots.delete(hash) + } -// The FixedQueue is implemented as a singly-linked list of fixed-size -// circular buffers. It looks something like this: -// -// head tail -// | | -// v v -// +-----------+ <-----\ +-----------+ <------\ +-----------+ -// | [null] | \----- | next | \------- | next | -// +-----------+ +-----------+ +-----------+ -// | item | <-- bottom | item | <-- bottom | [empty] | -// | item | | item | | [empty] | -// | item | | item | | [empty] | -// | item | | item | | [empty] | -// | item | | item | bottom --> | item | -// | item | | item | | item | -// | ... | | ... | | ... | -// | item | | item | | item | -// | item | | item | | item | -// | [empty] | <-- top | item | | item | -// | [empty] | | item | | item | -// | [empty] | | [empty] | <-- top top --> | [empty] | -// +-----------+ +-----------+ +-----------+ -// -// Or, if there is only one circular buffer, it looks something -// like either of these: -// -// head tail head tail -// | | | | -// v v v v -// +-----------+ +-----------+ -// | [null] | | [null] | -// +-----------+ +-----------+ -// | [empty] | | item | -// | [empty] | | item | -// | item | <-- bottom top --> | [empty] | -// | item | | [empty] | -// | [empty] | <-- top bottom --> | item | -// | [empty] | | item | -// +-----------+ +-----------+ -// -// Adding a value means moving `top` forward by one, removing means -// moving `bottom` forward by one. After reaching the end, the queue -// wraps around. -// -// When `top === bottom` the current queue is empty and when -// `top + 1 === bottom` it's full. This wastes a single space of storage -// but allows much quicker checks. + /** + * Gets information about a specific snapshot + * @param {SnapshotRequestOptions} requestOpts - Request options to match + * @returns {SnapshotInfo|null} - Snapshot information or null if not found + */ + getSnapshotInfo (requestOpts) { + const request = formatRequestKey(requestOpts, this.#headerFilters, this.matchOptions) + const hash = createRequestHash(request) + const snapshot = this.#snapshots.get(hash) -class FixedCircularBuffer { - constructor() { - this.bottom = 0; - this.top = 0; - this.list = new Array(kSize); - this.next = null; - } + if (!snapshot) return null - isEmpty() { - return this.top === this.bottom; + return { + hash, + request: snapshot.request, + responseCount: snapshot.responses ? snapshot.responses.length : (snapshot.response ? 1 : 0), // .response for legacy snapshots + callCount: snapshot.callCount || 0, + timestamp: snapshot.timestamp + } } - isFull() { - return ((this.top + 1) & kMask) === this.bottom; - } + /** + * Replaces all snapshots with new data (full replacement) + * @param {Array<{hash: string; snapshot: SnapshotEntry}>|Record} snapshotData - New snapshot data to replace existing ones + * @returns {void} + */ + replaceSnapshots (snapshotData) { + this.#snapshots.clear() - push(data) { - this.list[this.top] = data; - this.top = (this.top + 1) & kMask; + if (Array.isArray(snapshotData)) { + for (const { hash, snapshot } of snapshotData) { + this.#snapshots.set(hash, snapshot) + } + } else if (snapshotData && typeof snapshotData === 'object') { + // Legacy object format + this.#snapshots = new Map(Object.entries(snapshotData)) + } } - shift() { - const nextItem = this.list[this.bottom]; - if (nextItem === undefined) - return null; - this.list[this.bottom] = undefined; - this.bottom = (this.bottom + 1) & kMask; - return nextItem; + /** + * Starts the auto-flush timer + * @returns {void} + */ + #startAutoFlush () { + return this.#scheduleFlush() } -} -module.exports = class FixedQueue { - constructor() { - this.head = this.tail = new FixedCircularBuffer(); + /** + * Stops the auto-flush timer + * @returns {void} + */ + #stopAutoFlush () { + if (this.#flushTimeout) { + clearTimeout(this.#flushTimeout) + // Ensure any pending flush is completed + this.saveSnapshots().catch(() => { + // Ignore flush errors + }) + this.#flushTimeout = null + } } - isEmpty() { - return this.head.isEmpty(); + /** + * Schedules a flush (debounced to avoid excessive writes) + */ + #scheduleFlush () { + this.#flushTimeout = setTimeout(() => { + this.saveSnapshots().catch(() => { + // Ignore flush errors + }) + if (this.#autoFlush) { + this.#flushTimeout?.refresh() + } else { + this.#flushTimeout = null + } + }, 1000) // 1 second debounce } - push(data) { - if (this.head.isFull()) { - // Head is full: Creates a new queue, sets the old queue's `.next` to it, - // and sets it as the new main queue. - this.head = this.head.next = new FixedCircularBuffer(); + /** + * Cleanup method to stop timers + * @returns {void} + */ + destroy () { + this.#stopAutoFlush() + if (this.#flushTimeout) { + clearTimeout(this.#flushTimeout) + this.#flushTimeout = null } - this.head.push(data); } - shift() { - const tail = this.tail; - const next = tail.shift(); - if (tail.isEmpty() && tail.next !== null) { - // If there is another queue, it forms the new tail. - this.tail = tail.next; + /** + * Async close method that saves all recordings and performs cleanup + * @returns {Promise} + */ + async close () { + // Save any pending recordings if we have a snapshot path + if (this.#snapshotPath && this.#snapshots.size !== 0) { + await this.saveSnapshots() } - return next; + + // Perform cleanup + this.destroy() } -}; +} + +module.exports = { SnapshotRecorder, formatRequestKey, createRequestHash, filterHeadersForMatching, filterHeadersForStorage, createHeaderFilters } /***/ }), -/***/ 2128: +/***/ 9683: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const DispatcherBase = __nccwpck_require__(1841) -const FixedQueue = __nccwpck_require__(4660) -const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = __nccwpck_require__(6443) -const PoolStats = __nccwpck_require__(3246) - -const kClients = Symbol('clients') -const kNeedDrain = Symbol('needDrain') -const kQueue = Symbol('queue') -const kClosedResolve = Symbol('closed resolve') -const kOnDrain = Symbol('onDrain') -const kOnConnect = Symbol('onConnect') -const kOnDisconnect = Symbol('onDisconnect') -const kOnConnectionError = Symbol('onConnectionError') -const kGetDispatcher = Symbol('get dispatcher') -const kAddClient = Symbol('add client') -const kRemoveClient = Symbol('remove client') -const kStats = Symbol('stats') - -class PoolBase extends DispatcherBase { - constructor () { - super() - - this[kQueue] = new FixedQueue() - this[kClients] = [] - this[kQueued] = 0 - - const pool = this - - this[kOnDrain] = function onDrain (origin, targets) { - const queue = pool[kQueue] - - let needDrain = false - - while (!needDrain) { - const item = queue.shift() - if (!item) { - break - } - pool[kQueued]-- - needDrain = !this.dispatch(item.opts, item.handler) - } - - this[kNeedDrain] = needDrain - - if (!this[kNeedDrain] && pool[kNeedDrain]) { - pool[kNeedDrain] = false - pool.emit('drain', origin, [pool, ...targets]) - } - - if (pool[kClosedResolve] && queue.isEmpty()) { - Promise - .all(pool[kClients].map(c => c.close())) - .then(pool[kClosedResolve]) - } - } - - this[kOnConnect] = (origin, targets) => { - pool.emit('connect', origin, [pool, ...targets]) - } - - this[kOnDisconnect] = (origin, targets, err) => { - pool.emit('disconnect', origin, [pool, ...targets], err) - } - - this[kOnConnectionError] = (origin, targets, err) => { - pool.emit('connectionError', origin, [pool, ...targets], err) - } - - this[kStats] = new PoolStats(this) - } +const { InvalidArgumentError } = __nccwpck_require__(8707) +const { setHeader } = __nccwpck_require__(3440) +const { runtimeFeatures } = __nccwpck_require__(313) - get [kBusy] () { - return this[kNeedDrain] - } +/** + * @typedef {Object} HeaderFilters + * @property {Set} ignore - Set of headers to ignore for matching + * @property {Set} exclude - Set of headers to exclude from matching + * @property {Set} match - Set of headers to match (empty means match + */ - get [kConnected] () { - return this[kClients].filter(client => client[kConnected]).length - } +/** + * Creates cached header sets for performance + * + * @param {import('./snapshot-recorder').SnapshotRecorderMatchOptions} matchOptions - Matching options for headers + * @returns {HeaderFilters} - Cached sets for ignore, exclude, and match headers + */ +function createHeaderFilters (matchOptions = {}) { + const { ignoreHeaders = [], excludeHeaders = [], matchHeaders = [], caseSensitive = false } = matchOptions - get [kFree] () { - return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length + return { + ignore: new Set(ignoreHeaders.map(header => caseSensitive ? header : header.toLowerCase())), + exclude: new Set(excludeHeaders.map(header => caseSensitive ? header : header.toLowerCase())), + match: new Set(matchHeaders.map(header => caseSensitive ? header : header.toLowerCase())) } +} - get [kPending] () { - let ret = this[kQueued] - for (const { [kPending]: pending } of this[kClients]) { - ret += pending - } - return ret - } +const crypto = runtimeFeatures.has('crypto') + ? __nccwpck_require__(7598) + : null - get [kRunning] () { - let ret = 0 - for (const { [kRunning]: running } of this[kClients]) { - ret += running - } - return ret - } +/** + * @callback HashIdFunction + * @param {string} value - The value to hash + * @returns {string} - The base64url encoded hash of the value + */ - get [kSize] () { - let ret = this[kQueued] - for (const { [kSize]: size } of this[kClients]) { - ret += size - } - return ret - } +/** + * Generates a hash for a given value + * @type {HashIdFunction} + */ +const hashId = crypto?.hash + ? (value) => crypto.hash('sha256', value, 'base64url') + : (value) => Buffer.from(value).toString('base64url') - get stats () { - return this[kStats] - } +/** + * @typedef {(url: string) => boolean} IsUrlExcluded Checks if a URL matches any of the exclude patterns + */ - async [kClose] () { - if (this[kQueue].isEmpty()) { - await Promise.all(this[kClients].map(c => c.close())) - } else { - await new Promise((resolve) => { - this[kClosedResolve] = resolve - }) - } - } +/** @typedef {{[key: Lowercase]: string}} NormalizedHeaders */ +/** @typedef {Array} UndiciHeaders */ +/** @typedef {Record} Headers */ - async [kDestroy] (err) { - while (true) { - const item = this[kQueue].shift() - if (!item) { - break - } - item.handler.onError(err) - } +/** + * @param {*} headers + * @returns {headers is UndiciHeaders} + */ +function isUndiciHeaders (headers) { + return Array.isArray(headers) && (headers.length & 1) === 0 +} - await Promise.all(this[kClients].map(c => c.destroy(err))) +/** + * Factory function to create a URL exclusion checker + * @param {Array} [excludePatterns=[]] - Array of patterns to exclude + * @returns {IsUrlExcluded} - A function that checks if a URL matches any of the exclude patterns + */ +function isUrlExcludedFactory (excludePatterns = []) { + if (excludePatterns.length === 0) { + return () => false } - [kDispatch] (opts, handler) { - const dispatcher = this[kGetDispatcher]() + return function isUrlExcluded (url) { + let urlLowerCased - if (!dispatcher) { - this[kNeedDrain] = true - this[kQueue].push({ opts, handler }) - this[kQueued]++ - } else if (!dispatcher.dispatch(opts, handler)) { - dispatcher[kNeedDrain] = true - this[kNeedDrain] = !this[kGetDispatcher]() + for (const pattern of excludePatterns) { + if (typeof pattern === 'string') { + if (!urlLowerCased) { + // Convert URL to lowercase only once + urlLowerCased = url.toLowerCase() + } + // Simple string match (case-insensitive) + if (urlLowerCased.includes(pattern.toLowerCase())) { + return true + } + } else if (pattern instanceof RegExp) { + // Regex pattern match + if (pattern.test(url)) { + return true + } + } } - return !this[kNeedDrain] + return false } +} - [kAddClient] (client) { - client - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]) +/** + * Normalizes headers for consistent comparison + * + * @param {Object|UndiciHeaders} headers - Headers to normalize + * @returns {NormalizedHeaders} - Normalized headers as a lowercase object + */ +function normalizeHeaders (headers) { + /** @type {NormalizedHeaders} */ + const normalizedHeaders = {} - this[kClients].push(client) + if (!headers) return normalizedHeaders - if (this[kNeedDrain]) { - queueMicrotask(() => { - if (this[kNeedDrain]) { - this[kOnDrain](client[kUrl], [this, client]) - } - }) + // Handle array format (undici internal format: [name, value, name, value, ...]) + if (isUndiciHeaders(headers)) { + for (let i = 0; i < headers.length; i += 2) { + const key = headers[i] + const value = headers[i + 1] + if (key && value !== undefined) { + // Convert Buffers to strings if needed + const keyStr = Buffer.isBuffer(key) ? key.toString() : key + const valueStr = Buffer.isBuffer(value) ? value.toString() : value + setHeader(normalizedHeaders, keyStr.toLowerCase(), valueStr) + } } - - return this + return normalizedHeaders } - [kRemoveClient] (client) { - client.close(() => { - const idx = this[kClients].indexOf(client) - if (idx !== -1) { - this[kClients].splice(idx, 1) + // Handle object format + if (headers && typeof headers === 'object') { + for (const [key, value] of Object.entries(headers)) { + if (key && typeof key === 'string') { + setHeader(normalizedHeaders, key.toLowerCase(), Array.isArray(value) ? value.join(', ') : String(value)) } - }) + } + } - this[kNeedDrain] = this[kClients].some(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )) + return normalizedHeaders +} + +const validSnapshotModes = /** @type {const} */ (['record', 'playback', 'update']) + +/** @typedef {typeof validSnapshotModes[number]} SnapshotMode */ + +/** + * @param {*} mode - The snapshot mode to validate + * @returns {asserts mode is SnapshotMode} + */ +function validateSnapshotMode (mode) { + if (!validSnapshotModes.includes(mode)) { + throw new InvalidArgumentError(`Invalid snapshot mode: ${mode}. Must be one of: ${validSnapshotModes.join(', ')}`) } } module.exports = { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher + createHeaderFilters, + hashId, + isUndiciHeaders, + normalizeHeaders, + isUrlExcludedFactory, + validateSnapshotMode } /***/ }), -/***/ 3246: +/***/ 7659: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = __nccwpck_require__(6443) -const kPool = Symbol('pool') +"use strict"; -class PoolStats { - constructor (pool) { - this[kPool] = pool - } - get connected () { - return this[kPool][kConnected] - } +const { + safeHTTPMethods, + pathHasQueryOrFragment, + hasSafeIterator, + isValidHTTPToken, + setHeader +} = __nccwpck_require__(3440) - get free () { - return this[kPool][kFree] - } +const { serializePathWithQuery } = __nccwpck_require__(3440) +const { kRequestOrigin } = __nccwpck_require__(6443) - get pending () { - return this[kPool][kPending] - } +const MAX_DELTA_SECONDS = 2147483647 +const RESTRICTIVE_DIRECTIVE_NAMES = ['no-store', 'private', 'no-cache'] +const kInvalidCacheControlDirectives = Symbol('invalid cache-control directives') - get queued () { - return this[kPool][kQueued] - } +function trimOWS (value) { + return value.replace(/^[\t ]+|[\t ]+$/g, '') +} - get running () { - return this[kPool][kRunning] +function arrayIncludes (array, value) { + for (let i = 0; i < array.length; i++) { + if (array[i] === value) { + return true + } } - get size () { - return this[kPool][kSize] - } + return false } -module.exports = PoolStats +function trimOWSStart (value) { + return value.replace(/^[\t ]+/, '') +} +function trimOWSEnd (value) { + return value.replace(/[\t ]+$/, '') +} -/***/ }), +function findUnescapedQuote (value, start) { + let escaped = false + for (let i = start; i < value.length; i++) { + if (escaped) { + escaped = false + } else if (value[i] === '\\') { + escaped = true + } else if (value[i] === '"') { + return i + } + } -/***/ 628: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return -1 +} -"use strict"; +function splitCacheControlHeaderValue (value) { + const directives = [] + let start = 0 + let quoteStart = -1 + let inQuote = false + let escaped = false + for (let i = 0; i < value.length; i++) { + if (inQuote) { + if (escaped) { + escaped = false + } else if (value[i] === '\\') { + escaped = true + } else if (value[i] === '"') { + inQuote = false + quoteStart = -1 + } + } else if (value[i] === '"') { + inQuote = true + quoteStart = i + } else if (value[i] === ',') { + directives.push({ value: value.substring(start, i), fromMalformedQuote: false }) + start = i + 1 + } + } + + if (!inQuote) { + directives.push({ value: value.substring(start), fromMalformedQuote: false }) + return directives + } + + const tail = value.substring(start) + const quoteOffset = quoteStart - start + let tailStart = 0 + for (let i = 0; i < tail.length; i++) { + if (tail[i] === ',') { + directives.push({ + value: tail.substring(tailStart, i), + fromMalformedQuote: tailStart > quoteOffset + }) + tailStart = i + 1 + } + } -const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kGetDispatcher -} = __nccwpck_require__(2128) -const Client = __nccwpck_require__(3701) -const { - InvalidArgumentError -} = __nccwpck_require__(8707) -const util = __nccwpck_require__(3440) -const { kUrl, kInterceptors } = __nccwpck_require__(6443) -const buildConnector = __nccwpck_require__(9136) + directives.push({ + value: tail.substring(tailStart), + fromMalformedQuote: tailStart > quoteOffset + }) + return directives +} -const kOptions = Symbol('options') -const kConnections = Symbol('connections') -const kFactory = Symbol('factory') +function markInvalidCacheControlDirective (directives, key) { + let invalidDirectives = directives[kInvalidCacheControlDirectives] -function defaultFactory (origin, opts) { - return new Client(origin, opts) + if (invalidDirectives === undefined) { + invalidDirectives = new Set() + Object.defineProperty(directives, kInvalidCacheControlDirectives, { + value: invalidDirectives + }) + } + + invalidDirectives.add(key) } -class Pool extends PoolBase { - constructor (origin, { - connections, - factory = defaultFactory, - connect, - connectTimeout, - tls, - maxCachedSessions, - socketPath, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - allowH2, - ...options - } = {}) { - super() +function hasInvalidCacheControlDirective (directives, key) { + return directives[kInvalidCacheControlDirectives]?.has(key) === true +} - if (connections != null && (!Number.isFinite(connections) || connections < 0)) { - throw new InvalidArgumentError('invalid connections') +function getMalformedRestrictiveDirectiveName (key) { + for (const directiveName of RESTRICTIVE_DIRECTIVE_NAMES) { + if ( + key.startsWith(directiveName) && + key.length > directiveName.length && + !isValidHTTPToken(key[directiveName.length]) + ) { + return directiveName } + } - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') + let tokenOnlyKey = '' + let hasInvalidTokenChar = false + for (let i = 0; i < key.length; i++) { + if (isValidHTTPToken(key[i])) { + tokenOnlyKey += key[i] + } else { + hasInvalidTokenChar = true } + } - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } + if (hasInvalidTokenChar && arrayIncludes(RESTRICTIVE_DIRECTIVE_NAMES, tokenOnlyKey)) { + return tokenOnlyKey + } +} - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }) +/** + * @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts + */ +function getRequestOrigin (opts) { + const origin = opts[kRequestOrigin] === undefined + ? opts.origin + : opts[kRequestOrigin] + return typeof origin === 'string' || origin instanceof URL + ? origin + : null +} + +/** + * @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts + * @param {string|null|undefined} interceptorOrigin + */ +function getInterceptorOrigin (opts, interceptorOrigin) { + const requestOrigin = getRequestOrigin(opts) + if (interceptorOrigin === undefined) { + return requestOrigin + } + if (interceptorOrigin === null) { + return null + } + if (requestOrigin) { + try { + if (new URL(requestOrigin).origin !== interceptorOrigin) { + return null + } + } catch { + return interceptorOrigin } + } + return interceptorOrigin +} - this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool) - ? options.interceptors.Pool - : [] - this[kConnections] = connections || null - this[kUrl] = util.parseOrigin(origin) - this[kOptions] = { ...util.deepClone(options), connect, allowH2 } - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined - this[kFactory] = factory +/** + * @param {import('../../types/dispatcher.d.ts').default.DispatchOptions} opts + * @param {string|URL|null} [origin] + */ +function makeCacheKey (opts, origin = getRequestOrigin(opts)) { + if (!origin) { + throw new Error('opts.origin is undefined') + } - this.on('connectionError', (origin, targets, error) => { - // If a connection error occurs, we remove the client from the pool, - // and emit a connectionError event. They will not be re-used. - // Fixes https://github.com/nodejs/undici/issues/3895 - for (const target of targets) { - // Do not use kRemoveClient here, as it will close the client, - // but the client cannot be closed in this state. - const idx = this[kClients].indexOf(target) - if (idx !== -1) { - this[kClients].splice(idx, 1) + let fullPath = opts.path || '/' + + if (opts.query && !pathHasQueryOrFragment(fullPath)) { + fullPath = serializePathWithQuery(fullPath, opts.query) + } + + return { + origin: origin.toString(), + method: opts.method, + path: fullPath, + headers: opts.headers + } +} + +function appendHeader (headers, key, val) { + const headerName = key.toLowerCase() + // Reading `headers[headerName]` directly would resolve `__proto__` (and any + // other inherited name) through the prototype chain rather than report the + // header as absent. + const current = Object.hasOwn(headers, headerName) + ? headers[headerName] + : undefined + const values = Array.isArray(val) ? val : [val] + + if (current === undefined) { + setHeader(headers, headerName, Array.isArray(val) ? val.slice() : val) + } else if (Array.isArray(current)) { + current.push(...values) + } else { + setHeader(headers, headerName, [current, ...values]) + } +} + +/** + * @param {Record} + * @returns {Record} + */ +function normalizeHeaders (opts) { + let headers + if (opts.headers == null) { + headers = {} + } else if (typeof opts.headers === 'object') { + headers = {} + + if (hasSafeIterator(opts.headers)) { + if (Array.isArray(opts.headers)) { + // Array format: could be flat alternating [k, v, k, v, ...] + // or array-of-pairs [[k, v], ...] + const first = opts.headers[0] + if (Array.isArray(first)) { + for (const x of opts.headers) { + if (!Array.isArray(x)) { + throw new Error('opts.headers is not a valid header map') + } + const [key, val] = x + if (typeof key !== 'string' || typeof val !== 'string') { + throw new Error('opts.headers is not a valid header map') + } + appendHeader(headers, key, val) + } + } else { + // Flat alternating array [k, v, k, v, ...] + const len = opts.headers.length + if (len % 2 !== 0) { + throw new Error('opts.headers is not a valid header map') + } + for (let i = 0; i < len; i += 2) { + const key = opts.headers[i] + const val = opts.headers[i + 1] + if (typeof key !== 'string' || (typeof val !== 'string' && !Array.isArray(val))) { + throw new Error('opts.headers is not a valid header map') + } + if (typeof val === 'string') { + appendHeader(headers, key, val) + } else { + const mapped = [] + for (let j = 0; j < val.length; j++) { + const v = val[j] + mapped.push(typeof v === 'string' ? v : v.toString('latin1')) + } + appendHeader(headers, key, mapped) + } + } + } + } else { + // Non-array iterable (e.g. Map) — use original iteration logic + for (const x of opts.headers) { + if (!Array.isArray(x)) { + throw new Error('opts.headers is not a valid header map') + } + const [key, val] = x + if (typeof key !== 'string' || typeof val !== 'string') { + throw new Error('opts.headers is not a valid header map') + } + appendHeader(headers, key, val) } } - }) - } - - [kGetDispatcher] () { - for (const client of this[kClients]) { - if (!client[kNeedDrain]) { - return client + } else { + for (const key of Object.keys(opts.headers)) { + appendHeader(headers, key, opts.headers[key]) } } - - if (!this[kConnections] || this[kClients].length < this[kConnections]) { - const dispatcher = this[kFactory](this[kUrl], this[kOptions]) - this[kAddClient](dispatcher) - return dispatcher - } + } else { + throw new Error('opts.headers is not an object') } + + return headers } -module.exports = Pool +/** + * @param {any} key + */ +function assertCacheKey (key) { + if (typeof key !== 'object') { + throw new TypeError(`expected key to be object, got ${typeof key}`) + } + for (const property of ['origin', 'method', 'path']) { + if (typeof key[property] !== 'string') { + throw new TypeError(`expected key.${property} to be string, got ${typeof key[property]}`) + } + } -/***/ }), + if (key.headers !== undefined && typeof key.headers !== 'object') { + throw new TypeError(`expected headers to be object, got ${typeof key}`) + } +} -/***/ 6672: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** + * @param {any} value + */ +function assertCacheValue (value) { + if (typeof value !== 'object') { + throw new TypeError(`expected value to be object, got ${typeof value}`) + } -"use strict"; + for (const property of ['statusCode', 'cachedAt', 'staleAt', 'deleteAt']) { + if (typeof value[property] !== 'number') { + throw new TypeError(`expected value.${property} to be number, got ${typeof value[property]}`) + } + } + if (typeof value.statusMessage !== 'string') { + throw new TypeError(`expected value.statusMessage to be string, got ${typeof value.statusMessage}`) + } -const { kProxy, kClose, kDestroy, kDispatch, kInterceptors } = __nccwpck_require__(6443) -const { URL } = __nccwpck_require__(3136) -const Agent = __nccwpck_require__(7405) -const Pool = __nccwpck_require__(628) -const DispatcherBase = __nccwpck_require__(1841) -const { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = __nccwpck_require__(8707) -const buildConnector = __nccwpck_require__(9136) -const Client = __nccwpck_require__(3701) + if (value.headers != null && typeof value.headers !== 'object') { + throw new TypeError(`expected value.rawHeaders to be object, got ${typeof value.headers}`) + } -const kAgent = Symbol('proxy agent') -const kClient = Symbol('proxy client') -const kProxyHeaders = Symbol('proxy headers') -const kRequestTls = Symbol('request tls settings') -const kProxyTls = Symbol('proxy tls settings') -const kConnectEndpoint = Symbol('connect endpoint function') -const kTunnelProxy = Symbol('tunnel proxy') + if (value.vary !== undefined && typeof value.vary !== 'object') { + throw new TypeError(`expected value.vary to be object, got ${typeof value.vary}`) + } -function defaultProtocolPort (protocol) { - return protocol === 'https:' ? 443 : 80 + if (value.etag !== undefined && typeof value.etag !== 'string') { + throw new TypeError(`expected value.etag to be string, got ${typeof value.etag}`) + } } -function defaultFactory (origin, opts) { - return new Pool(origin, opts) -} +/** + * @see https://www.rfc-editor.org/rfc/rfc9111.html#name-cache-control + * @see https://www.iana.org/assignments/http-cache-directives/http-cache-directives.xhtml -const noop = () => {} + * @param {string | string[]} header + * @returns {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} + */ +function parseCacheControlHeader (header) { + /** + * @type {import('../../types/cache-interceptor.d.ts').default.CacheControlDirectives} + */ + const output = {} + const invalidNumericDirectives = new Set() + const invalidNoArgumentDirectives = new Set() -function defaultAgentFactory (origin, opts) { - if (opts.connections === 1) { - return new Client(origin, opts) - } - return new Pool(origin, opts) -} + const directives = splitCacheControlHeaderValue(Array.isArray(header) ? header.join(',') : header) -class Http1ProxyWrapper extends DispatcherBase { - #client + for (let i = 0; i < directives.length; i++) { + const directiveRecord = directives[i] + const directive = directiveRecord.value.toLowerCase() + const fromMalformedQuote = directiveRecord.fromMalformedQuote + const keyValueDelimiter = directive.indexOf('=') - constructor (proxyUrl, { headers = {}, connect, factory }) { - super() - if (!proxyUrl) { - throw new InvalidArgumentError('Proxy URL is mandatory') + let key + let value + let keyHasTrailingWhitespace = false + let valueHasLeadingWhitespace = false + if (keyValueDelimiter !== -1) { + const rawKey = directive.substring(0, keyValueDelimiter) + const rawValue = directive.substring(keyValueDelimiter + 1) + + keyHasTrailingWhitespace = trimOWSEnd(rawKey) !== rawKey + valueHasLeadingWhitespace = trimOWSStart(rawValue) !== rawValue + key = trimOWS(rawKey) + value = trimOWSStart(rawValue) + } else { + key = trimOWS(directive) } - this[kProxyHeaders] = headers - if (factory) { - this.#client = factory(proxyUrl, { connect }) - } else { - this.#client = new Client(proxyUrl, { connect }) + const malformedRestrictiveDirectiveName = getMalformedRestrictiveDirectiveName(key) + if (malformedRestrictiveDirectiveName !== undefined) { + output[malformedRestrictiveDirectiveName] = true + continue } - } - [kDispatch] (opts, handler) { - const onHeaders = handler.onHeaders - handler.onHeaders = function (statusCode, data, resume) { - if (statusCode === 407) { - if (typeof handler.onError === 'function') { - handler.onError(new InvalidArgumentError('Proxy Authentication Required (407)')) + switch (key) { + case 'min-fresh': + case 'max-stale': + case 'max-age': + case 's-maxage': + case 'stale-while-revalidate': + case 'stale-if-error': { + if (fromMalformedQuote || invalidNumericDirectives.has(key)) { + continue } - return + + if (value === undefined || keyHasTrailingWhitespace || valueHasLeadingWhitespace) { + delete output[key] + invalidNumericDirectives.add(key) + markInvalidCacheControlDirective(output, key) + continue + } + + if ( + value.length >= 2 && + value[0] === '"' && + value[value.length - 1] === '"' + ) { + value = value.substring(1, value.length - 1) + } + + if (!/^[0-9]+$/.test(value)) { + delete output[key] + invalidNumericDirectives.add(key) + markInvalidCacheControlDirective(output, key) + continue + } + + const parsedValue = Math.min(parseInt(value, 10), MAX_DELTA_SECONDS) + + if (key === 'min-fresh') { + if (!(key in output) || output[key] < parsedValue) { + output[key] = parsedValue + } + } else if (!(key in output) || output[key] > parsedValue) { + output[key] = parsedValue + } + + break } - if (onHeaders) onHeaders.call(this, statusCode, data, resume) - } + case 'private': + case 'no-cache': { + if (fromMalformedQuote) { + output[key] = true + break + } - // Rewrite request as an HTTP1 Proxy request, without tunneling. - const { - origin, - path = '/', - headers = {} - } = opts + if (value !== undefined && value.length === 0) { + output[key] = true + break + } - opts.path = origin + path + if (value) { + // The private and no-cache directives can be unqualified (aka just + // `private` or `no-cache`) or qualified (w/ a value). When they're + // qualified, it's a list of headers like `no-cache=header1`, + // `no-cache="header1"`, or `no-cache="header1, header2"` + // If we're given multiple headers, the comma messes us up since + // we split the full header by commas. So, let's loop through the + // remaining parts in front of us until we find one that contains a + // closing quote. We can then skip the consumed quoted-list fragments and + // continue parsing like normal. + // https://www.rfc-editor.org/rfc/rfc9111.html#name-no-cache-2 + if (value[0] === '"') { + // Something like `no-cache="some-header"` OR `no-cache="some-header, another-header"`. + value = trimOWSEnd(value) + + let fieldList = '' + let lastQuotedPart = i + let foundEndingQuote = false + const closingQuote = findUnescapedQuote(value, 1) + + if (closingQuote !== -1) { + fieldList = value.substring(1, closingQuote) + foundEndingQuote = true + } else { + // Something like `no-cache="some-header, another-header"` + // This can still be something invalid, e.g. `no-cache="some-header, ...` + const fieldListParts = [value.substring(1)] + + for (let j = i + 1; j < directives.length; j++) { + const nextPart = trimOWS(directives[j].value) + const closingQuote = findUnescapedQuote(nextPart, 0) + + lastQuotedPart = j + + if (closingQuote !== -1) { + fieldListParts.push(nextPart.substring(0, closingQuote)) + foundEndingQuote = true + break + } - if (!('host' in headers) && !('Host' in headers)) { - const { host } = new URL(origin) - headers.host = host - } - opts.headers = { ...this[kProxyHeaders], ...headers } + fieldListParts.push(nextPart) + } - return this.#client[kDispatch](opts, handler) - } + fieldList = fieldListParts.join(',') + } - async [kClose] () { - return this.#client.close() - } + if (!foundEndingQuote) { + output[key] = true + break + } - async [kDestroy] (err) { - return this.#client.destroy(err) + i = lastQuotedPart + + const headers = fieldList.split(',') + let validFieldNames = true + for (let j = 0; j < headers.length; j++) { + headers[j] = trimOWS(headers[j]) + if (!isValidHTTPToken(headers[j])) { + validFieldNames = false + } + } + + if (!validFieldNames) { + output[key] = true + } else if (output[key] !== true) { + if (key in output) { + output[key] = output[key].concat(headers) + } else { + output[key] = headers + } + } + } else { + // Something like `no-cache=some-header` + const fieldName = trimOWS(value) + + if (!isValidHTTPToken(fieldName)) { + output[key] = true + } else if (output[key] !== true) { + if (key in output) { + output[key] = output[key].concat(fieldName) + } else { + output[key] = [fieldName] + } + } + } + + break + } + } + // eslint-disable-next-line no-fallthrough + case 'public': + case 'must-revalidate': + case 'proxy-revalidate': + case 'immutable': + case 'no-transform': + case 'must-understand': + case 'only-if-cached': + if (fromMalformedQuote || invalidNoArgumentDirectives.has(key)) { + continue + } + + if (value !== undefined) { + // These are qualified (something like `public=...`) when they aren't + // allowed to be, skip all instances of the malformed directive. + delete output[key] + invalidNoArgumentDirectives.add(key) + continue + } + + output[key] = true + break + case 'no-store': + output[key] = true + break + default: + // Ignore unknown directives as per https://www.rfc-editor.org/rfc/rfc9111.html#section-5.2.3-1 + continue + } } + + return output } -class ProxyAgent extends DispatcherBase { - constructor (opts) { - super() +/** + * @param {string | string[]} varyHeader Vary header from the server + * @returns {string[]} + */ +function splitVaryHeader (varyHeader) { + const values = Array.isArray(varyHeader) ? varyHeader : [varyHeader] + const output = [] - if (!opts || (typeof opts === 'object' && !(opts instanceof URL) && !opts.uri)) { - throw new InvalidArgumentError('Proxy uri is mandatory') + for (let i = 0; i < values.length; i++) { + const parts = values[i].split(',') + for (let j = 0; j < parts.length; j++) { + output.push(parts[j]) } + } - const { clientFactory = defaultFactory } = opts - if (typeof clientFactory !== 'function') { - throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') + return output +} + +/** + * @param {string | string[]} varyHeader Vary header from the server + * @returns {boolean} + */ +function hasVaryStar (varyHeader) { + const values = splitVaryHeader(varyHeader) + for (let i = 0; i < values.length; i++) { + if (trimOWS(values[i]).indexOf('*') !== -1) { + return true } + } - const { proxyTunnel = true } = opts + return false +} - const url = this.#getUrl(opts) - const { href, origin, port, protocol, username, password, hostname: proxyHostname } = url +/** + * @param {string | string[]} varyHeader Vary header from the server + * @param {Record} headers Request headers + * @returns {Record | undefined} + */ +function parseVaryHeader (varyHeader, headers) { + if (hasVaryStar(varyHeader)) { + return headers + } - this[kProxy] = { uri: href, protocol } - this[kInterceptors] = opts.interceptors?.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) - ? opts.interceptors.ProxyAgent - : [] - this[kRequestTls] = opts.requestTls - this[kProxyTls] = opts.proxyTls - this[kProxyHeaders] = opts.headers || {} - this[kTunnelProxy] = proxyTunnel + const output = /** @type {Record} */ ({}) - if (opts.auth && opts.token) { - throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') - } else if (opts.auth) { - /* @deprecated in favour of opts.token */ - this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` - } else if (opts.token) { - this[kProxyHeaders]['proxy-authorization'] = opts.token - } else if (username && password) { - this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}` - } + const varyingHeaders = splitVaryHeader(varyHeader) - const connect = buildConnector({ ...opts.proxyTls }) - this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }) + for (const header of varyingHeaders) { + const trimmedHeader = trimOWS(header).toLowerCase() - const agentFactory = opts.factory || defaultAgentFactory - const factory = (origin, options) => { - const { protocol } = new URL(origin) - if (!this[kTunnelProxy] && protocol === 'http:' && this[kProxy].protocol === 'http:') { - return new Http1ProxyWrapper(this[kProxy].uri, { - headers: this[kProxyHeaders], - connect, - factory: agentFactory - }) - } - return agentFactory(origin, options) - } - this[kClient] = clientFactory(url, { connect }) - this[kAgent] = new Agent({ - ...opts, - factory, - connect: async (opts, callback) => { - let requestedPath = opts.host - if (!opts.port) { - requestedPath += `:${defaultProtocolPort(opts.protocol)}` - } - try { - const { socket, statusCode } = await this[kClient].connect({ - origin, - port, - path: requestedPath, - signal: opts.signal, - headers: { - ...this[kProxyHeaders], - host: opts.host - }, - servername: this[kProxyTls]?.servername || proxyHostname - }) - if (statusCode !== 200) { - socket.on('error', noop).destroy() - callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)) - } - if (opts.protocol !== 'https:') { - callback(null, socket) - return - } - let servername - if (this[kRequestTls]) { - servername = this[kRequestTls].servername - } else { - servername = opts.servername - } - this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback) - } catch (err) { - if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { - // Throw a custom error to avoid loop in client.js#connect - callback(new SecureProxyConnectionError(err)) - } else { - callback(err) - } - } - } - }) + if (trimmedHeader.length === 0) { + continue + } + + if (!isValidHTTPToken(trimmedHeader)) { + return undefined + } + + const headerValue = headers[trimmedHeader] + output[trimmedHeader] = Array.isArray(headerValue) ? headerValue.slice() : headerValue ?? null } - dispatch (opts, handler) { - const headers = buildHeaders(opts.headers) - throwIfProxyAuthIsSent(headers) + return output +} - if (headers && !('host' in headers) && !('Host' in headers)) { - const { host } = new URL(opts.origin) - headers.host = host - } +/** + * @param {string | string[]} varyHeader Vary header from the server + * @returns {boolean} + */ +function isInvalidOrWildcardVaryHeader (varyHeader) { + return hasVaryStar(varyHeader) || parseVaryHeader(varyHeader, {}) === undefined +} - return this[kAgent].dispatch( - { - ...opts, - headers - }, - handler - ) +/** + * Note: this deviates from the spec a little. Empty etags ("", W/"") are valid, + * however, including them in cached resposnes serves little to no purpose. + * + * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-etag + * + * @param {string} etag + * @returns {boolean} + */ +function isEtagUsable (etag) { + if (etag.length <= 2) { + // Shortest an etag can be is two chars (just ""). This is where we deviate + // from the spec requiring a min of 3 chars however + return false } - /** - * @param {import('../types/proxy-agent').ProxyAgent.Options | string | URL} opts - * @returns {URL} - */ - #getUrl (opts) { - if (typeof opts === 'string') { - return new URL(opts) - } else if (opts instanceof URL) { - return opts - } else { - return new URL(opts.uri) + if (etag[0] === '"' && etag[etag.length - 1] === '"') { + // ETag: ""asd123"" or ETag: "W/"asd123"", kinda undefined behavior in the + // spec. Some servers will accept these while others don't. + // ETag: "asd123" + return !(etag[1] === '"' || etag.startsWith('"W/')) + } + + if (etag.startsWith('W/"') && etag[etag.length - 1] === '"') { + // ETag: W/"", also where we deviate from the spec & require a min of 3 + // chars + // ETag: for W/"", W/"asd123" + return etag.length !== 4 + } + + // Anything else + return false +} + +/** + * @param {unknown} store + * @returns {asserts store is import('../../types/cache-interceptor.d.ts').default.CacheStore} + */ +function assertCacheStore (store, name = 'CacheStore') { + if (typeof store !== 'object' || store === null) { + throw new TypeError(`expected type of ${name} to be a CacheStore, got ${store === null ? 'null' : typeof store}`) + } + + for (const fn of ['get', 'createWriteStream', 'delete']) { + if (typeof store[fn] !== 'function') { + throw new TypeError(`${name} needs to have a \`${fn}()\` function`) } } +} +/** + * @param {unknown} methods + * @returns {asserts methods is import('../../types/cache-interceptor.d.ts').default.CacheMethods[]} + */ +function assertCacheMethods (methods, name = 'CacheMethods') { + if (!Array.isArray(methods)) { + throw new TypeError(`expected type of ${name} needs to be an array, got ${methods === null ? 'null' : typeof methods}`) + } - async [kClose] () { - await this[kAgent].close() - await this[kClient].close() + if (methods.length === 0) { + throw new TypeError(`${name} needs to have at least one method`) } - async [kDestroy] () { - await this[kAgent].destroy() - await this[kClient].destroy() + for (const method of methods) { + if (!arrayIncludes(safeHTTPMethods, method)) { + throw new TypeError(`element of ${name}-array needs to be one of following values: ${safeHTTPMethods.join(', ')}, got ${method}`) + } } } /** - * @param {string[] | Record} headers - * @returns {Record} + * Creates a string key for request deduplication purposes. + * This key is used to identify in-flight requests that can be shared. + * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey + * @param {Set} [excludeHeaders] Set of lowercase header names to exclude from the key + * @returns {string} */ -function buildHeaders (headers) { - // When using undici.fetch, the headers list is stored - // as an array. - if (Array.isArray(headers)) { - /** @type {Record} */ - const headersPair = {} +function makeDeduplicationKey (cacheKey, excludeHeaders) { + // Use JSON.stringify to produce a collision-resistant key. + // Previous format used `:` and `=` delimiters without escaping, which + // allowed different header sets to produce identical keys (e.g. + // {a:"x:b=y"} vs {a:"x", b:"y"}). See: https://github.com/nodejs/undici/issues/5012 + const headers = {} - for (let i = 0; i < headers.length; i += 2) { - headersPair[headers[i]] = headers[i + 1] + if (cacheKey.headers) { + const sortedHeaders = Object.keys(cacheKey.headers).sort() + for (const header of sortedHeaders) { + // Skip excluded headers + if (excludeHeaders?.has(header.toLowerCase())) { + continue + } + setHeader(headers, header, cacheKey.headers[header]) } + } - return headersPair + return JSON.stringify([cacheKey.origin, cacheKey.method, cacheKey.path, headers]) +} + +module.exports = { + getInterceptorOrigin, + getRequestOrigin, + makeCacheKey, + normalizeHeaders, + assertCacheKey, + assertCacheValue, + parseCacheControlHeader, + hasInvalidCacheControlDirective, + parseVaryHeader, + hasVaryStar, + isInvalidOrWildcardVaryHeader, + isEtagUsable, + assertCacheMethods, + assertCacheStore, + makeDeduplicationKey +} + + +/***/ }), + +/***/ 5453: +/***/ ((module) => { + +"use strict"; + + +/** + * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-date-time-formats + * + * @param {string} date + * @returns {Date | undefined} + */ +function parseHttpDate (date) { + // Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate + // Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format + // Sunday, 06-Nov-94 08:49:37 GMT ; obsolete RFC 850 format + + switch (date[3]) { + case ',': return parseImfDate(date) + case ' ': return parseAscTimeDate(date) + default: return parseRfc850Date(date) } +} - return headers +function makeDate (year, monthIdx, day, hour, minute, second, weekday) { + const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second)) + + // Date.UTC treats years 0-99 as 1900-1999. Reset the full year so component + // checks below validate the HTTP date as written. + if (year >= 0 && year <= 99) { + result.setUTCFullYear(year) + } + + return result.getUTCFullYear() === year && + result.getUTCMonth() === monthIdx && + result.getUTCDate() === day && + result.getUTCHours() === hour && + result.getUTCMinutes() === minute && + result.getUTCSeconds() === second && + result.getUTCDay() === weekday + ? result + : undefined } /** - * @param {Record} headers + * @see https://httpwg.org/specs/rfc9110.html#preferred.date.format * - * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers - * Nevertheless, it was changed and to avoid a security vulnerability by end users - * this check was created. - * It should be removed in the next major version for performance reasons + * @param {string} date + * @returns {Date | undefined} */ -function throwIfProxyAuthIsSent (headers) { - const existProxyAuth = headers && Object.keys(headers) - .find((key) => key.toLowerCase() === 'proxy-authorization') - if (existProxyAuth) { - throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') +function parseImfDate (date) { + if ( + date.length !== 29 || + date[4] !== ' ' || + date[7] !== ' ' || + date[11] !== ' ' || + date[16] !== ' ' || + date[19] !== ':' || + date[22] !== ':' || + date[25] !== ' ' || + date[26] !== 'G' || + date[27] !== 'M' || + date[28] !== 'T' + ) { + return undefined + } + + let weekday = -1 + if (date[0] === 'S' && date[1] === 'u' && date[2] === 'n') { // Sunday + weekday = 0 + } else if (date[0] === 'M' && date[1] === 'o' && date[2] === 'n') { // Monday + weekday = 1 + } else if (date[0] === 'T' && date[1] === 'u' && date[2] === 'e') { // Tuesday + weekday = 2 + } else if (date[0] === 'W' && date[1] === 'e' && date[2] === 'd') { // Wednesday + weekday = 3 + } else if (date[0] === 'T' && date[1] === 'h' && date[2] === 'u') { // Thursday + weekday = 4 + } else if (date[0] === 'F' && date[1] === 'r' && date[2] === 'i') { // Friday + weekday = 5 + } else if (date[0] === 'S' && date[1] === 'a' && date[2] === 't') { // Saturday + weekday = 6 + } else { + return undefined // Not a valid day of the week + } + + let day = 0 + if (date[5] === '0') { + // Single digit day, e.g. "Sun Nov 6 08:49:37 1994" + const code = date.charCodeAt(6) + if (code < 49 || code > 57) { + return undefined // Not a digit + } + day = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(5) + if (code1 < 49 || code1 > 51) { + return undefined // Not a digit between 1 and 3 + } + const code2 = date.charCodeAt(6) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + day = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } + + let monthIdx = -1 + if ( + (date[8] === 'J' && date[9] === 'a' && date[10] === 'n') + ) { + monthIdx = 0 // Jan + } else if ( + (date[8] === 'F' && date[9] === 'e' && date[10] === 'b') + ) { + monthIdx = 1 // Feb + } else if ( + (date[8] === 'M' && date[9] === 'a') + ) { + if (date[10] === 'r') { + monthIdx = 2 // Mar + } else if (date[10] === 'y') { + monthIdx = 4 // May + } else { + return undefined // Invalid month + } + } else if ( + (date[8] === 'J') + ) { + if (date[9] === 'a' && date[10] === 'n') { + monthIdx = 0 // Jan + } else if (date[9] === 'u') { + if (date[10] === 'n') { + monthIdx = 5 // Jun + } else if (date[10] === 'l') { + monthIdx = 6 // Jul + } else { + return undefined // Invalid month + } + } else { + return undefined // Invalid month + } + } else if ( + (date[8] === 'A') + ) { + if (date[9] === 'p' && date[10] === 'r') { + monthIdx = 3 // Apr + } else if (date[9] === 'u' && date[10] === 'g') { + monthIdx = 7 // Aug + } else { + return undefined // Invalid month + } + } else if ( + (date[8] === 'S' && date[9] === 'e' && date[10] === 'p') + ) { + monthIdx = 8 // Sep + } else if ( + (date[8] === 'O' && date[9] === 'c' && date[10] === 't') + ) { + monthIdx = 9 // Oct + } else if ( + (date[8] === 'N' && date[9] === 'o' && date[10] === 'v') + ) { + monthIdx = 10 // Nov + } else if ( + (date[8] === 'D' && date[9] === 'e' && date[10] === 'c') + ) { + monthIdx = 11 // Dec + } else { + // Not a valid month + return undefined + } + + const yearDigit1 = date.charCodeAt(12) + if (yearDigit1 < 48 || yearDigit1 > 57) { + return undefined // Not a digit + } + const yearDigit2 = date.charCodeAt(13) + if (yearDigit2 < 48 || yearDigit2 > 57) { + return undefined // Not a digit + } + const yearDigit3 = date.charCodeAt(14) + if (yearDigit3 < 48 || yearDigit3 > 57) { + return undefined // Not a digit + } + const yearDigit4 = date.charCodeAt(15) + if (yearDigit4 < 48 || yearDigit4 > 57) { + return undefined // Not a digit + } + const year = (yearDigit1 - 48) * 1000 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48) + + let hour = 0 + if (date[17] === '0') { + const code = date.charCodeAt(18) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + hour = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(17) + if (code1 < 48 || code1 > 50) { + return undefined // Not a digit between 0 and 2 + } + const code2 = date.charCodeAt(18) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + if (code1 === 50 && code2 > 51) { + return undefined // Hour cannot be greater than 23 + } + hour = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } + + let minute = 0 + if (date[20] === '0') { + const code = date.charCodeAt(21) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + minute = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(20) + if (code1 < 48 || code1 > 53) { + return undefined // Not a digit between 0 and 5 + } + const code2 = date.charCodeAt(21) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + minute = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } + + let second = 0 + if (date[23] === '0') { + const code = date.charCodeAt(24) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + second = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(23) + if (code1 < 48 || code1 > 53) { + return undefined // Not a digit between 0 and 5 + } + const code2 = date.charCodeAt(24) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number } + + return makeDate(year, monthIdx, day, hour, minute, second, weekday) } -module.exports = ProxyAgent +/** + * @see https://httpwg.org/specs/rfc9110.html#obsolete.date.formats + * + * @param {string} date + * @returns {Date | undefined} + */ +function parseAscTimeDate (date) { + // This is assumed to be in UTC + if ( + date.length !== 24 || + date[7] !== ' ' || + date[10] !== ' ' || + date[19] !== ' ' + ) { + return undefined + } -/***/ }), + let weekday = -1 + if (date[0] === 'S' && date[1] === 'u' && date[2] === 'n') { // Sunday + weekday = 0 + } else if (date[0] === 'M' && date[1] === 'o' && date[2] === 'n') { // Monday + weekday = 1 + } else if (date[0] === 'T' && date[1] === 'u' && date[2] === 'e') { // Tuesday + weekday = 2 + } else if (date[0] === 'W' && date[1] === 'e' && date[2] === 'd') { // Wednesday + weekday = 3 + } else if (date[0] === 'T' && date[1] === 'h' && date[2] === 'u') { // Thursday + weekday = 4 + } else if (date[0] === 'F' && date[1] === 'r' && date[2] === 'i') { // Friday + weekday = 5 + } else if (date[0] === 'S' && date[1] === 'a' && date[2] === 't') { // Saturday + weekday = 6 + } else { + return undefined // Not a valid day of the week + } -/***/ 50: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let monthIdx = -1 + if ( + (date[4] === 'J' && date[5] === 'a' && date[6] === 'n') + ) { + monthIdx = 0 // Jan + } else if ( + (date[4] === 'F' && date[5] === 'e' && date[6] === 'b') + ) { + monthIdx = 1 // Feb + } else if ( + (date[4] === 'M' && date[5] === 'a') + ) { + if (date[6] === 'r') { + monthIdx = 2 // Mar + } else if (date[6] === 'y') { + monthIdx = 4 // May + } else { + return undefined // Invalid month + } + } else if ( + (date[4] === 'J') + ) { + if (date[5] === 'a' && date[6] === 'n') { + monthIdx = 0 // Jan + } else if (date[5] === 'u') { + if (date[6] === 'n') { + monthIdx = 5 // Jun + } else if (date[6] === 'l') { + monthIdx = 6 // Jul + } else { + return undefined // Invalid month + } + } else { + return undefined // Invalid month + } + } else if ( + (date[4] === 'A') + ) { + if (date[5] === 'p' && date[6] === 'r') { + monthIdx = 3 // Apr + } else if (date[5] === 'u' && date[6] === 'g') { + monthIdx = 7 // Aug + } else { + return undefined // Invalid month + } + } else if ( + (date[4] === 'S' && date[5] === 'e' && date[6] === 'p') + ) { + monthIdx = 8 // Sep + } else if ( + (date[4] === 'O' && date[5] === 'c' && date[6] === 't') + ) { + monthIdx = 9 // Oct + } else if ( + (date[4] === 'N' && date[5] === 'o' && date[6] === 'v') + ) { + monthIdx = 10 // Nov + } else if ( + (date[4] === 'D' && date[5] === 'e' && date[6] === 'c') + ) { + monthIdx = 11 // Dec + } else { + // Not a valid month + return undefined + } -"use strict"; + let day = 0 + if (date[8] === ' ') { + // Single digit day, e.g. "Sun Nov 6 08:49:37 1994" + const code = date.charCodeAt(9) + if (code < 49 || code > 57) { + return undefined // Not a digit + } + day = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(8) + if (code1 < 49 || code1 > 51) { + return undefined // Not a digit between 1 and 3 + } + const code2 = date.charCodeAt(9) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + day = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } + let hour = 0 + if (date[11] === '0') { + const code = date.charCodeAt(12) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + hour = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(11) + if (code1 < 48 || code1 > 50) { + return undefined // Not a digit between 0 and 2 + } + const code2 = date.charCodeAt(12) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + if (code1 === 50 && code2 > 51) { + return undefined // Hour cannot be greater than 23 + } + hour = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } -const Dispatcher = __nccwpck_require__(883) -const RetryHandler = __nccwpck_require__(7816) + let minute = 0 + if (date[14] === '0') { + const code = date.charCodeAt(15) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + minute = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(14) + if (code1 < 48 || code1 > 53) { + return undefined // Not a digit between 0 and 5 + } + const code2 = date.charCodeAt(15) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + minute = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } -class RetryAgent extends Dispatcher { - #agent = null - #options = null - constructor (agent, options = {}) { - super(options) - this.#agent = agent - this.#options = options + let second = 0 + if (date[17] === '0') { + const code = date.charCodeAt(18) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + second = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(17) + if (code1 < 48 || code1 > 53) { + return undefined // Not a digit between 0 and 5 + } + const code2 = date.charCodeAt(18) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number } - dispatch (opts, handler) { - const retry = new RetryHandler({ - ...opts, - retryOptions: this.#options - }, { - dispatch: this.#agent.dispatch.bind(this.#agent), - handler - }) - return this.#agent.dispatch(opts, retry) + const yearDigit1 = date.charCodeAt(20) + if (yearDigit1 < 48 || yearDigit1 > 57) { + return undefined // Not a digit + } + const yearDigit2 = date.charCodeAt(21) + if (yearDigit2 < 48 || yearDigit2 > 57) { + return undefined // Not a digit + } + const yearDigit3 = date.charCodeAt(22) + if (yearDigit3 < 48 || yearDigit3 > 57) { + return undefined // Not a digit + } + const yearDigit4 = date.charCodeAt(23) + if (yearDigit4 < 48 || yearDigit4 > 57) { + return undefined // Not a digit } + const year = (yearDigit1 - 48) * 1000 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48) - close () { - return this.#agent.close() + return makeDate(year, monthIdx, day, hour, minute, second, weekday) +} + +/** + * @see https://httpwg.org/specs/rfc9110.html#obsolete.date.formats + * + * @param {string} date + * @returns {Date | undefined} + */ +function parseRfc850Date (date) { + let commaIndex = -1 + + let weekday = -1 + if (date[0] === 'S') { + if (date[1] === 'u' && date[2] === 'n' && date[3] === 'd' && date[4] === 'a' && date[5] === 'y') { + weekday = 0 // Sunday + commaIndex = 6 + } else if (date[1] === 'a' && date[2] === 't' && date[3] === 'u' && date[4] === 'r' && date[5] === 'd' && date[6] === 'a' && date[7] === 'y') { + weekday = 6 // Saturday + commaIndex = 8 + } + } else if (date[0] === 'M' && date[1] === 'o' && date[2] === 'n' && date[3] === 'd' && date[4] === 'a' && date[5] === 'y') { + weekday = 1 // Monday + commaIndex = 6 + } else if (date[0] === 'T') { + if (date[1] === 'u' && date[2] === 'e' && date[3] === 's' && date[4] === 'd' && date[5] === 'a' && date[6] === 'y') { + weekday = 2 // Tuesday + commaIndex = 7 + } else if (date[1] === 'h' && date[2] === 'u' && date[3] === 'r' && date[4] === 's' && date[5] === 'd' && date[6] === 'a' && date[7] === 'y') { + weekday = 4 // Thursday + commaIndex = 8 + } + } else if (date[0] === 'W' && date[1] === 'e' && date[2] === 'd' && date[3] === 'n' && date[4] === 'e' && date[5] === 's' && date[6] === 'd' && date[7] === 'a' && date[8] === 'y') { + weekday = 3 // Wednesday + commaIndex = 9 + } else if (date[0] === 'F' && date[1] === 'r' && date[2] === 'i' && date[3] === 'd' && date[4] === 'a' && date[5] === 'y') { + weekday = 5 // Friday + commaIndex = 6 + } else { + // Not a valid day name + return undefined } - destroy () { - return this.#agent.destroy() + if ( + date[commaIndex] !== ',' || + (date.length - commaIndex - 1) !== 23 || + date[commaIndex + 1] !== ' ' || + date[commaIndex + 4] !== '-' || + date[commaIndex + 8] !== '-' || + date[commaIndex + 11] !== ' ' || + date[commaIndex + 14] !== ':' || + date[commaIndex + 17] !== ':' || + date[commaIndex + 20] !== ' ' || + date[commaIndex + 21] !== 'G' || + date[commaIndex + 22] !== 'M' || + date[commaIndex + 23] !== 'T' + ) { + return undefined } -} - -module.exports = RetryAgent + let day = 0 + if (date[commaIndex + 2] === '0') { + // Single digit day, e.g. "Sun Nov 6 08:49:37 1994" + const code = date.charCodeAt(commaIndex + 3) + if (code < 49 || code > 57) { + return undefined // Not a digit + } + day = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(commaIndex + 2) + if (code1 < 49 || code1 > 51) { + return undefined // Not a digit between 1 and 3 + } + const code2 = date.charCodeAt(commaIndex + 3) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + day = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } -/***/ }), + let monthIdx = -1 + if ( + (date[commaIndex + 5] === 'J' && date[commaIndex + 6] === 'a' && date[commaIndex + 7] === 'n') + ) { + monthIdx = 0 // Jan + } else if ( + (date[commaIndex + 5] === 'F' && date[commaIndex + 6] === 'e' && date[commaIndex + 7] === 'b') + ) { + monthIdx = 1 // Feb + } else if ( + (date[commaIndex + 5] === 'M' && date[commaIndex + 6] === 'a' && date[commaIndex + 7] === 'r') + ) { + monthIdx = 2 // Mar + } else if ( + (date[commaIndex + 5] === 'A' && date[commaIndex + 6] === 'p' && date[commaIndex + 7] === 'r') + ) { + monthIdx = 3 // Apr + } else if ( + (date[commaIndex + 5] === 'M' && date[commaIndex + 6] === 'a' && date[commaIndex + 7] === 'y') + ) { + monthIdx = 4 // May + } else if ( + (date[commaIndex + 5] === 'J' && date[commaIndex + 6] === 'u' && date[commaIndex + 7] === 'n') + ) { + monthIdx = 5 // Jun + } else if ( + (date[commaIndex + 5] === 'J' && date[commaIndex + 6] === 'u' && date[commaIndex + 7] === 'l') + ) { + monthIdx = 6 // Jul + } else if ( + (date[commaIndex + 5] === 'A' && date[commaIndex + 6] === 'u' && date[commaIndex + 7] === 'g') + ) { + monthIdx = 7 // Aug + } else if ( + (date[commaIndex + 5] === 'S' && date[commaIndex + 6] === 'e' && date[commaIndex + 7] === 'p') + ) { + monthIdx = 8 // Sep + } else if ( + (date[commaIndex + 5] === 'O' && date[commaIndex + 6] === 'c' && date[commaIndex + 7] === 't') + ) { + monthIdx = 9 // Oct + } else if ( + (date[commaIndex + 5] === 'N' && date[commaIndex + 6] === 'o' && date[commaIndex + 7] === 'v') + ) { + monthIdx = 10 // Nov + } else if ( + (date[commaIndex + 5] === 'D' && date[commaIndex + 6] === 'e' && date[commaIndex + 7] === 'c') + ) { + monthIdx = 11 // Dec + } else { + // Not a valid month + return undefined + } -/***/ 2581: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const yearDigit1 = date.charCodeAt(commaIndex + 9) + if (yearDigit1 < 48 || yearDigit1 > 57) { + return undefined // Not a digit + } + const yearDigit2 = date.charCodeAt(commaIndex + 10) + if (yearDigit2 < 48 || yearDigit2 > 57) { + return undefined // Not a digit + } -"use strict"; + let year = (yearDigit1 - 48) * 10 + (yearDigit2 - 48) // Convert ASCII codes to number + // RFC 6265 states that the year is in the range 1970-2069. + // @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.1 + // + // 3. If the year-value is greater than or equal to 70 and less than or + // equal to 99, increment the year-value by 1900. + // 4. If the year-value is greater than or equal to 0 and less than or + // equal to 69, increment the year-value by 2000. + year += year < 70 ? 2000 : 1900 -// We include a version number for the Dispatcher API. In case of breaking changes, -// this version number must be increased to avoid conflicts. -const globalDispatcher = Symbol.for('undici.globalDispatcher.1') -const { InvalidArgumentError } = __nccwpck_require__(8707) -const Agent = __nccwpck_require__(7405) + let hour = 0 + if (date[commaIndex + 12] === '0') { + const code = date.charCodeAt(commaIndex + 13) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + hour = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(commaIndex + 12) + if (code1 < 48 || code1 > 50) { + return undefined // Not a digit between 0 and 2 + } + const code2 = date.charCodeAt(commaIndex + 13) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + if (code1 === 50 && code2 > 51) { + return undefined // Hour cannot be greater than 23 + } + hour = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } -if (getGlobalDispatcher() === undefined) { - setGlobalDispatcher(new Agent()) -} + let minute = 0 + if (date[commaIndex + 15] === '0') { + const code = date.charCodeAt(commaIndex + 16) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + minute = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(commaIndex + 15) + if (code1 < 48 || code1 > 53) { + return undefined // Not a digit between 0 and 5 + } + const code2 = date.charCodeAt(commaIndex + 16) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + minute = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number + } -function setGlobalDispatcher (agent) { - if (!agent || typeof agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument agent must implement Agent') + let second = 0 + if (date[commaIndex + 18] === '0') { + const code = date.charCodeAt(commaIndex + 19) + if (code < 48 || code > 57) { + return undefined // Not a digit + } + second = code - 48 // Convert ASCII code to number + } else { + const code1 = date.charCodeAt(commaIndex + 18) + if (code1 < 48 || code1 > 53) { + return undefined // Not a digit between 0 and 5 + } + const code2 = date.charCodeAt(commaIndex + 19) + if (code2 < 48 || code2 > 57) { + return undefined // Not a digit + } + second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number } - Object.defineProperty(globalThis, globalDispatcher, { - value: agent, - writable: true, - enumerable: false, - configurable: false - }) -} -function getGlobalDispatcher () { - return globalThis[globalDispatcher] + return makeDate(year, monthIdx, day, hour, minute, second, weekday) } module.exports = { - setGlobalDispatcher, - getGlobalDispatcher + parseHttpDate } /***/ }), -/***/ 8155: -/***/ ((module) => { +/***/ 313: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = class DecoratorHandler { - #handler +/** @typedef {`node:${string}`} NodeModuleName */ - constructor (handler) { - if (typeof handler !== 'object' || handler === null) { - throw new TypeError('handler must be an object') - } - this.#handler = handler - } +/** @type {Record any>} */ +const lazyLoaders = { + __proto__: null, + 'node:crypto': () => __nccwpck_require__(7598), + 'node:sqlite': () => __nccwpck_require__(99) +} - onConnect (...args) { - return this.#handler.onConnect?.(...args) +/** + * @param {NodeModuleName} moduleName + * @returns {boolean} + */ +function detectRuntimeFeatureByNodeModule (moduleName) { + try { + lazyLoaders[moduleName]() + return true + } catch (err) { + if (err.code !== 'ERR_UNKNOWN_BUILTIN_MODULE' && err.code !== 'ERR_NO_CRYPTO') { + throw err + } + return false } +} - onError (...args) { - return this.#handler.onError?.(...args) - } +const runtimeFeaturesAsNodeModule = /** @type {const} */ (['crypto', 'sqlite']) +/** @typedef {typeof runtimeFeaturesAsNodeModule[number]} RuntimeFeatureByNodeModule */ +/** @typedef {RuntimeFeatureByNodeModule} Feature */ - onUpgrade (...args) { - return this.#handler.onUpgrade?.(...args) +/** + * @param {Feature} feature + * @returns {boolean} + */ +function detectRuntimeFeature (feature) { + if (runtimeFeaturesAsNodeModule.includes(/** @type {RuntimeFeatureByNodeModule} */ (feature))) { + return detectRuntimeFeatureByNodeModule(`node:${feature}`) } + throw new TypeError(`unknown feature: ${feature}`) +} - onResponseStarted (...args) { - return this.#handler.onResponseStarted?.(...args) - } +/** + * @class + * @name RuntimeFeatures + */ +class RuntimeFeatures { + /** @type {Map} */ + #map = new Map() - onHeaders (...args) { - return this.#handler.onHeaders?.(...args) + /** + * Clears all cached feature detections. + */ + clear () { + this.#map.clear() } - onData (...args) { - return this.#handler.onData?.(...args) + /** + * @param {Feature} feature + * @returns {boolean} + */ + has (feature) { + return ( + this.#map.get(feature) ?? this.#detectRuntimeFeature(feature) + ) } - onComplete (...args) { - return this.#handler.onComplete?.(...args) + /** + * @param {Feature} feature + * @param {boolean} value + */ + set (feature, value) { + if (runtimeFeaturesAsNodeModule.includes(feature) === false) { + throw new TypeError(`unknown feature: ${feature}`) + } + this.#map.set(feature, value) } - onBodySent (...args) { - return this.#handler.onBodySent?.(...args) + /** + * @param {Feature} feature + * @returns {boolean} + */ + #detectRuntimeFeature (feature) { + const result = detectRuntimeFeature(feature) + this.#map.set(feature, result) + return result } } +const instance = new RuntimeFeatures() + +module.exports.runtimeFeatures = instance +module.exports["default"] = instance + /***/ }), -/***/ 8754: +/***/ 6854: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const util = __nccwpck_require__(3440) -const { kBodyUsed } = __nccwpck_require__(6443) -const assert = __nccwpck_require__(4589) -const { InvalidArgumentError } = __nccwpck_require__(8707) -const EE = __nccwpck_require__(8474) - -const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] - -const kBody = Symbol('body') - -class BodyAsyncIterable { - constructor (body) { - this[kBody] = body - this[kBodyUsed] = false - } +const { + kConnected, + kPending, + kRunning, + kSize, + kFree, + kQueued +} = __nccwpck_require__(6443) - async * [Symbol.asyncIterator] () { - assert(!this[kBodyUsed], 'disturbed') - this[kBodyUsed] = true - yield * this[kBody] +class ClientStats { + constructor (client) { + this.connected = client[kConnected] + this.pending = client[kPending] + this.running = client[kRunning] + this.size = client[kSize] } } -class RedirectHandler { - constructor (dispatch, maxRedirections, opts, handler) { - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } - - util.validateHandler(handler, opts.method, opts.upgrade) - - this.dispatch = dispatch - this.location = null - this.abort = null - this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy - this.maxRedirections = maxRedirections - this.handler = handler - this.history = [] - this.redirectionLimitReached = false - - if (util.isStream(this.opts.body)) { - // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp - // so that it can be dispatched again? - // TODO (fix): Do we need 100-expect support to provide a way to do this properly? - if (util.bodyLength(this.opts.body) === 0) { - this.opts.body - .on('data', function () { - assert(false) - }) - } - - if (typeof this.opts.body.readableDidRead !== 'boolean') { - this.opts.body[kBodyUsed] = false - EE.prototype.on.call(this.opts.body, 'data', function () { - this[kBodyUsed] = true - }) - } - } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { - // TODO (fix): We can't access ReadableStream internal state - // to determine whether or not it has been disturbed. This is just - // a workaround. - this.opts.body = new BodyAsyncIterable(this.opts.body) - } else if ( - this.opts.body && - typeof this.opts.body !== 'string' && - !ArrayBuffer.isView(this.opts.body) && - util.isIterable(this.opts.body) - ) { - // TODO: Should we allow re-using iterable if !this.opts.idempotent - // or through some other flag? - this.opts.body = new BodyAsyncIterable(this.opts.body) - } +class PoolStats { + constructor (pool) { + this.connected = pool[kConnected] + this.free = pool[kFree] + this.pending = pool[kPending] + this.queued = pool[kQueued] + this.running = pool[kRunning] + this.size = pool[kSize] } +} - onConnect (abort) { - this.abort = abort - this.handler.onConnect(abort, { history: this.history }) - } +module.exports = { ClientStats, PoolStats } - onUpgrade (statusCode, headers, socket) { - this.handler.onUpgrade(statusCode, headers, socket) - } - onError (error) { - this.handler.onError(error) - } +/***/ }), - onHeaders (statusCode, headers, resume, statusText) { - this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) - ? null - : parseLocation(statusCode, headers) +/***/ 6603: +/***/ ((module) => { - if (this.opts.throwOnMaxRedirect && this.history.length >= this.maxRedirections) { - if (this.request) { - this.request.abort(new Error('max redirects')) - } +"use strict"; - this.redirectionLimitReached = true - this.abort(new Error('max redirects')) - return - } - if (this.opts.origin) { - this.history.push(new URL(this.opts.path, this.opts.origin)) - } +/** + * This module offers an optimized timer implementation designed for scenarios + * where high precision is not critical. + * + * The timer achieves faster performance by using a low-resolution approach, + * with an accuracy target of within 500ms. This makes it particularly useful + * for timers with delays of 1 second or more, where exact timing is less + * crucial. + * + * It's important to note that Node.js timers are inherently imprecise, as + * delays can occur due to the event loop being blocked by other operations. + * Consequently, timers may trigger later than their scheduled time. + */ - if (!this.location) { - return this.handler.onHeaders(statusCode, headers, resume, statusText) - } +/** + * The fastNow variable contains the internal fast timer clock value. + * + * @type {number} + */ +let fastNow = 0 - const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))) - const path = search ? `${pathname}${search}` : pathname +/** + * RESOLUTION_MS represents the target resolution time in milliseconds. + * + * @type {number} + * @default 1000 + */ +const RESOLUTION_MS = 1e3 - // Remove headers referring to the original URL. - // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. - // https://tools.ietf.org/html/rfc7231#section-6.4 - this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin) - this.opts.path = path - this.opts.origin = origin - this.opts.maxRedirections = 0 - this.opts.query = null +/** + * TICK_MS defines the desired interval in milliseconds between each tick. + * The target value is set to half the resolution time, minus 1 ms, to account + * for potential event loop overhead. + * + * @type {number} + * @default 499 + */ +const TICK_MS = (RESOLUTION_MS >> 1) - 1 - // https://tools.ietf.org/html/rfc7231#section-6.4.4 - // In case of HTTP 303, always replace method to be either HEAD or GET - if (statusCode === 303 && this.opts.method !== 'HEAD') { - this.opts.method = 'GET' - this.opts.body = null - } - } +/** + * fastNowTimeout is a Node.js timer used to manage and process + * the FastTimers stored in the `fastTimers` array. + * + * @type {NodeJS.Timeout} + */ +let fastNowTimeout - onData (chunk) { - if (this.location) { - /* - https://tools.ietf.org/html/rfc7231#section-6.4 +/** + * The kFastTimer symbol is used to identify FastTimer instances. + * + * @type {Symbol} + */ +const kFastTimer = Symbol('kFastTimer') - TLDR: undici always ignores 3xx response bodies. +/** + * The fastTimers array contains all active FastTimers. + * + * @type {FastTimer[]} + */ +const fastTimers = [] - Redirection is used to serve the requested resource from another URL, so it is assumes that - no body is generated (and thus can be ignored). Even though generating a body is not prohibited. +/** + * These constants represent the various states of a FastTimer. + */ - For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually - (which means it's optional and not mandated) contain just an hyperlink to the value of - the Location response header, so the body can be ignored safely. +/** + * The `NOT_IN_LIST` constant indicates that the FastTimer is not included + * in the `fastTimers` array. Timers with this status will not be processed + * during the next tick by the `onTick` function. + * + * A FastTimer can be re-added to the `fastTimers` array by invoking the + * `refresh` method on the FastTimer instance. + * + * @type {-2} + */ +const NOT_IN_LIST = -2 - For status 300, which is "Multiple Choices", the spec mentions both generating a Location - response header AND a response body with the other possible location to follow. - Since the spec explicitly chooses not to specify a format for such body and leave it to - servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. - */ - } else { - return this.handler.onData(chunk) - } - } +/** + * The `TO_BE_CLEARED` constant indicates that the FastTimer is scheduled + * for removal from the `fastTimers` array. A FastTimer in this state will + * be removed in the next tick by the `onTick` function and will no longer + * be processed. + * + * This status is also set when the `clear` method is called on the FastTimer instance. + * + * @type {-1} + */ +const TO_BE_CLEARED = -1 - onComplete (trailers) { - if (this.location) { - /* - https://tools.ietf.org/html/rfc7231#section-6.4 +/** + * The `PENDING` constant signifies that the FastTimer is awaiting processing + * in the next tick by the `onTick` function. Timers with this status will have + * their `_idleStart` value set and their status updated to `ACTIVE` in the next tick. + * + * @type {0} + */ +const PENDING = 0 - TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections - and neither are useful if present. +/** + * The `ACTIVE` constant indicates that the FastTimer is active and waiting + * for its timer to expire. During the next tick, the `onTick` function will + * check if the timer has expired, and if so, it will execute the associated callback. + * + * @type {1} + */ +const ACTIVE = 1 - See comment on onData method above for more detailed information. - */ +/** + * The onTick function processes the fastTimers array. + * + * @returns {void} + */ +function onTick () { + /** + * Increment the fastNow value by the TICK_MS value, despite the actual time + * that has passed since the last tick. This approach ensures independence + * from the system clock and delays caused by a blocked event loop. + * + * @type {number} + */ + fastNow += TICK_MS - this.location = null - this.abort = null + /** + * The `idx` variable is used to iterate over the `fastTimers` array. + * Expired timers are removed by replacing them with the last element in the array. + * Consequently, `idx` is only incremented when the current element is not removed. + * + * @type {number} + */ + let idx = 0 - this.dispatch(this.opts, this) - } else { - this.handler.onComplete(trailers) - } - } + /** + * The len variable will contain the length of the fastTimers array + * and will be decremented when a FastTimer should be removed from the + * fastTimers array. + * + * @type {number} + */ + let len = fastTimers.length - onBodySent (chunk) { - if (this.handler.onBodySent) { - this.handler.onBodySent(chunk) + while (idx < len) { + /** + * @type {FastTimer} + */ + const timer = fastTimers[idx] + + // If the timer is in the ACTIVE state and the timer has expired, it will + // be processed in the next tick. + if (timer._state === PENDING) { + // Set the _idleStart value to the fastNow value minus the TICK_MS value + // to account for the time the timer was in the PENDING state. + timer._idleStart = fastNow - TICK_MS + timer._state = ACTIVE + } else if ( + timer._state === ACTIVE && + fastNow >= timer._idleStart + timer._idleTimeout + ) { + timer._state = TO_BE_CLEARED + timer._idleStart = -1 + timer._onTimeout(timer._timerArg) } - } -} -function parseLocation (statusCode, headers) { - if (redirectableStatusCodes.indexOf(statusCode) === -1) { - return null - } + if (timer._state === TO_BE_CLEARED) { + timer._state = NOT_IN_LIST - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].length === 8 && util.headerNameToString(headers[i]) === 'location') { - return headers[i + 1] + // Move the last element to the current index and decrement len if it is + // not the only element in the array. + if (--len !== 0) { + fastTimers[idx] = fastTimers[len] + } + } else { + ++idx } } -} -// https://tools.ietf.org/html/rfc7231#section-6.4.4 -function shouldRemoveHeader (header, removeContent, unknownOrigin) { - if (header.length === 4) { - return util.headerNameToString(header) === 'host' - } - if (removeContent && util.headerNameToString(header).startsWith('content-')) { - return true - } - if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) { - const name = util.headerNameToString(header) - return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization' + // Set the length of the fastTimers array to the new length and thus + // removing the excess FastTimers elements from the array. + fastTimers.length = len + + // If there are still active FastTimers in the array, refresh the Timer. + // If there are no active FastTimers, the timer will be refreshed again + // when a new FastTimer is instantiated. + if (fastTimers.length !== 0) { + refreshTimeout() } - return false } -// https://tools.ietf.org/html/rfc7231#section-6.4 -function cleanRequestHeaders (headers, removeContent, unknownOrigin) { - const ret = [] - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { - ret.push(headers[i], headers[i + 1]) - } - } - } else if (headers && typeof headers === 'object') { - for (const key of Object.keys(headers)) { - if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { - ret.push(key, headers[key]) - } - } +function refreshTimeout () { + // If the fastNowTimeout is already set and the Timer has the refresh()- + // method available, call it to refresh the timer. + // Some timer objects returned by setTimeout may not have a .refresh() + // method (e.g. mocked timers in tests). + if (fastNowTimeout?.refresh) { + fastNowTimeout.refresh() + // fastNowTimeout is not instantiated yet or refresh is not availabe, + // create a new Timer. } else { - assert(headers == null, 'headers must be an object or an array') + clearTimeout(fastNowTimeout) + fastNowTimeout = setTimeout(onTick, TICK_MS) + // If the Timer has an unref method, call it to allow the process to exit, + // if there are no other active handles. When using fake timers or mocked + // environments (like Jest), .unref() may not be defined, + fastNowTimeout?.unref() } - return ret -} - -module.exports = RedirectHandler - - -/***/ }), - -/***/ 7816: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - -const assert = __nccwpck_require__(4589) - -const { kRetryHandlerDefaultRetry } = __nccwpck_require__(6443) -const { RequestRetryError } = __nccwpck_require__(8707) -const { - isDisturbed, - parseHeaders, - parseRangeHeader, - wrapRequestBody -} = __nccwpck_require__(3440) - -function calculateRetryAfterHeader (retryAfter) { - const current = Date.now() - return new Date(retryAfter).getTime() - current } -class RetryHandler { - constructor (opts, handlers) { - const { retryOptions, ...dispatchOpts } = opts - const { - // Retry scoped - retry: retryFn, - maxRetries, - maxTimeout, - minTimeout, - timeoutFactor, - // Response scoped - methods, - errorCodes, - retryAfter, - statusCodes - } = retryOptions ?? {} - - this.dispatch = handlers.dispatch - this.handler = handlers.handler - this.opts = { ...dispatchOpts, body: wrapRequestBody(opts.body) } - this.abort = null - this.aborted = false - this.retryOpts = { - retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], - retryAfter: retryAfter ?? true, - maxTimeout: maxTimeout ?? 30 * 1000, // 30s, - minTimeout: minTimeout ?? 500, // .5s - timeoutFactor: timeoutFactor ?? 2, - maxRetries: maxRetries ?? 5, - // What errors we should retry - methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], - // Indicates which errors to retry - statusCodes: statusCodes ?? [500, 502, 503, 504, 429], - // List of errors to retry - errorCodes: errorCodes ?? [ - 'ECONNRESET', - 'ECONNREFUSED', - 'ENOTFOUND', - 'ENETDOWN', - 'ENETUNREACH', - 'EHOSTDOWN', - 'EHOSTUNREACH', - 'EPIPE', - 'UND_ERR_SOCKET' - ] - } - - this.retryCount = 0 - this.retryCountCheckpoint = 0 - this.start = 0 - this.end = null - this.etag = null - this.resume = null - - // Handle possible onConnect duplication - this.handler.onConnect(reason => { - this.aborted = true - if (this.abort) { - this.abort(reason) - } else { - this.reason = reason - } - }) - } +/** + * The `FastTimer` class is a data structure designed to store and manage + * timer information. + */ +class FastTimer { + [kFastTimer] = true - onRequestSent () { - if (this.handler.onRequestSent) { - this.handler.onRequestSent() - } - } + /** + * The state of the timer, which can be one of the following: + * - NOT_IN_LIST (-2) + * - TO_BE_CLEARED (-1) + * - PENDING (0) + * - ACTIVE (1) + * + * @type {-2|-1|0|1} + * @private + */ + _state = NOT_IN_LIST - onUpgrade (statusCode, headers, socket) { - if (this.handler.onUpgrade) { - this.handler.onUpgrade(statusCode, headers, socket) - } - } + /** + * The number of milliseconds to wait before calling the callback. + * + * @type {number} + * @private + */ + _idleTimeout = -1 - onConnect (abort) { - if (this.aborted) { - abort(this.reason) - } else { - this.abort = abort - } - } + /** + * The time in milliseconds when the timer was started. This value is used to + * calculate when the timer should expire. + * + * @type {number} + * @default -1 + * @private + */ + _idleStart = -1 - onBodySent (chunk) { - if (this.handler.onBodySent) return this.handler.onBodySent(chunk) - } + /** + * The function to be executed when the timer expires. + * @type {Function} + * @private + */ + _onTimeout - static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { - const { statusCode, code, headers } = err - const { method, retryOptions } = opts - const { - maxRetries, - minTimeout, - maxTimeout, - timeoutFactor, - statusCodes, - errorCodes, - methods - } = retryOptions - const { counter } = state + /** + * The argument to be passed to the callback when the timer expires. + * + * @type {*} + * @private + */ + _timerArg - // Any code that is not a Undici's originated and allowed to retry - if (code && code !== 'UND_ERR_REQ_RETRY' && !errorCodes.includes(code)) { - cb(err) - return - } + /** + * @constructor + * @param {Function} callback A function to be executed after the timer + * expires. + * @param {number} delay The time, in milliseconds that the timer should wait + * before the specified function or code is executed. + * @param {*} arg + */ + constructor (callback, delay, arg) { + this._onTimeout = callback + this._idleTimeout = delay + this._timerArg = arg - // If a set of method are provided and the current method is not in the list - if (Array.isArray(methods) && !methods.includes(method)) { - cb(err) - return - } + this.refresh() + } - // If a set of status code are provided and the current status code is not in the list - if ( - statusCode != null && - Array.isArray(statusCodes) && - !statusCodes.includes(statusCode) - ) { - cb(err) - return + /** + * Sets the timer's start time to the current time, and reschedules the timer + * to call its callback at the previously specified duration adjusted to the + * current time. + * Using this on a timer that has already called its callback will reactivate + * the timer. + * + * @returns {void} + */ + refresh () { + // In the special case that the timer is not in the list of active timers, + // add it back to the array to be processed in the next tick by the onTick + // function. + if (this._state === NOT_IN_LIST) { + fastTimers.push(this) } - // If we reached the max number of retries - if (counter > maxRetries) { - cb(err) - return + // If the timer is the only active timer, refresh the fastNowTimeout for + // better resolution. + if (!fastNowTimeout || fastTimers.length === 1) { + refreshTimeout() } - let retryAfterHeader = headers?.['retry-after'] - if (retryAfterHeader) { - retryAfterHeader = Number(retryAfterHeader) - retryAfterHeader = Number.isNaN(retryAfterHeader) - ? calculateRetryAfterHeader(retryAfterHeader) - : retryAfterHeader * 1e3 // Retry-After is in seconds - } + // Setting the state to PENDING will cause the timer to be reset in the + // next tick by the onTick function. + this._state = PENDING + } - const retryTimeout = - retryAfterHeader > 0 - ? Math.min(retryAfterHeader, maxTimeout) - : Math.min(minTimeout * timeoutFactor ** (counter - 1), maxTimeout) + /** + * The `clear` method cancels the timer, preventing it from executing. + * + * @returns {void} + * @private + */ + clear () { + // Set the state to TO_BE_CLEARED to mark the timer for removal in the next + // tick by the onTick function. + this._state = TO_BE_CLEARED - setTimeout(() => cb(null), retryTimeout) + // Reset the _idleStart value to -1 to indicate that the timer is no longer + // active. + this._idleStart = -1 } +} + +/** + * This module exports a setTimeout and clearTimeout function that can be + * used as a drop-in replacement for the native functions. + */ +module.exports = { + /** + * The setTimeout() method sets a timer which executes a function once the + * timer expires. + * @param {Function} callback A function to be executed after the timer + * expires. + * @param {number} delay The time, in milliseconds that the timer should + * wait before the specified function or code is executed. + * @param {*} [arg] An optional argument to be passed to the callback function + * when the timer expires. + * @returns {NodeJS.Timeout|FastTimer} + */ + setTimeout (callback, delay, arg) { + // If the delay is less than or equal to the RESOLUTION_MS value return a + // native Node.js Timer instance. + return delay <= RESOLUTION_MS + ? setTimeout(callback, delay, arg) + : new FastTimer(callback, delay, arg) + }, + /** + * The clearTimeout method cancels an instantiated Timer previously created + * by calling setTimeout. + * + * @param {NodeJS.Timeout|FastTimer} timeout + */ + clearTimeout (timeout) { + // If the timeout is a FastTimer, call its own clear method. + if (timeout[kFastTimer]) { + /** + * @type {FastTimer} + */ + timeout.clear() + // Otherwise it is an instance of a native NodeJS.Timeout, so call the + // Node.js native clearTimeout function. + } else { + clearTimeout(timeout) + } + }, + /** + * The setFastTimeout() method sets a fastTimer which executes a function once + * the timer expires. + * @param {Function} callback A function to be executed after the timer + * expires. + * @param {number} delay The time, in milliseconds that the timer should + * wait before the specified function or code is executed. + * @param {*} [arg] An optional argument to be passed to the callback function + * when the timer expires. + * @returns {FastTimer} + */ + setFastTimeout (callback, delay, arg) { + return new FastTimer(callback, delay, arg) + }, + /** + * The clearTimeout method cancels an instantiated FastTimer previously + * created by calling setFastTimeout. + * + * @param {FastTimer} timeout + */ + clearFastTimeout (timeout) { + timeout.clear() + }, + /** + * The now method returns the value of the internal fast timer clock. + * + * @returns {number} + */ + now () { + return fastNow + }, + /** + * Trigger the onTick function to process the fastTimers array. + * Exported for testing purposes only. + * Marking as deprecated to discourage any use outside of testing. + * @deprecated + * @param {number} [delay=0] The delay in milliseconds to add to the now value. + */ + tick (delay = 0) { + fastNow += delay - RESOLUTION_MS + 1 + onTick() + onTick() + }, + /** + * Reset FastTimers. + * Exported for testing purposes only. + * Marking as deprecated to discourage any use outside of testing. + * @deprecated + */ + reset () { + fastNow = 0 + fastTimers.length = 0 + clearTimeout(fastNowTimeout) + fastNowTimeout = null + }, + /** + * Exporting for testing purposes only. + * Marking as deprecated to discourage any use outside of testing. + * @deprecated + */ + kFastTimer +} - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const headers = parseHeaders(rawHeaders) - this.retryCount += 1 +/***/ }), - if (statusCode >= 300) { - if (this.retryOpts.statusCodes.includes(statusCode) === false) { - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } else { - this.abort( - new RequestRetryError('Request failed', statusCode, { - headers, - data: { - count: this.retryCount - } - }) - ) - return false - } - } +/***/ 9634: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // Checkpoint for resume from where we left it - if (this.resume != null) { - this.resume = null +"use strict"; - // Only Partial Content 206 supposed to provide Content-Range, - // any other status code that partially consumed the payload - // should not be retry because it would result in downstream - // wrongly concatanete multiple responses. - if (statusCode !== 206 && (this.start > 0 || statusCode !== 200)) { - this.abort( - new RequestRetryError('server does not support the range header and the payload was partially consumed', statusCode, { - headers, - data: { count: this.retryCount } - }) - ) - return false - } - const contentRange = parseRangeHeader(headers['content-range']) - // If no content range - if (!contentRange) { - this.abort( - new RequestRetryError('Content-Range mismatch', statusCode, { - headers, - data: { count: this.retryCount } - }) - ) - return false - } +const assert = __nccwpck_require__(4589) - // Let's start with a weak etag check - if (this.etag != null && this.etag !== headers.etag) { - this.abort( - new RequestRetryError('ETag mismatch', statusCode, { - headers, - data: { count: this.retryCount } - }) - ) - return false - } +const { kConstruct } = __nccwpck_require__(6443) +const { urlEquals, getFieldValues } = __nccwpck_require__(6798) +const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3440) +const { webidl } = __nccwpck_require__(7879) +const { cloneResponse, fromInnerResponse, getResponseState } = __nccwpck_require__(9051) +const { Request, fromInnerRequest, getRequestState } = __nccwpck_require__(9967) +const { fetching } = __nccwpck_require__(4398) +const { urlIsHttpHttpsScheme, readAllBytes } = __nccwpck_require__(3168) +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation + * @typedef {Object} CacheBatchOperation + * @property {'delete' | 'put'} type + * @property {any} request + * @property {any} response + * @property {import('../../../types/cache').CacheQueryOptions} options + */ - const { start, size, end = size - 1 } = contentRange +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list + * @typedef {[any, any][]} requestResponseList + */ - assert(this.start === start, 'content-range mismatch') - assert(this.end == null || this.end === end, 'content-range mismatch') +class Cache { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list + * @type {requestResponseList} + */ + #relevantRequestResponseList - this.resume = resume - return true + constructor () { + if (arguments[0] !== kConstruct) { + webidl.illegalConstructor() } - if (this.end == null) { - if (statusCode === 206) { - // First time we receive 206 - const range = parseRangeHeader(headers['content-range']) + webidl.util.markAsUncloneable(this) + this.#relevantRequestResponseList = arguments[1] + } - if (range == null) { - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } + async match (request, options = {}) { + webidl.brandCheck(this, webidl.is.Cache) - const { start, size, end = size - 1 } = range - assert( - start != null && Number.isFinite(start), - 'content-range mismatch' - ) - assert(end != null && Number.isFinite(end), 'invalid content-length') + const prefix = 'Cache.match' + webidl.argumentLengthCheck(arguments, 1, prefix) - this.start = start - this.end = end - } + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options, prefix, 'options') - // We make our best to checkpoint the body for further range headers - if (this.end == null) { - const contentLength = headers['content-length'] - this.end = contentLength != null ? Number(contentLength) - 1 : null - } + const p = this.#internalMatchAll(request, options, 1) - assert(Number.isFinite(this.start)) - assert( - this.end == null || Number.isFinite(this.end), - 'invalid content-length' - ) + if (p.length === 0) { + return + } - this.resume = resume - this.etag = headers.etag != null ? headers.etag : null + return p[0] + } - // Weak etags are not useful for comparison nor cache - // for instance not safe to assume if the response is byte-per-byte - // equal - if (this.etag != null && this.etag.startsWith('W/')) { - this.etag = null - } + async matchAll (request = undefined, options = {}) { + webidl.brandCheck(this, webidl.is.Cache) - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } + const prefix = 'Cache.matchAll' + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options, prefix, 'options') - const err = new RequestRetryError('Request failed', statusCode, { - headers, - data: { count: this.retryCount } - }) + return this.#internalMatchAll(request, options) + } - this.abort(err) + async add (request) { + webidl.brandCheck(this, webidl.is.Cache) - return false - } + const prefix = 'Cache.add' + webidl.argumentLengthCheck(arguments, 1, prefix) - onData (chunk) { - this.start += chunk.length + request = webidl.converters.RequestInfo(request) - return this.handler.onData(chunk) - } + // 1. + const requests = [request] - onComplete (rawTrailers) { - this.retryCount = 0 - return this.handler.onComplete(rawTrailers) + // 2. + const responseArrayPromise = this.addAll(requests) + + // 3. + return await responseArrayPromise } - onError (err) { - if (this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) - } + async addAll (requests) { + webidl.brandCheck(this, webidl.is.Cache) - // We reconcile in case of a mix between network errors - // and server error response - if (this.retryCount - this.retryCountCheckpoint > 0) { - // We count the difference between the last checkpoint and the current retry count - this.retryCount = - this.retryCountCheckpoint + - (this.retryCount - this.retryCountCheckpoint) - } else { - this.retryCount += 1 - } + const prefix = 'Cache.addAll' + webidl.argumentLengthCheck(arguments, 1, prefix) - this.retryOpts.retry( - err, - { - state: { counter: this.retryCount }, - opts: { retryOptions: this.retryOpts, ...this.opts } - }, - onRetry.bind(this) - ) + // 1. + const responsePromises = [] - function onRetry (err) { - if (err != null || this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) - } + // 2. + const requestList = [] - if (this.start !== 0) { - const headers = { range: `bytes=${this.start}-${this.end ?? ''}` } + // 3. + for (let request of requests) { + if (request === undefined) { + throw webidl.errors.conversionFailed({ + prefix, + argument: 'Argument 1', + types: ['undefined is not allowed'] + }) + } - // Weak etag check - weak etags will make comparison algorithms never match - if (this.etag != null) { - headers['if-match'] = this.etag - } + request = webidl.converters.RequestInfo(request) - this.opts = { - ...this.opts, - headers: { - ...this.opts.headers, - ...headers - } - } + if (typeof request === 'string') { + continue } - try { - this.retryCountCheckpoint = this.retryCount - this.dispatch(this.opts, this) - } catch (err) { - this.handler.onError(err) + // 3.1 + const r = getRequestState(request) + + // 3.2 + if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { + throw webidl.errors.exception({ + header: prefix, + message: 'Expected http/s scheme when method is not GET.' + }) } } - } -} - -module.exports = RetryHandler + // 4. + /** @type {ReturnType[]} */ + const fetchControllers = [] -/***/ }), - -/***/ 379: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 5. + for (const request of requests) { + // 5.1 + const r = getRequestState(new Request(request)) -"use strict"; + // 5.2 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: prefix, + message: 'Expected http/s scheme.' + }) + } -const { isIP } = __nccwpck_require__(7030) -const { lookup } = __nccwpck_require__(610) -const DecoratorHandler = __nccwpck_require__(8155) -const { InvalidArgumentError, InformationalError } = __nccwpck_require__(8707) -const maxInt = Math.pow(2, 31) - 1 + // 5.4 + r.initiator = 'fetch' + r.destination = 'subresource' -class DNSInstance { - #maxTTL = 0 - #maxItems = 0 - #records = new Map() - dualStack = true - affinity = null - lookup = null - pick = null + // 5.5 + requestList.push(r) - constructor (opts) { - this.#maxTTL = opts.maxTTL - this.#maxItems = opts.maxItems - this.dualStack = opts.dualStack - this.affinity = opts.affinity - this.lookup = opts.lookup ?? this.#defaultLookup - this.pick = opts.pick ?? this.#defaultPick - } + // 5.6 + const responsePromise = Promise.withResolvers() - get full () { - return this.#records.size === this.#maxItems - } + // 5.7 + fetchControllers.push(fetching({ + request: r, + processResponse (response) { + // 1. + if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Received an invalid status code or the request failed.' + })) + } else if (response.headersList.contains('vary')) { // 2. + // 2.1 + const fieldValues = getFieldValues(response.headersList.get('vary')) - runLookup (origin, opts, cb) { - const ips = this.#records.get(origin.hostname) + // 2.2 + for (const fieldValue of fieldValues) { + // 2.2.1 + if (fieldValue === '*') { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'invalid vary field value' + })) - // If full, we just return the origin - if (ips == null && this.full) { - cb(null, origin.origin) - return - } + for (const controller of fetchControllers) { + controller.abort() + } - const newOpts = { - affinity: this.affinity, - dualStack: this.dualStack, - lookup: this.lookup, - pick: this.pick, - ...opts.dns, - maxTTL: this.#maxTTL, - maxItems: this.#maxItems - } + return + } + } + } + }, + // Possible spec bug. If the body is never read, `processResponseEndOfBody` (which is attached to a TransformStream's flush hook) + // never runs, so this would hang. This hook, on the other hand, always reads the body. + // https://github.com/nodejs/undici/issues/5615 + processResponseConsumeBody (response) { + // 1. + if (response.aborted) { + responsePromise.reject(new DOMException('aborted', 'AbortError')) + return + } - // If no IPs we lookup - if (ips == null) { - this.lookup(origin, newOpts, (err, addresses) => { - if (err || addresses == null || addresses.length === 0) { - cb(err ?? new InformationalError('No DNS entries found')) - return + // 2. + responsePromise.resolve(response) } + })) - this.setRecords(origin, addresses) - const records = this.#records.get(origin.hostname) + // 5.8 + responsePromises.push(responsePromise.promise) + } - const ip = this.pick( - origin, - records, - newOpts.affinity - ) + // 6. + const p = Promise.all(responsePromises) - let port - if (typeof ip.port === 'number') { - port = `:${ip.port}` - } else if (origin.port !== '') { - port = `:${origin.port}` - } else { - port = '' - } + // 7. + const responses = await p - cb( - null, - `${origin.protocol}//${ - ip.family === 6 ? `[${ip.address}]` : ip.address - }${port}` - ) - }) - } else { - // If there's IPs we pick - const ip = this.pick( - origin, - ips, - newOpts.affinity - ) + // 7.1 + const operations = [] - // If no IPs we lookup - deleting old records - if (ip == null) { - this.#records.delete(origin.hostname) - this.runLookup(origin, opts, cb) - return - } + // 7.2 + let index = 0 - let port - if (typeof ip.port === 'number') { - port = `:${ip.port}` - } else if (origin.port !== '') { - port = `:${origin.port}` - } else { - port = '' + // 7.3 + for (const response of responses) { + // 7.3.1 + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 7.3.2 + request: requestList[index], // 7.3.3 + response // 7.3.4 } - cb( - null, - `${origin.protocol}//${ - ip.family === 6 ? `[${ip.address}]` : ip.address - }${port}` - ) + operations.push(operation) // 7.3.5 + + index++ // 7.3.6 } - } - #defaultLookup (origin, opts, cb) { - lookup( - origin.hostname, - { - all: true, - family: this.dualStack === false ? this.affinity : 0, - order: 'ipv4first' - }, - (err, addresses) => { - if (err) { - return cb(err) - } + // 7.5 + const cacheJobPromise = Promise.withResolvers() - const results = new Map() + // 7.6.1 + let errorData = null - for (const addr of addresses) { - // On linux we found duplicates, we attempt to remove them with - // the latest record - results.set(`${addr.address}:${addr.family}`, addr) - } + // 7.6.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } - cb(null, results.values()) + // 7.6.3 + queueMicrotask(() => { + // 7.6.3.1 + if (errorData === null) { + cacheJobPromise.resolve(undefined) + } else { + // 7.6.3.2 + cacheJobPromise.reject(errorData) } - ) + }) + + // 7.7 + return cacheJobPromise.promise } - #defaultPick (origin, hostnameRecords, affinity) { - let ip = null - const { records, offset } = hostnameRecords + async put (request, response) { + webidl.brandCheck(this, webidl.is.Cache) - let family - if (this.dualStack) { - if (affinity == null) { - // Balance between ip families - if (offset == null || offset === maxInt) { - hostnameRecords.offset = 0 - affinity = 4 - } else { - hostnameRecords.offset++ - affinity = (hostnameRecords.offset & 1) === 1 ? 6 : 4 - } - } + const prefix = 'Cache.put' + webidl.argumentLengthCheck(arguments, 2, prefix) - if (records[affinity] != null && records[affinity].ips.length > 0) { - family = records[affinity] - } else { - family = records[affinity === 4 ? 6 : 4] - } - } else { - family = records[affinity] - } + request = webidl.converters.RequestInfo(request) + response = webidl.converters.Response(response, prefix, 'response') - // If no IPs we return null - if (family == null || family.ips.length === 0) { - return ip - } + // 1. + let innerRequest = null - if (family.offset == null || family.offset === maxInt) { - family.offset = 0 - } else { - family.offset++ + // 2. + if (webidl.is.Request(request)) { + innerRequest = getRequestState(request) + } else { // 3. + innerRequest = getRequestState(new Request(request)) } - const position = family.offset % family.ips.length - ip = family.ips[position] ?? null - - if (ip == null) { - return ip + // 4. + if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { + throw webidl.errors.exception({ + header: prefix, + message: 'Expected an http/s scheme when method is not GET' + }) } - if (Date.now() - ip.timestamp > ip.ttl) { // record TTL is already in ms - // We delete expired records - // It is possible that they have different TTL, so we manage them individually - family.ips.splice(position, 1) - return this.pick(origin, hostnameRecords, affinity) + // 5. + const innerResponse = getResponseState(response) + + // 6. + if (innerResponse.status === 206) { + throw webidl.errors.exception({ + header: prefix, + message: 'Got 206 status' + }) } - return ip - } + // 7. + if (innerResponse.headersList.contains('vary')) { + // 7.1. + const fieldValues = getFieldValues(innerResponse.headersList.get('vary')) - setRecords (origin, addresses) { - const timestamp = Date.now() - const records = { records: { 4: null, 6: null } } - for (const record of addresses) { - record.timestamp = timestamp - if (typeof record.ttl === 'number') { - // The record TTL is expected to be in ms - record.ttl = Math.min(record.ttl, this.#maxTTL) - } else { - record.ttl = this.#maxTTL + // 7.2. + for (const fieldValue of fieldValues) { + // 7.2.1 + if (fieldValue === '*') { + throw webidl.errors.exception({ + header: prefix, + message: 'Got * vary field value' + }) + } } + } - const familyRecords = records.records[record.family] ?? { ips: [] } - - familyRecords.ips.push(record) - records.records[record.family] = familyRecords + // 8. + if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { + throw webidl.errors.exception({ + header: prefix, + message: 'Response body is locked or disturbed' + }) } - this.#records.set(origin.hostname, records) - } + // 9. + const clonedResponse = cloneResponse(innerResponse) - getHandler (meta, opts) { - return new DNSDispatchHandler(this, meta, opts) - } -} + // 10. + const bodyReadPromise = Promise.withResolvers() -class DNSDispatchHandler extends DecoratorHandler { - #state = null - #opts = null - #dispatch = null - #handler = null - #origin = null + // 11. + if (innerResponse.body != null) { + // 11.1 + const stream = innerResponse.body.stream + + // 11.2 + const reader = stream.getReader() - constructor (state, { origin, handler, dispatch }, opts) { - super(handler) - this.#origin = origin - this.#handler = handler - this.#opts = { ...opts } - this.#state = state - this.#dispatch = dispatch - } + // 11.3 + readAllBytes(reader, bodyReadPromise.resolve, bodyReadPromise.reject) + } else { + bodyReadPromise.resolve(undefined) + } - onError (err) { - switch (err.code) { - case 'ETIMEDOUT': - case 'ECONNREFUSED': { - if (this.#state.dualStack) { - // We delete the record and retry - this.#state.runLookup(this.#origin, this.#opts, (err, newOrigin) => { - if (err) { - return this.#handler.onError(err) - } + // 12. + /** @type {CacheBatchOperation[]} */ + const operations = [] - const dispatchOpts = { - ...this.#opts, - origin: newOrigin - } + // 13. + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 14. + request: innerRequest, // 15. + response: clonedResponse // 16. + } - this.#dispatch(dispatchOpts, this) - }) + // 17. + operations.push(operation) - // if dual-stack disabled, we error out - return - } + // 19. + const bytes = await bodyReadPromise.promise - this.#handler.onError(err) - return - } - case 'ENOTFOUND': - this.#state.deleteRecord(this.#origin) - // eslint-disable-next-line no-fallthrough - default: - this.#handler.onError(err) - break + if (clonedResponse.body != null) { + clonedResponse.body.source = bytes } - } -} -module.exports = interceptorOpts => { - if ( - interceptorOpts?.maxTTL != null && - (typeof interceptorOpts?.maxTTL !== 'number' || interceptorOpts?.maxTTL < 0) - ) { - throw new InvalidArgumentError('Invalid maxTTL. Must be a positive number') - } + // 19.1 + const cacheJobPromise = Promise.withResolvers() - if ( - interceptorOpts?.maxItems != null && - (typeof interceptorOpts?.maxItems !== 'number' || - interceptorOpts?.maxItems < 1) - ) { - throw new InvalidArgumentError( - 'Invalid maxItems. Must be a positive number and greater than zero' - ) - } + // 19.2.1 + let errorData = null - if ( - interceptorOpts?.affinity != null && - interceptorOpts?.affinity !== 4 && - interceptorOpts?.affinity !== 6 - ) { - throw new InvalidArgumentError('Invalid affinity. Must be either 4 or 6') - } + // 19.2.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } - if ( - interceptorOpts?.dualStack != null && - typeof interceptorOpts?.dualStack !== 'boolean' - ) { - throw new InvalidArgumentError('Invalid dualStack. Must be a boolean') - } + // 19.2.3 + queueMicrotask(() => { + // 19.2.3.1 + if (errorData === null) { + cacheJobPromise.resolve() + } else { // 19.2.3.2 + cacheJobPromise.reject(errorData) + } + }) - if ( - interceptorOpts?.lookup != null && - typeof interceptorOpts?.lookup !== 'function' - ) { - throw new InvalidArgumentError('Invalid lookup. Must be a function') + return cacheJobPromise.promise } - if ( - interceptorOpts?.pick != null && - typeof interceptorOpts?.pick !== 'function' - ) { - throw new InvalidArgumentError('Invalid pick. Must be a function') - } + async delete (request, options = {}) { + webidl.brandCheck(this, webidl.is.Cache) - const dualStack = interceptorOpts?.dualStack ?? true - let affinity - if (dualStack) { - affinity = interceptorOpts?.affinity ?? null - } else { - affinity = interceptorOpts?.affinity ?? 4 - } + const prefix = 'Cache.delete' + webidl.argumentLengthCheck(arguments, 1, prefix) - const opts = { - maxTTL: interceptorOpts?.maxTTL ?? 10e3, // Expressed in ms - lookup: interceptorOpts?.lookup ?? null, - pick: interceptorOpts?.pick ?? null, - dualStack, - affinity, - maxItems: interceptorOpts?.maxItems ?? Infinity - } + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options, prefix, 'options') - const instance = new DNSInstance(opts) + /** + * @type {Request} + */ + let r = null - return dispatch => { - return function dnsInterceptor (origDispatchOpts, handler) { - const origin = - origDispatchOpts.origin.constructor === URL - ? origDispatchOpts.origin - : new URL(origDispatchOpts.origin) + if (webidl.is.Request(request)) { + r = getRequestState(request) - if (isIP(origin.hostname) !== 0) { - return dispatch(origDispatchOpts, handler) + if (r.method !== 'GET' && !options.ignoreMethod) { + return false } + } else { + assert(typeof request === 'string') - instance.runLookup(origin, origDispatchOpts, (err, newOrigin) => { - if (err) { - return handler.onError(err) - } - - let dispatchOpts = null - dispatchOpts = { - ...origDispatchOpts, - servername: origin.hostname, // For SNI on TLS - origin: newOrigin, - headers: { - host: origin.hostname, - ...origDispatchOpts.headers - } - } + r = getRequestState(new Request(request)) + } - dispatch( - dispatchOpts, - instance.getHandler({ origin, dispatch, handler }, origDispatchOpts) - ) - }) + /** @type {CacheBatchOperation[]} */ + const operations = [] - return true + /** @type {CacheBatchOperation} */ + const operation = { + type: 'delete', + request: r, + options } - } -} + operations.push(operation) -/***/ }), + const cacheJobPromise = Promise.withResolvers() -/***/ 8060: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let errorData = null + let requestResponses -"use strict"; + try { + requestResponses = this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } + queueMicrotask(() => { + if (errorData === null) { + cacheJobPromise.resolve(!!requestResponses?.length) + } else { + cacheJobPromise.reject(errorData) + } + }) -const util = __nccwpck_require__(3440) -const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8707) -const DecoratorHandler = __nccwpck_require__(8155) + return cacheJobPromise.promise + } -class DumpHandler extends DecoratorHandler { - #maxSize = 1024 * 1024 - #abort = null - #dumped = false - #aborted = false - #size = 0 - #reason = null - #handler = null + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys + * @param {any} request + * @param {import('../../../types/cache').CacheQueryOptions} options + * @returns {Promise} + */ + async keys (request = undefined, options = {}) { + webidl.brandCheck(this, webidl.is.Cache) - constructor ({ maxSize }, handler) { - super(handler) + const prefix = 'Cache.keys' - if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) { - throw new InvalidArgumentError('maxSize must be a number greater than 0') - } + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options, prefix, 'options') - this.#maxSize = maxSize ?? this.#maxSize - this.#handler = handler - } + // 1. + let r = null - onConnect (abort) { - this.#abort = abort + // 2. + if (request !== undefined) { + // 2.1 + if (webidl.is.Request(request)) { + // 2.1.1 + r = getRequestState(request) - this.#handler.onConnect(this.#customAbort.bind(this)) - } + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { // 2.2 + r = getRequestState(new Request(request)) + } + } - #customAbort (reason) { - this.#aborted = true - this.#reason = reason - } + // 4. + const promise = Promise.withResolvers() - // TODO: will require adjustment after new hooks are out - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const headers = util.parseHeaders(rawHeaders) - const contentLength = headers['content-length'] + // 5. + // 5.1 + const requests = [] - if (contentLength != null && contentLength > this.#maxSize) { - throw new RequestAbortedError( - `Response size (${contentLength}) larger than maxSize (${ - this.#maxSize - })` - ) + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + // 5.2.1.1 + requests.push(requestResponse[0]) + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) + + // 5.3.2 + for (const requestResponse of requestResponses) { + // 5.3.2.1 + requests.push(requestResponse[0]) + } } - if (this.#aborted) { - return true - } + // 5.4 + queueMicrotask(() => { + // 5.4.1 + const requestList = [] + + // 5.4.2 + for (const request of requests) { + const requestObject = fromInnerRequest( + request, + undefined, + new AbortController().signal, + 'immutable' + ) + // 5.4.2.1 + requestList.push(requestObject) + } - return this.#handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) + // 5.4.3 + promise.resolve(Object.freeze(requestList)) + }) + + return promise.promise } - onError (err) { - if (this.#dumped) { - return - } + /** + * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm + * @param {CacheBatchOperation[]} operations + * @returns {requestResponseList} + */ + #batchCacheOperations (operations) { + // 1. + const cache = this.#relevantRequestResponseList - err = this.#reason ?? err + // 2. + const backupCache = [...cache] - this.#handler.onError(err) - } + // 3. + const addedItems = [] - onData (chunk) { - this.#size = this.#size + chunk.length + // 4.1 + const resultList = [] - if (this.#size >= this.#maxSize) { - this.#dumped = true + try { + // 4.2 + for (const operation of operations) { + // 4.2.1 + if (operation.type !== 'delete' && operation.type !== 'put') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'operation type does not match "delete" or "put"' + }) + } - if (this.#aborted) { - this.#handler.onError(this.#reason) - } else { - this.#handler.onComplete([]) - } - } + // 4.2.2 + if (operation.type === 'delete' && operation.response != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'delete operation should not have an associated response' + }) + } - return true - } + // 4.2.3 + if (this.#queryCache(operation.request, operation.options, addedItems).length) { + throw new DOMException('???', 'InvalidStateError') + } - onComplete (trailers) { - if (this.#dumped) { - return - } + // 4.2.4 + let requestResponses - if (this.#aborted) { - this.#handler.onError(this.reason) - return - } + // 4.2.5 + if (operation.type === 'delete') { + // 4.2.5.1 + requestResponses = this.#queryCache(operation.request, operation.options) - this.#handler.onComplete(trailers) - } -} + // TODO: the spec is wrong, this is needed to pass WPTs + if (requestResponses.length === 0) { + return [] + } -function createDumpInterceptor ( - { maxSize: defaultMaxSize } = { - maxSize: 1024 * 1024 - } -) { - return dispatch => { - return function Intercept (opts, handler) { - const { dumpMaxSize = defaultMaxSize } = - opts + // 4.2.5.2 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) - const dumpHandler = new DumpHandler( - { maxSize: dumpMaxSize }, - handler - ) + // 4.2.5.2.1 + cache.splice(idx, 1) + } + } else if (operation.type === 'put') { // 4.2.6 + // 4.2.6.1 + if (operation.response == null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'put operation should have an associated response' + }) + } - return dispatch(opts, dumpHandler) - } - } -} + // 4.2.6.2 + const r = operation.request -module.exports = createDumpInterceptor + // 4.2.6.3 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'expected http or https scheme' + }) + } + // 4.2.6.4 + if (r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'not get method' + }) + } -/***/ }), + // 4.2.6.5 + if (operation.options != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'options must not be defined' + }) + } -/***/ 5092: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 4.2.6.6 + requestResponses = this.#queryCache(operation.request) -"use strict"; + // 4.2.6.7 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) + // 4.2.6.7.1 + cache.splice(idx, 1) + } -const RedirectHandler = __nccwpck_require__(8754) + // 4.2.6.8 + cache.push([operation.request, operation.response]) -function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { - return (dispatch) => { - return function Intercept (opts, handler) { - const { maxRedirections = defaultMaxRedirections } = opts + // 4.2.6.10 + addedItems.push([operation.request, operation.response]) + } - if (!maxRedirections) { - return dispatch(opts, handler) + // 4.2.7 + resultList.push([operation.request, operation.response]) } - const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler) - opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting. - return dispatch(opts, redirectHandler) + // 4.3 + return resultList + } catch (e) { // 5. + // 5.1 + this.#relevantRequestResponseList.length = 0 + + // 5.2 + this.#relevantRequestResponseList = backupCache + + // 5.3 + throw e } } -} - -module.exports = createRedirectInterceptor + /** + * @see https://w3c.github.io/ServiceWorker/#query-cache + * @param {any} requestQuery + * @param {import('../../../types/cache').CacheQueryOptions} options + * @param {requestResponseList} targetStorage + * @returns {requestResponseList} + */ + #queryCache (requestQuery, options, targetStorage) { + /** @type {requestResponseList} */ + const resultList = [] -/***/ }), + const storage = targetStorage ?? this.#relevantRequestResponseList -/***/ 1514: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + for (const requestResponse of storage) { + const [cachedRequest, cachedResponse] = requestResponse + if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { + resultList.push(requestResponse) + } + } -"use strict"; + return resultList + } -const RedirectHandler = __nccwpck_require__(8754) + /** + * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm + * @param {any} requestQuery + * @param {any} request + * @param {any | null} response + * @param {import('../../../types/cache').CacheQueryOptions | undefined} options + * @returns {boolean} + */ + #requestMatchesCachedItem (requestQuery, request, response = null, options) { + // if (options?.ignoreMethod === false && request.method === 'GET') { + // return false + // } -module.exports = opts => { - const globalMaxRedirections = opts?.maxRedirections - return dispatch => { - return function redirectInterceptor (opts, handler) { - const { maxRedirections = globalMaxRedirections, ...baseOpts } = opts + const queryURL = new URL(requestQuery.url) - if (!maxRedirections) { - return dispatch(opts, handler) - } + const cachedURL = new URL(request.url) - const redirectHandler = new RedirectHandler( - dispatch, - maxRedirections, - opts, - handler - ) + if (options?.ignoreSearch) { + cachedURL.search = '' - return dispatch(baseOpts, redirectHandler) + queryURL.search = '' } - } -} - -/***/ }), + if (!urlEquals(queryURL, cachedURL, true)) { + return false + } -/***/ 2026: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if ( + response == null || + options?.ignoreVary || + !response.headersList.contains('vary') + ) { + return true + } -"use strict"; + const fieldValues = getFieldValues(response.headersList.get('vary')) -const RetryHandler = __nccwpck_require__(7816) + for (const fieldValue of fieldValues) { + if (fieldValue === '*') { + return false + } -module.exports = globalOpts => { - return dispatch => { - return function retryInterceptor (opts, handler) { - return dispatch( - opts, - new RetryHandler( - { ...opts, retryOptions: { ...globalOpts, ...opts.retryOptions } }, - { - handler, - dispatch - } - ) - ) - } - } -} + const requestValue = request.headersList.get(fieldValue) + const queryValue = requestQuery.headersList.get(fieldValue) + // If one has the header and the other doesn't, or one has + // a different value than the other, return false + if (requestValue !== queryValue) { + return false + } + } -/***/ }), + return true + } -/***/ 2824: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + #internalMatchAll (request, options, maxResponses = Infinity) { + // 1. + let r = null -"use strict"; + // 2. + if (request !== undefined) { + if (webidl.is.Request(request)) { + // 2.1.1 + r = getRequestState(request) -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; -const utils_1 = __nccwpck_require__(172); -// C headers -var ERROR; -(function (ERROR) { - ERROR[ERROR["OK"] = 0] = "OK"; - ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; - ERROR[ERROR["STRICT"] = 2] = "STRICT"; - ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; - ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; - ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; - ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; - ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; - ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; - ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; - ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; - ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; - ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; - ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; - ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; - ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; - ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; - ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; - ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; - ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; - ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; - ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; - ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; - ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; - ERROR[ERROR["USER"] = 24] = "USER"; -})(ERROR = exports.ERROR || (exports.ERROR = {})); -var TYPE; -(function (TYPE) { - TYPE[TYPE["BOTH"] = 0] = "BOTH"; - TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; - TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; -})(TYPE = exports.TYPE || (exports.TYPE = {})); -var FLAGS; -(function (FLAGS) { - FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; - FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; - FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; - FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; - FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; - FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; - FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; - FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; - // 1 << 8 is unused - FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; -})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); -var LENIENT_FLAGS; -(function (LENIENT_FLAGS) { - LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; - LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; - LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; -})(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); -var METHODS; -(function (METHODS) { - METHODS[METHODS["DELETE"] = 0] = "DELETE"; - METHODS[METHODS["GET"] = 1] = "GET"; - METHODS[METHODS["HEAD"] = 2] = "HEAD"; - METHODS[METHODS["POST"] = 3] = "POST"; - METHODS[METHODS["PUT"] = 4] = "PUT"; - /* pathological */ - METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; - METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; - METHODS[METHODS["TRACE"] = 7] = "TRACE"; - /* WebDAV */ - METHODS[METHODS["COPY"] = 8] = "COPY"; - METHODS[METHODS["LOCK"] = 9] = "LOCK"; - METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; - METHODS[METHODS["MOVE"] = 11] = "MOVE"; - METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; - METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; - METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; - METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; - METHODS[METHODS["BIND"] = 16] = "BIND"; - METHODS[METHODS["REBIND"] = 17] = "REBIND"; - METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; - METHODS[METHODS["ACL"] = 19] = "ACL"; - /* subversion */ - METHODS[METHODS["REPORT"] = 20] = "REPORT"; - METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; - METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; - METHODS[METHODS["MERGE"] = 23] = "MERGE"; - /* upnp */ - METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; - METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; - METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; - METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; - /* RFC-5789 */ - METHODS[METHODS["PATCH"] = 28] = "PATCH"; - METHODS[METHODS["PURGE"] = 29] = "PURGE"; - /* CalDAV */ - METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; - /* RFC-2068, section 19.6.1.2 */ - METHODS[METHODS["LINK"] = 31] = "LINK"; - METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; - /* icecast */ - METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; - /* RFC-7540, section 11.6 */ - METHODS[METHODS["PRI"] = 34] = "PRI"; - /* RFC-2326 RTSP */ - METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; - METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; - METHODS[METHODS["SETUP"] = 37] = "SETUP"; - METHODS[METHODS["PLAY"] = 38] = "PLAY"; - METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; - METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; - METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; - METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; - METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; - METHODS[METHODS["RECORD"] = 44] = "RECORD"; - /* RAOP */ - METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; -})(METHODS = exports.METHODS || (exports.METHODS = {})); -exports.METHODS_HTTP = [ - METHODS.DELETE, - METHODS.GET, - METHODS.HEAD, - METHODS.POST, - METHODS.PUT, - METHODS.CONNECT, - METHODS.OPTIONS, - METHODS.TRACE, - METHODS.COPY, - METHODS.LOCK, - METHODS.MKCOL, - METHODS.MOVE, - METHODS.PROPFIND, - METHODS.PROPPATCH, - METHODS.SEARCH, - METHODS.UNLOCK, - METHODS.BIND, - METHODS.REBIND, - METHODS.UNBIND, - METHODS.ACL, - METHODS.REPORT, - METHODS.MKACTIVITY, - METHODS.CHECKOUT, - METHODS.MERGE, - METHODS['M-SEARCH'], - METHODS.NOTIFY, - METHODS.SUBSCRIBE, - METHODS.UNSUBSCRIBE, - METHODS.PATCH, - METHODS.PURGE, - METHODS.MKCALENDAR, - METHODS.LINK, - METHODS.UNLINK, - METHODS.PRI, - // TODO(indutny): should we allow it with HTTP? - METHODS.SOURCE, -]; -exports.METHODS_ICE = [ - METHODS.SOURCE, -]; -exports.METHODS_RTSP = [ - METHODS.OPTIONS, - METHODS.DESCRIBE, - METHODS.ANNOUNCE, - METHODS.SETUP, - METHODS.PLAY, - METHODS.PAUSE, - METHODS.TEARDOWN, - METHODS.GET_PARAMETER, - METHODS.SET_PARAMETER, - METHODS.REDIRECT, - METHODS.RECORD, - METHODS.FLUSH, - // For AirPlay - METHODS.GET, - METHODS.POST, -]; -exports.METHOD_MAP = utils_1.enumToMap(METHODS); -exports.H_METHOD_MAP = {}; -Object.keys(exports.METHOD_MAP).forEach((key) => { - if (/^H/.test(key)) { - exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; - } -}); -var FINISH; -(function (FINISH) { - FINISH[FINISH["SAFE"] = 0] = "SAFE"; - FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; - FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; -})(FINISH = exports.FINISH || (exports.FINISH = {})); -exports.ALPHA = []; -for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { - // Upper case - exports.ALPHA.push(String.fromCharCode(i)); - // Lower case - exports.ALPHA.push(String.fromCharCode(i + 0x20)); -} -exports.NUM_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, -}; -exports.HEX_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, - A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, - a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, -}; -exports.NUM = [ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', -]; -exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); -exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; -exports.USERINFO_CHARS = exports.ALPHANUM - .concat(exports.MARK) - .concat(['%', ';', ':', '&', '=', '+', '$', ',']); -// TODO(indutny): use RFC -exports.STRICT_URL_CHAR = [ - '!', '"', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - ':', ';', '<', '=', '>', - '@', '[', '\\', ']', '^', '_', - '`', - '{', '|', '}', '~', -].concat(exports.ALPHANUM); -exports.URL_CHAR = exports.STRICT_URL_CHAR - .concat(['\t', '\f']); -// All characters with 0x80 bit set to 1 -for (let i = 0x80; i <= 0xff; i++) { - exports.URL_CHAR.push(i); -} -exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); -/* Tokens as defined by rfc 2616. Also lowercases them. - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - */ -exports.STRICT_TOKEN = [ - '!', '#', '$', '%', '&', '\'', - '*', '+', '-', '.', - '^', '_', '`', - '|', '~', -].concat(exports.ALPHANUM); -exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); -/* - * Verify that a char is a valid visible (printable) US-ASCII - * character or %x80-FF - */ -exports.HEADER_CHARS = ['\t']; -for (let i = 32; i <= 255; i++) { - if (i !== 127) { - exports.HEADER_CHARS.push(i); + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { + // 2.2.1 + r = getRequestState(new Request(request)) + } } -} -// ',' = \x44 -exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); -exports.MAJOR = exports.NUM_MAP; -exports.MINOR = exports.MAJOR; -var HEADER_STATE; -(function (HEADER_STATE) { - HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; - HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; - HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; - HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; - HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; - HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; - HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; -})(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); -exports.SPECIAL_HEADERS = { - 'connection': HEADER_STATE.CONNECTION, - 'content-length': HEADER_STATE.CONTENT_LENGTH, - 'proxy-connection': HEADER_STATE.CONNECTION, - 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, - 'upgrade': HEADER_STATE.UPGRADE, -}; -//# sourceMappingURL=constants.js.map - -/***/ }), -/***/ 3870: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 5. + // 5.1 + const responses = [] -"use strict"; + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + responses.push(requestResponse[1]) + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) + // 5.3.2 + for (const requestResponse of requestResponses) { + responses.push(requestResponse[1]) + } + } -const { Buffer } = __nccwpck_require__(4573) + // 5.4 + // We don't implement CORs so we don't need to loop over the responses, yay! -module.exports = Buffer.from('AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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PgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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iQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB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CABB3AgLii1JbnZhbGlkIGNoYXIgaW4gdXJsIHF1ZXJ5AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fYm9keQBDb250ZW50LUxlbmd0aCBvdmVyZmxvdwBDaHVuayBzaXplIG92ZXJmbG93AFJlc3BvbnNlIG92ZXJmbG93AEludmFsaWQgbWV0aG9kIGZvciBIVFRQL3gueCByZXF1ZXN0AEludmFsaWQgbWV0aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zAFVzZXIgY2FsbGJhY2sgZXJyb3IAYG9uX3Jlc2V0YCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfaGVhZGVyYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9iZWdpbmAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3N0YXR1c19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3ZlcnNpb25fY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl91cmxfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXRob2RfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfZmllbGRfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fbmFtZWAgY2FsbGJhY2sgZXJyb3IAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzZXJ2ZXIASW52YWxpZCBoZWFkZXIgdmFsdWUgY2hhcgBJbnZhbGlkIGhlYWRlciBmaWVsZCBjaGFyAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdmVyc2lvbgBJbnZhbGlkIG1pbm9yIHZlcnNpb24ASW52YWxpZCBtYWpvciB2ZXJzaW9uAEV4cGVjdGVkIHNwYWNlIGFmdGVyIHZlcnNpb24ARXhwZWN0ZWQgQ1JMRiBhZnRlciB2ZXJzaW9uAEludmFsaWQgSFRUUCB2ZXJzaW9uAEludmFsaWQgaGVhZGVyIHRva2VuAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdXJsAEludmFsaWQgY2hhcmFjdGVycyBpbiB1cmwAVW5leHBlY3RlZCBzdGFydCBjaGFyIGluIHVybABEb3VibGUgQCBpbiB1cmwARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgARHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhciBpbiB1cmwgcGF0aABDb250ZW50LUxlbmd0aCBjYW4ndCBiZSBwcmVzZW50IHdpdGggVHJhbnNmZXItRW5jb2RpbmcASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgc2l6ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl92YWx1ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlZCB2YWx1ZQBQYXVzZWQgYnkgb25faGVhZGVyc19jb21wbGV0ZQBJbnZhbGlkIEVPRiBzdGF0ZQBvbl9yZXNldCBwYXVzZQBvbl9jaHVua19oZWFkZXIgcGF1c2UAb25fbWVzc2FnZV9iZWdpbiBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fdmFsdWUgcGF1c2UAb25fc3RhdHVzX2NvbXBsZXRlIHBhdXNlAG9uX3ZlcnNpb25fY29tcGxldGUgcGF1c2UAb25fdXJsX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXNzYWdlX2NvbXBsZXRlIHBhdXNlAG9uX21ldGhvZF9jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfZmllbGRfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUgcGF1c2UAVW5leHBlY3RlZCBzcGFjZSBhZnRlciBzdGFydCBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAFBhdXNlIG9uIENPTk5FQ1QvVXBncmFkZQBQYXVzZSBvbiBQUkkvVXBncmFkZQBFeHBlY3RlZCBIVFRQLzIgQ29ubmVjdGlvbiBQcmVmYWNlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fbWV0aG9kAEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl9maWVsZABQYXVzZWQASW52YWxpZCB3b3JkIGVuY291bnRlcmVkAEludmFsaWQgbWV0aG9kIGVuY291bnRlcmVkAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2NoZW1hAFJlcXVlc3QgaGFzIGludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYABTV0lUQ0hfUFJPWFkAVVNFX1BST1hZAE1LQUNUSVZJVFkAVU5QUk9DRVNTQUJMRV9FTlRJVFkAQ09QWQBNT1ZFRF9QRVJNQU5FTlRMWQBUT09fRUFSTFkATk9USUZZAEZBSUxFRF9ERVBFTkRFTkNZAEJBRF9HQVRFV0FZAFBMQVkAUFVUAENIRUNLT1VUAEdBVEVXQVlfVElNRU9VVABSRVFVRVNUX1RJTUVPVVQATkVUV09SS19DT05ORUNUX1RJTUVPVVQAQ09OTkVDVElPTl9USU1FT1VUAExPR0lOX1RJTUVPVVQATkVUV09SS19SRUFEX1RJTUVPVVQAUE9TVABNSVNESVJFQ1RFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX0xPQURfQkFMQU5DRURfUkVRVUVTVABCQURfUkVRVUVTVABIVFRQX1JFUVVFU1RfU0VOVF9UT19IVFRQU19QT1JUAFJFUE9SVABJTV9BX1RFQVBPVABSRVNFVF9DT05URU5UAE5PX0NPTlRFTlQAUEFSVElBTF9DT05URU5UAEhQRV9JTlZBTElEX0NPTlNUQU5UAEhQRV9DQl9SRVNFVABHRVQASFBFX1NUUklDVABDT05GTElDVABURU1QT1JBUllfUkVESVJFQ1QAUEVSTUFORU5UX1JFRElSRUNUAENPTk5FQ1QATVVMVElfU1RBVFVTAEhQRV9JTlZBTElEX1NUQVRVUwBUT09fTUFOWV9SRVFVRVNUUwBFQVJMWV9ISU5UUwBVTkFWQUlMQUJMRV9GT1JfTEVHQUxfUkVBU09OUwBPUFRJT05TAFNXSVRDSElOR19QUk9UT0NPTFMAVkFSSUFOVF9BTFNPX05FR09USUFURVMATVVMVElQTEVfQ0hPSUNFUwBJTlRFUk5BTF9TRVJWRVJfRVJST1IAV0VCX1NFUlZFUl9VTktOT1dOX0VSUk9SAFJBSUxHVU5fRVJST1IASURFTlRJVFlfUFJPVklERVJfQVVUSEVOVElDQVRJT05fRVJST1IAU1NMX0NFUlRJRklDQVRFX0VSUk9SAElOVkFMSURfWF9GT1JXQVJERURfRk9SAFNFVF9QQVJBTUVURVIAR0VUX1BBUkFNRVRFUgBIUEVfVVNFUgBTRUVfT1RIRVIASFBFX0NCX0NIVU5LX0hFQURFUgBNS0NBTEVOREFSAFNFVFVQAFdFQl9TRVJWRVJfSVNfRE9XTgBURUFSRE9XTgBIUEVfQ0xPU0VEX0NPTk5FQ1RJT04ASEVVUklTVElDX0VYUElSQVRJT04ARElTQ09OTkVDVEVEX09QRVJBVElPTgBOT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTgBIUEVfSU5WQUxJRF9WRVJTSU9OAEhQRV9DQl9NRVNTQUdFX0JFR0lOAFNJVEVfSVNfRlJPWkVOAEhQRV9JTlZBTElEX0hFQURFUl9UT0tFTgBJTlZBTElEX1RPS0VOAEZPUkJJRERFTgBFTkhBTkNFX1lPVVJfQ0FMTQBIUEVfSU5WQUxJRF9VUkwAQkxPQ0tFRF9CWV9QQVJFTlRBTF9DT05UUk9MAE1LQ09MAEFDTABIUEVfSU5URVJOQUwAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRV9VTk9GRklDSUFMAEhQRV9PSwBVTkxJTksAVU5MT0NLAFBSSQBSRVRSWV9XSVRIAEhQRV9JTlZBTElEX0NPTlRFTlRfTEVOR1RIAEhQRV9VTkVYUEVDVEVEX0NPTlRFTlRfTEVOR1RIAEZMVVNIAFBST1BQQVRDSABNLVNFQVJDSABVUklfVE9PX0xPTkcAUFJPQ0VTU0lORwBNSVNDRUxMQU5FT1VTX1BFUlNJU1RFTlRfV0FSTklORwBNSVNDRUxMQU5FT1VTX1dBUk5JTkcASFBFX0lOVkFMSURfVFJBTlNGRVJfRU5DT0RJTkcARXhwZWN0ZWQgQ1JMRgBIUEVfSU5WQUxJRF9DSFVOS19TSVpFAE1PVkUAQ09OVElOVUUASFBFX0NCX1NUQVRVU19DT01QTEVURQBIUEVfQ0JfSEVBREVSU19DT01QTEVURQBIUEVfQ0JfVkVSU0lPTl9DT01QTEVURQBIUEVfQ0JfVVJMX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8AAF4TAAAmEwAAMBAAAPAXAACdEwAAFRIAADkXAADwEgAAChAAAHUSAACtEgAAghMAAE8UAAB/EAAAoBUAACMUAACJEgAAixQAAE0VAADUEQAAzxQAABAYAADJFgAA3BYAAMERAADgFwAAuxQAAHQUAAB8FQAA5RQAAAgXAAAfEAAAZRUAAKMUAAAoFQAAAhUAAJkVAAAsEAAAixkAAE8PAADUDgAAahAAAM4QAAACFwAAiQ4AAG4TAAAcEwAAZhQAAFYXAADBEwAAzRMAAGwTAABoFwAAZhcAAF8XAAAiEwAAzg8AAGkOAADYDgAAYxYAAMsTAACqDgAAKBcAACYXAADFEwAAXRYAAOgRAABnEwAAZRMAAPIWAABzEwAAHRcAAPkWAADzEQAAzw4AAM4VAAAMEgAAsxEAAKURAABhEAAAMhcAALsTAEH5NQsBAQBBkDYL4AEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB/TcLAQEAQZE4C14CAwICAgICAAACAgACAgACAgICAgICAgICAAQAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEH9OQsBAQBBkToLXgIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAQfA7Cw1sb3NlZWVwLWFsaXZlAEGJPAsBAQBBoDwL4AEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBBiT4LAQEAQaA+C+cBAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAEGwwAALXwEBAAEBAQEBAAABAQABAQABAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAEGQwgALIWVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgBBwMIACy1yYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AQfnCAAsFAQIAAQMAQZDDAAvgAQQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH5xAALBQECAAEDAEGQxQAL4AEEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cYACwQBAAABAEGRxwAL3wEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAEH6yAALBAEAAAIAQZDJAAtfAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAQfrKAAsEAQAAAQBBkMsACwEBAEGqywALQQIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEH6zAALBAEAAAEAQZDNAAsBAQBBms0ACwYCAAAAAAIAQbHNAAs6AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB8M4AC5YBTk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRU9SRElSRUNUT1JUUkNIUEFSQU1FVEVSVVJDRUJTQ1JJQkVBUkRPV05BQ0VJTkROS0NLVUJTQ1JJQkVIVFRQL0FEVFAv', 'base64') + // 5.5.1 + const responseList = [] + // 5.5.2 + for (const response of responses) { + // 5.5.2.1 + const responseObject = fromInnerResponse(cloneResponse(response), 'immutable') -/***/ }), + responseList.push(responseObject) -/***/ 3434: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (responseList.length >= maxResponses) { + break + } + } -"use strict"; + // 6. + return Object.freeze(responseList) + } + static { + webidl.is.Cache = (arg) => { + return arg != null && typeof arg === 'object' && #relevantRequestResponseList in arg + } + } +} -const { Buffer } = __nccwpck_require__(4573) +Object.defineProperties(Cache.prototype, { + [Symbol.toStringTag]: { + value: 'Cache', + configurable: true + }, + match: kEnumerableProperty, + matchAll: kEnumerableProperty, + add: kEnumerableProperty, + addAll: kEnumerableProperty, + put: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) -module.exports = Buffer.from('AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAX8AYAJ/fwBgBH9/f38Bf2AAAGADf39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQAEA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAAy0sBQYAAAIAAAAAAAACAQIAAgICAAADAAAAAAMDAwMBAQEBAQEBAQEAAAIAAAAEBQFwARISBQMBAAIGCAF/AUGA1AQLB9EFIgZtZW1vcnkCAAtfaW5pdGlhbGl6ZQAIGV9faW5kaXJlY3RfZnVuY3Rpb25fdGFibGUBAAtsbGh0dHBfaW5pdAAJGGxsaHR0cF9zaG91bGRfa2VlcF9hbGl2ZQAvDGxsaHR0cF9hbGxvYwALBm1hbGxvYwAxC2xsaHR0cF9mcmVlAAwEZnJlZQAMD2xsaHR0cF9nZXRfdHlwZQANFWxsaHR0cF9nZXRfaHR0cF9tYWpvcgAOFWxsaHR0cF9nZXRfaHR0cF9taW5vcgAPEWxsaHR0cF9nZXRfbWV0aG9kABAWbGxodHRwX2dldF9zdGF0dXNfY29kZQAREmxsaHR0cF9nZXRfdXBncmFkZQASDGxsaHR0cF9yZXNldAATDmxsaHR0cF9leGVjdXRlABQUbGxodHRwX3NldHRpbmdzX2luaXQAFQ1sbGh0dHBfZmluaXNoABYMbGxodHRwX3BhdXNlABcNbGxodHRwX3Jlc3VtZQAYG2xsaHR0cF9yZXN1bWVfYWZ0ZXJfdXBncmFkZQAZEGxsaHR0cF9nZXRfZXJybm8AGhdsbGh0dHBfZ2V0X2Vycm9yX3JlYXNvbgAbF2xsaHR0cF9zZXRfZXJyb3JfcmVhc29uABwUbGxodHRwX2dldF9lcnJvcl9wb3MAHRFsbGh0dHBfZXJybm9fbmFtZQAeEmxsaHR0cF9tZXRob2RfbmFtZQAfEmxsaHR0cF9zdGF0dXNfbmFtZQAgGmxsaHR0cF9zZXRfbGVu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PgtBhwEMPQtBiAEMPAtBiQEMOwtBigEMOgtBiwEMOQtBjAEMOAtBjQEMNwtBjgEMNgtBjwEMNQtBkAEMNAtBkQEMMwtBkgEMMgtBkwEMMQtBlAEMMAtBlQEMLwtBlgEMLgtBlwEMLQtBmAEMLAtBmQEMKwtBmgEMKgtBmwEMKQtBnAEMKAtBnQEMJwtBngEMJgtBnwEMJQtBoAEMJAtBoQEMIwtBogEMIgtBowEMIQtBpAEMIAtBpQEMHwtBpgEMHgtBpwEMHQtBqAEMHAtBqQEMGwtBqgEMGgtBqwEMGQtBrAEMGAtBrQEMFwtBrgEMFgtBAQwVC0GvAQwUC0GwAQwTC0GxAQwSC0GzAQwRC0GyAQwQC0G0AQwPC0G1AQwOC0G2AQwNC0G3AQwMC0G4AQwLC0G5AQwKC0G6AQwJC0G7AQwIC0HGAQwHC0G8AQwGC0G9AQwFC0G+AQwEC0G/AQwDC0HAAQwCC0HCAQwBC0HBAQshAwNAAkACQAJAAkACQAJAAkACQAJAIAICfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAgJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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iQEhAwykAgtBASABLQAAQd8ARw1nGiABQQFqIQEMXgtBigEhAyABIARGDaICIAIoAgAiACAEIAFraiEFIAEgAGtBAWohBgNAIAEtAAAgAEGMzwBqLQAARw1kIABBAUYN+gEgAEEBaiEAIAQgAUEBaiIBRw0ACyACIAU2AgAMogILQYsBIQMgASAERg2hAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGOzwBqLQAARw1kIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyiAgsgAkEANgIAIAZBAWohAUECDGULQYwBIQMgASAERg2gAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHwzwBqLQAARw1jIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyhAgsgAkEANgIAIAZBAWohAUEfDGQLQY0BIQMgASAERg2fAiACKAIAIgAgBCABa2ohBSABIABrQQFqIQYCQANAIAEtAAAgAEHyzwBqLQAARw1iIABBAUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAygAgsgAkEANgIAIAZBAWohAUEJDGMLIAEgBEYEQEGOASEDDJ8CCwJAAkAgAS0AAEHJAGsOBwBiYmJiYgFiCyABQQFqIQFB+AAhAwyGAgsgAUEBaiEBQfkAIQMMhQILQY8BIQMgASAERg2dAiACKAIAIgAgBCABa2ohBSABIABrQQVqIQYCQANAIAEtAAAgAEGRzwBqLQAARw1gIABBBUYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAyeAgsgAkEANgIAIAZBAWohAUEYDGELQZABIQMgASAERg2cAiACKAIAIgAgBCABa2ohBSABIABrQQJqIQYCQANAIAEtAAAgAEGXzwBqLQAARw1fIABBAkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAydAgsgAkEANgIAIAZBAWohAUEXDGALQZEBIQMgASAERg2bAiACKAIAIgAgBCABa2ohBSABIABrQQZqIQYCQANAIAEtAAAgAEGazwBqLQAARw1eIABBBkYNASAAQQFqIQAgBCABQQFqIgFHDQALIAIgBTYCAAycAgsgAkEANgIAIAZBAWohAUEV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JSIARQ0RIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMtAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0gIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMswELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0iIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMsgELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0OIAJB5QA2AhwgAiABNgIUIAIgADYCDEEAIQMMsQELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0dIAJB0wA2AhwgAiABNgIUIAIgADYCDEEAIQMMsAELIAIoAgQhACACQQA2AgQgAiAAIAEQJSIARQ0fIAJB0gA2AhwgAiABNgIUIAIgADYCDEEAIQMMrwELIABBP0cNASABQQFqCyEBQQUhAwyUAQtBACEDIAJBADYCHCACIAE2AhQgAkH9EjYCECACQQc2AgwMrAELIAJBADYCHCACIAE2AhQgAkHcCDYCECACQQc2AgxBACEDDKsBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNByACQeUANgIcIAIgATYCFCACIAA2AgxBACEDDKoBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNFiACQdMANgIcIAIgATYCFCACIAA2AgxBACEDDKkBCyACKAIEIQAgAkEANgIEIAIgACABECUiAEUNGCACQdIANgIcIAIgATYCFCACIAA2AgxBACEDDKgBCyACQQA2AhwgAiABNgIUIAJBxgo2AhAgAkEHNgIMQQAhAwynAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQMgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwymAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRIgAkHTADYCHCACIAE2AhQgAiAANgIMQQAhAwylAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDRQgAkHSADYCHCACIAE2AhQgAiAANgIMQQAhAwykAQsgAigCBCEAIAJBADYCBCACIAAgARAlIgBFDQAgAkHlADYCHCACIAE2AhQgAiAANgIMQQAhAwyjAQtB1QAhAwyJAQsgAEEVRwRAIAJBADYCHCACIAE2AhQgAkG5DTYCECACQRo2AgxB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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB5ABrDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0HhJw8LQaQhDwtByywPC0H+MQ8LQcAkDwtBqyQPC0GNKA8LQeImDwtBgDAPC0G5Lw8LQdckDwtB7x8PC0HhHw8LQfofDwtB8iAPC0GoLw8LQa4yDwtBiDAPC0HsJw8LQYIiDwtBjh0PC0HQLg8LQcojDwtBxTIPC0HfHA8LQdIcDwtBxCAPC0HXIA8LQaIfDwtB7S4PC0GrMA8LQdQlDwtBzC4PC0H6Lg8LQfwrDwtB0jAPC0HxHQ8LQbsgDwtB9ysPC0GQMQ8LQdcxDwtBoi0PC0HUJw8LQeArDwtBnywPC0HrMQ8LQdUfDwtByjEPC0HeJQ8LQdQeDwtB9BwPC0GnMg8LQbEdDwtBoB0PC0G5MQ8LQbwwDwtBkiEPC0GzJg8LQeksDwtBrB4PC0HUKw8LQfcmDwtBgCYPC0GwIQ8LQf4eDwtBjSMPC0GJLQ8LQfciDwtBoDEPC0GuHw8LQcYlDwtB6B4PC0GTIg8LQcIvDwtBwx0PC0GLLA8LQeEdDwtBjS8PC0HqIQ8LQbQtDwtB0i8PC0HfMg8LQdIyDwtB8DAPC0GpIg8LQfkjDwtBmR4PC0G1LA8LQZswDwtBkjIPC0G2Kw8LQcIiDwtB+DIPC0GeJQ8LQdAiDwtBuh4PC0GBHg8LAAtB1iEhAQsgAQsWACAAIAAtAC1B/gFxIAFBAEdyOgAtCxkAIAAgAC0ALUH9AXEgAUEAR0EBdHI6AC0LGQAgACAALQAtQfsBcSABQQBHQQJ0cjoALQsZACAAIAAtAC1B9wFxIAFBAEdBA3RyOgAtCz4BAn8CQCAAKAI4IgNFDQAgAygCBCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBxhE2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCCCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB9go2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCDCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB7Ro2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCECIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBlRA2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCFCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBqhs2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCGCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB7RM2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCKCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABB9gg2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCHCIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBwhk2AhBBGCEECyAECz4BAn8CQCAAKAI4IgNFDQAgAygCICIDRQ0AIAAgASACIAFrIAMRAQAiBEF/Rw0AIABBlBQ2AhBBGCEECyAEC1kBAn8CQCAALQAoQQFGDQAgAC8BMiIBQeQAa0HkAEkNACABQcwBRg0AIAFBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhAiAAQYgEcUGABEYNACAAQShxRSECCyACC4wBAQJ/AkACQAJAIAAtACpFDQAgAC0AK0UNACAALwEwIgFBAnFFDQEMAgsgAC8BMCIBQQFxRQ0BC0EBIQIgAC0AKEEBRg0AIAAvATIiAEHkAGtB5ABJDQAgAEHMAUYNACAAQbACRg0AIAFBwABxDQBBACECIAFBiARxQYAERg0AIAFBKHFBAEchAgsgAgtzACAAQRBq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAA/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAAQTBq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAAQSBq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAAQd0BNgIcCwYAIAAQMguaLQELfyMAQRBrIgokAEGk0AAoAgAiCUUEQEHk0wAoAgAiBUUEQEHw0wBCfzcCAEHo0wBCgICEgICAwAA3AgBB5NMAIApBCGpBcHFB2KrVqgVzIgU2AgBB+NMAQQA2AgBByNMAQQA2AgALQczTAEGA1AQ2AgBBnNAAQYDUBDYCAEGw0AAgBTYCAEGs0ABBfzYCAEHQ0wBBgKwDNgIAA0AgAUHI0ABqIAFBvNAAaiICNgIAIAIgAUG00ABqIgM2AgAgAUHA0ABqIAM2AgAgAUHQ0ABqIAFBxNAAaiIDNgIAIAMgAjYCACABQdjQAGogAUHM0ABqIgI2AgAgAiADNgIAIAFB1NAAaiACNgIAIAFBIGoiAUGAAkcNAAtBjNQEQcGrAzYCAEGo0ABB9NMAKAIANgIAQZjQAEHAqwM2AgBBpNAAQYjUBDYCAEHM/wdBODYCAEGI1AQhCQsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAQewBTQRAQYzQACgCACIGQRAgAEETakFwcSAAQQtJGyIEQQN2IgB2IgFBA3EEQAJAIAFBAXEgAHJBAXMiAkEDdCIAQbTQAGoiASAAQbzQAGooAgAiACgCCCIDRgRAQYzQACAGQX4gAndxNgIADAELIAEgAzYCCCADIAE2AgwLIABBCGohASAAIAJBA3QiAkEDcjYCBCAAIAJqIgAgACgCBEEBcjYCBAwRC0GU0AAoAgAiCCAETw0BIAEEQAJAQQIgAHQiAkEAIAJrciABIAB0cWgiAEEDdCICQbTQAGoiASACQbzQAGooAgAiAigCCCIDRgRAQYzQACAGQX4gAHdxIgY2AgAMAQsgASADNgIIIAMgATYCDAsgAiAEQQNyNgIEIABBA3QiACAEayEFIAAgAmogBTYCACACIARqIgQgBUEBcjYCBCAIBEAgCEF4cUG00ABqIQBBoNAAKAIAIQMCf0EBIAhBA3Z0IgEgBnFFBEBBjNAAIAEgBnI2AgAgAAwBCyAAKAIICyIBIAM2AgwgACADNgIIIAMgADYCDCADIAE2AggLIAJBCGohAUGg0AAgBDYCAEGU0AAgBTYCAAwRC0GQ0AAoAgAiC0UNASALaEECdEG80gBqKAIAIgAoAgRBeHEgBGshBSAAIQIDQAJAIAIoAhAiAUUEQCACQRRqKAIAIgFFDQELIAEoAgRBeHEgBGsiAyAFSSECIAMgBSACGyEFIAEgACACGyEAIAEhAgwBCwsgACgCGCEJIAAoAgwiAyAARwRAQZzQACgCABogAyAAKAIIIgE2AgggASADNgIMDBALIABBFGoiAigCACIBRQRAIAAoAhAiAUUNAyAAQRBqIQILA0AgAiEHIAEiA0EUaiICKAIAIgENACADQRBqIQIgAygCECIBDQALIAdBADYCAAwPC0F/IQQgAEG/f0sNACAAQRNqIgFBcHEhBEGQ0AAoAgAiCEUNAEEAIARrIQUCQAJAAkACf0EAIARBgAJJDQAaQR8gBEH///8HSw0AGiAEQSYgAUEIdmciAGt2QQFxIABBAXRrQT5qCyIGQQJ0QbzSAGooAgAiAkUEQEEAIQFBACEDDAELQQAhASAEQRkgBkEBdmtBACAGQR9HG3QhAEEAIQMDQAJAIAIoAgRBeHEgBGsiByAFTw0AIAIhAyAHIgUNAEEAIQUgAiEBDAMLIAEgAkEUaigCACIHIAcgAiAAQR12QQRxakEQaigCACICRhsgASAHGyEBIABBAXQhACACDQALCyABIANyRQRAQQAhA0ECIAZ0IgBBACAAa3IgCHEiAEUNAyAAaEECdEG80gBqKAIAIQELIAFFDQELA0AgASgCBEF4cSAEayICIAVJIQAgAiAFIAAbIQUgASADIAAbIQMgASgCECIABH8gAAUgAUEUaigCAAsiAQ0ACwsgA0UNACAFQZTQACgCACAEa08NACADKAIYIQcgAyADKAIMIgBHBEBBnNAAKAIAGiAAIAMoAggiATYCCCABIAA2AgwMDgsgA0EUaiICKAIAIgFFBEAgAygCECIBRQ0DIANBEGohAgsDQCACIQYgASIAQRRqIgIoAgAiAQ0AIABBEGohAiAAKAIQIgENAAsgBkEANgIADA0LQZTQACgCACIDIARPBEBBoNAAKAIAIQECQCADIARrIgJBEE8EQCABIARqIgAgAkEBcjYCBCABIANqIAI2AgAgASAEQQNyNgIEDAELIAEgA0EDcjYCBCABIANqIgAgACgCBEEBcjYCBEEAIQBBACECC0GU0AAgAjYCAEGg0AAgADYCACABQQhqIQEMDwtBmNAAKAIAIgMgBEsEQCAEIAlqIgAgAyAEayIBQQFyNgIEQaTQACAANgIAQZjQACABNgIAIAkgBEEDcjYCBCAJQQhqIQEMDwtBACEBIAQCf0Hk0wAoAgAEQEHs0wAoAgAMAQtB8NMAQn83AgBB6NMAQoCAhICAgMAANwIAQeTTACAKQQxqQXBxQdiq1aoFczYCAEH40wBBADYCAEHI0wBBADYCAEGAgAQLIgAgBEHHAGoiBWoiBkEAIABrIgdxIgJPBEBB/NMAQTA2AgAMDwsCQEHE0wAoAgAiAUUNAEG80wAoAgAiCCACaiEAIAAgAU0gACAIS3ENAEEAIQFB/NMAQTA2AgAMDwtByNMALQAAQQRxDQQCQAJAIAkEQEHM0wAhAQNAIAEoAgAiACAJTQRAIAAgASgCBGogCUsNAwsgASgCCCIBDQALC0EAEDMiAEF/Rg0FIAIhBkHo0wAoAgAiAUEBayIDIABxBEAgAiAAayAAIANqQQAgAWtxaiEGCyAEIAZPDQUgBkH+////B0sNBUHE0wAoAgAiAwRAQbzTACgCACIHIAZqIQEgASAHTQ0GIAEgA0sNBgsgBhAzIgEgAEcNAQwHCyAGIANrIAdxIgZB/v///wdLDQQgBhAzIQAgACABKAIAIAEoAgRqRg0DIAAhAQsCQCAGIARByABqTw0AIAFBf0YNAEHs0wAoAgAiACAFIAZrakEAIABrcSIAQf7///8HSwRAIAEhAAwHCyAAEDNBf0cEQCAAIAZqIQYgASEADAcLQQAgBmsQMxoMBAsgASIAQX9HDQUMAwtBACEDDAwLQQAhAAwKCyAAQX9HDQILQcjTAEHI0wAoAgBBBHI2AgALIAJB/v///wdLDQEgAhAzIQBBABAzIQEgAEF/Rg0BIAFBf0YNASAAIAFPDQEgASAAayIGIARBOGpNDQELQbzTAEG80wAoAgAgBmoiATYCAEHA0wAoAgAgAUkEQEHA0wAgATYCAAsCQAJAAkBBpNAAKAIAIgIEQEHM0wAhAQNAIAAgASgCACIDIAEoAgQiBWpGDQIgASgCCCIBDQALDAILQZzQACgCACIBQQBHIAAgAU9xRQRAQZzQACAANgIAC0EAIQFB0NMAIAY2AgBBzNMAIAA2AgBBrNAAQX82AgBBsNAAQeTTACgCADYCAEHY0wBBADYCAANAIAFByNAAaiABQbzQAGoiAjYCACACIAFBtNAAaiIDNgIAIAFBwNAAaiADNgIAIAFB0NAAaiABQcTQAGoiAzYCACADIAI2AgAgAUHY0ABqIAFBzNAAaiICNgIAIAIgAzYCACABQdTQAGogAjYCACABQSBqIgFBgAJHDQALQXggAGtBD3EiASAAaiICIAZBOGsiAyABayIBQQFyNgIEQajQAEH00wAoAgA2AgBBmNAAIAE2AgBBpNAAIAI2AgAgACADakE4NgIEDAILIAAgAk0NACACIANJDQAgASgCDEEIcQ0AQXggAmtBD3EiACACaiIDQZjQACgCACAGaiIHIABrIgBBAXI2AgQgASAFIAZqNgIEQajQAEH00wAoAgA2AgBBmNAAIAA2AgBBpNAAIAM2AgAgAiAHakE4NgIEDAELIABBnNAAKAIASQRAQZzQACAANgIACyAAIAZqIQNBzNMAIQECQAJAAkADQCADIAEoAgBHBEAgASgCCCIBDQEMAgsLIAEtAAxBCHFFDQELQczTACEBA0AgASgCACIDIAJNBEAgAyABKAIEaiIFIAJLDQMLIAEoAgghAQwACwALIAEgADYCACABIAEoAgQgBmo2AgQgAEF4IABrQQ9xaiIJIARBA3I2AgQgA0F4IANrQQ9xaiIGIAQgCWoiBGshASACIAZGBEBBpNAAIAQ2AgBBmNAAQZjQACgCACABaiIANgIAIAQgAEEBcjYCBAwIC0Gg0AAoAgAgBkYEQEGg0AAgBDYCAEGU0ABBlNAAKAIAIAFqIgA2AgAgBCAAQQFyNgIEIAAgBGogADYCAAwICyAGKAIEIgVBA3FBAUcNBiAFQXhxIQggBUH/AU0EQCAFQQN2IQMgBigCCCIAIAYoAgwiAkYEQEGM0ABBjNAAKAIAQX4gA3dxNgIADAcLIAIgADYCCCAAIAI2AgwMBgsgBigCGCEHIAYgBigCDCIARwRAIAAgBigCCCICNgIIIAIgADYCDAwFCyAGQRRqIgIoAgAiBUUEQCAGKAIQIgVFDQQgBkEQaiECCwNAIAIhAyAFIgBBFGoiAigCACIFDQAgAEEQaiECIAAoAhAiBQ0ACyADQQA2AgAMBAtBeCAAa0EPcSIBIABqIgcgBkE4ayIDIAFrIgFBAXI2AgQgACADakE4NgIEIAIgBUE3IAVrQQ9xakE/ayIDIAMgAkEQakkbIgNBIzYCBEGo0ABB9NMAKAIANgIAQZjQACABNgIAQaTQACAHNgIAIANBEGpB1NMAKQIANwIAIANBzNMAKQIANwIIQdTTACADQQhqNgIAQdDTACAGNgIAQczTACAANgIAQdjTAEEANgIAIANBJGohAQNAIAFBBzYCACAFIAFBBGoiAUsNAAsgAiADRg0AIAMgAygCBEF+cTYCBCADIAMgAmsiBTYCACACIAVBAXI2AgQgBUH/AU0EQCAFQXhxQbTQAGohAAJ/QYzQACgCACIBQQEgBUEDdnQiA3FFBEBBjNAAIAEgA3I2AgAgAAwBCyAAKAIICyIBIAI2AgwgACACNgIIIAIgADYCDCACIAE2AggMAQtBHyEBIAVB////B00EQCAFQSYgBUEIdmciAGt2QQFxIABBAXRrQT5qIQELIAIgATYCHCACQgA3AhAgAUECdEG80gBqIQBBkNAAKAIAIgNBASABdCIGcUUEQCAAIAI2AgBBkNAAIAMgBnI2AgAgAiAANgIYIAIgAjYCCCACIAI2AgwMAQsgBUEZIAFBAXZrQQAgAUEfRxt0IQEgACgCACEDAkADQCADIgAoAgRBeHEgBUYNASABQR12IQMgAUEBdCEBIAAgA0EEcWpBEGoiBigCACIDDQALIAYgAjYCACACIAA2AhggAiACNgIMIAIgAjYCCAwBCyAAKAIIIgEgAjYCDCAAIAI2AgggAkEANgIYIAIgADYCDCACIAE2AggLQZjQACgCACIBIARNDQBBpNAAKAIAIgAgBGoiAiABIARrIgFBAXI2AgRBmNAAIAE2AgBBpNAAIAI2AgAgACAEQQNyNgIEIABBCGohAQwIC0EAIQFB/NMAQTA2AgAMBwtBACEACyAHRQ0AAkAgBigCHCICQQJ0QbzSAGoiAygCACAGRgRAIAMgADYCACAADQFBkNAAQZDQACgCAEF+IAJ3cTYCAAwCCyAHQRBBFCAHKAIQIAZGG2ogADYCACAARQ0BCyAAIAc2AhggBigCECICBEAgACACNgIQIAIgADYCGAsgBkEUaigCACICRQ0AIABBFGogAjYCACACIAA2AhgLIAEgCGohASAGIAhqIgYoAgQhBQsgBiAFQX5xNgIEIAEgBGogATYCACAEIAFBAXI2AgQgAUH/AU0EQCABQXhxQbTQAGohAAJ/QYzQACgCACICQQEgAUEDdnQiAXFFBEBBjNAAIAEgAnI2AgAgAAwBCyAAKAIICyIBIAQ2AgwgACAENgIIIAQgADYCDCAEIAE2AggMAQtBHyEFIAFB////B00EQCABQSYgAUEIdmciAGt2QQFxIABBAXRrQT5qIQULIAQgBTYCHCAEQgA3AhAgBUECdEG80gBqIQBBkNAAKAIAIgJBASAFdCIDcUUEQCAAIAQ2AgBBkNAAIAIgA3I2AgAgBCAANgIYIAQgBDYCCCAEIAQ2AgwMAQsgAUEZIAVBAXZrQQAgBUEfRxt0IQUgACgCACEAAkADQCAAIgIoAgRBeHEgAUYNASAFQR12IQAgBUEBdCEFIAIgAEEEcWpBEGoiAygCACIADQALIAMgBDYCACAEIAI2AhggBCAENgIMIAQgBDYCCAwBCyACKAIIIgAgBDYCDCACIAQ2AgggBEEANgIYIAQgAjYCDCAEIAA2AggLIAlBCGohAQwCCwJAIAdFDQACQCADKAIcIgFBAnRBvNIAaiICKAIAIANGBEAgAiAANgIAIAANAUGQ0AAgCEF+IAF3cSIINgIADAILIAdBEEEUIAcoAhAgA0YbaiAANgIAIABFDQELIAAgBzYCGCADKAIQIgEEQCAAIAE2AhAgASAANgIYCyADQRRqKAIAIgFFDQAgAEEUaiABNgIAIAEgADYCGAsCQCAFQQ9NBEAgAyAEIAVqIgBBA3I2AgQgACADaiIAIAAoAgRBAXI2AgQMAQsgAyAEaiICIAVBAXI2AgQgAyAEQQNyNgIEIAIgBWogBTYCACAFQf8BTQRAIAVBeHFBtNAAaiEAAn9BjNAAKAIAIgFBASAFQQN2dCIFcUUEQEGM0AAgASAFcjYCACAADAELIAAoAggLIgEgAjYCDCAAIAI2AgggAiAANgIMIAIgATYCCAwBC0EfIQEgBUH///8HTQRAIAVBJiAFQQh2ZyIAa3ZBAXEgAEEBdGtBPmohAQsgAiABNgIcIAJCADcCECABQQJ0QbzSAGohAEEBIAF0IgQgCHFFBEAgACACNgIAQZDQACAEIAhyNgIAIAIgADYCGCACIAI2AgggAiACNgIMDAELIAVBGSABQQF2a0EAIAFBH0cbdCEBIAAoAgAhBAJAA0AgBCIAKAIEQXhxIAVGDQEgAUEddiEEIAFBAXQhASAAIARBBHFqQRBqIgYoAgAiBA0ACyAGIAI2AgAgAiAANgIYIAIgAjYCDCACIAI2AggMAQsgACgCCCIBIAI2AgwgACACNgIIIAJBADYCGCACIAA2AgwgAiABNgIICyADQQhqIQEMAQsCQCAJRQ0AAkAgACgCHCIBQQJ0QbzSAGoiAigCACAARgRAIAIgAzYCACADDQFBkNAAIAtBfiABd3E2AgAMAgsgCUEQQRQgCSgCECAARhtqIAM2AgAgA0UNAQsgAyAJNgIYIAAoAhAiAQRAIAMgATYCECABIAM2AhgLIABBFGooAgAiAUUNACADQRRqIAE2AgAgASADNgIYCwJAIAVBD00EQCAAIAQgBWoiAUEDcjYCBCAAIAFqIgEgASgCBEEBcjYCBAwBCyAAIARqIgcgBUEBcjYCBCAAIARBA3I2AgQgBSAHaiAFNgIAIAgEQCAIQXhxQbTQAGohAUGg0AAoAgAhAwJ/QQEgCEEDdnQiAiAGcUUEQEGM0AAgAiAGcjYCACABDAELIAEoAggLIgIgAzYCDCABIAM2AgggAyABNgIMIAMgAjYCCAtBoNAAIAc2AgBBlNAAIAU2AgALIABBCGohAQsgCkEQaiQAIAELQwAgAEUEQD8AQRB0DwsCQCAAQf//A3ENACAAQQBIDQAgAEEQdkAAIgBBf0YEQEH80wBBMDYCAEF/DwsgAEEQdA8LAAsL3D8iAEGACAsJAQAAAAIAAAADAEGUCAsFBAAAAAUAQaQICwkGAAAABwAAAAgAQdwIC4otSW52YWxpZCBjaGFyIGluIHVybCBxdWVyeQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2JvZHkAQ29udGVudC1MZW5ndGggb3ZlcmZsb3cAQ2h1bmsgc2l6ZSBvdmVyZmxvdwBSZXNwb25zZSBvdmVyZmxvdwBJbnZhbGlkIG1ldGhvZCBmb3IgSFRUUC94LnggcmVxdWVzdABJbnZhbGlkIG1ldGhvZCBmb3IgUlRTUC94LnggcmVxdWVzdABFeHBlY3RlZCBTT1VSQ0UgbWV0aG9kIGZvciBJQ0UveC54IHJlcXVlc3QASW52YWxpZCBjaGFyIGluIHVybCBmcmFnbWVudCBzdGFydABFeHBlY3RlZCBkb3QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9zdGF0dXMASW52YWxpZCByZXNwb25zZSBzdGF0dXMASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucwBVc2VyIGNhbGxiYWNrIGVycm9yAGBvbl9yZXNldGAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2hlYWRlcmAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfYmVnaW5gIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwBB+TULAQEAQZA2C+ABAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQf03CwEBAEGROAteAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgBB/TkLAQEAQZE6C14CAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAEHwOwsNbG9zZWVlcC1hbGl2ZQBBiTwLAQEAQaA8C+ABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQYk+CwEBAEGgPgvnAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZABBsMAAC18BAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQBBkMIACyFlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AQcDCAAstcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQoNClNNDQoNClRUUC9DRS9UU1AvAEH5wgALBQECAAEDAEGQwwAL4AEEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+cQACwUBAgABAwBBkMUAC+ABBAEBBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQfnGAAsEAQAAAQBBkccAC98BAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQBB+sgACwQBAAACAEGQyQALXwMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAEH6ygALBAEAAAEAQZDLAAsBAQBBqssAC0ECAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBB+swACwQBAAABAEGQzQALAQEAQZrNAAsGAgAAAAACAEGxzQALOgMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQfDOAAuWAU5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==', 'base64') +const cacheQueryOptionConverters = [ + { + key: 'ignoreSearch', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'ignoreMethod', + converter: webidl.converters.boolean, + defaultValue: () => false + }, + { + key: 'ignoreVary', + converter: webidl.converters.boolean, + defaultValue: () => false + } +] +webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters) -/***/ }), +webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ + ...cacheQueryOptionConverters, + { + key: 'cacheName', + converter: webidl.converters.DOMString + } +]) -/***/ 172: -/***/ ((__unused_webpack_module, exports) => { +webidl.converters.Response = webidl.interfaceConverter( + webidl.is.Response, + 'Response' +) -"use strict"; +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.RequestInfo +) -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.enumToMap = void 0; -function enumToMap(obj) { - const res = {}; - Object.keys(obj).forEach((key) => { - const value = obj[key]; - if (typeof value === 'number') { - res[key] = value; - } - }); - return res; +module.exports = { + Cache } -exports.enumToMap = enumToMap; -//# sourceMappingURL=utils.js.map + /***/ }), -/***/ 7501: +/***/ 3245: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { kClients } = __nccwpck_require__(6443) -const Agent = __nccwpck_require__(7405) -const { - kAgent, - kMockAgentSet, - kMockAgentGet, - kDispatches, - kIsMockActive, - kNetConnect, - kGetNetConnect, - kOptions, - kFactory -} = __nccwpck_require__(1117) -const MockClient = __nccwpck_require__(7365) -const MockPool = __nccwpck_require__(4004) -const { matchValue, buildMockOptions } = __nccwpck_require__(3397) -const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8707) -const Dispatcher = __nccwpck_require__(883) -const Pluralizer = __nccwpck_require__(1529) -const PendingInterceptorsFormatter = __nccwpck_require__(6142) +const { Cache } = __nccwpck_require__(9634) +const { webidl } = __nccwpck_require__(7879) +const { kEnumerableProperty } = __nccwpck_require__(3440) +const { kConstruct } = __nccwpck_require__(6443) -class MockAgent extends Dispatcher { - constructor (opts) { - super(opts) +class CacheStorage { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map + * @type {Map} + */ + async has (cacheName) { + webidl.brandCheck(this, webidl.is.CacheStorage) - async close () { - await this[kAgent].close() - this[kClients].clear() - } + const prefix = 'CacheStorage.has' + webidl.argumentLengthCheck(arguments, 1, prefix) - deactivate () { - this[kIsMockActive] = false - } + cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName') - activate () { - this[kIsMockActive] = true + // 2.1.1 + // 2.2 + return this.#caches.has(cacheName) } - enableNetConnect (matcher) { - if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { - if (Array.isArray(this[kNetConnect])) { - this[kNetConnect].push(matcher) - } else { - this[kNetConnect] = [matcher] - } - } else if (typeof matcher === 'undefined') { - this[kNetConnect] = true - } else { - throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') - } - } + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open + * @param {string} cacheName + * @returns {Promise} + */ + async open (cacheName) { + webidl.brandCheck(this, webidl.is.CacheStorage) - disableNetConnect () { - this[kNetConnect] = false - } + const prefix = 'CacheStorage.open' + webidl.argumentLengthCheck(arguments, 1, prefix) - // This is required to bypass issues caused by using global symbols - see: - // https://github.com/nodejs/undici/issues/1447 - get isMockActive () { - return this[kIsMockActive] - } + cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName') - [kMockAgentSet] (origin, dispatcher) { - this[kClients].set(origin, dispatcher) - } + // 2.1 + if (this.#caches.has(cacheName)) { + // await caches.open('v1') !== await caches.open('v1') - [kFactory] (origin) { - const mockOptions = Object.assign({ agent: this }, this[kOptions]) - return this[kOptions] && this[kOptions].connections === 1 - ? new MockClient(origin, mockOptions) - : new MockPool(origin, mockOptions) - } + // 2.1.1 + const cache = this.#caches.get(cacheName) - [kMockAgentGet] (origin) { - // First check if we can immediately find it - const client = this[kClients].get(origin) - if (client) { - return client + // 2.1.1.1 + return new Cache(kConstruct, cache) } - // If the origin is not a string create a dummy parent pool and return to user - if (typeof origin !== 'string') { - const dispatcher = this[kFactory]('http://localhost:9999') - this[kMockAgentSet](origin, dispatcher) - return dispatcher - } + // 2.2 + const cache = [] - // If we match, create a pool and assign the same dispatches - for (const [keyMatcher, nonExplicitDispatcher] of Array.from(this[kClients])) { - if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { - const dispatcher = this[kFactory](origin) - this[kMockAgentSet](origin, dispatcher) - dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] - return dispatcher - } - } - } + // 2.3 + this.#caches.set(cacheName, cache) - [kGetNetConnect] () { - return this[kNetConnect] + // 2.4 + return new Cache(kConstruct, cache) } - pendingInterceptors () { - const mockAgentClients = this[kClients] + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete + * @param {string} cacheName + * @returns {Promise} + */ + async delete (cacheName) { + webidl.brandCheck(this, webidl.is.CacheStorage) - return Array.from(mockAgentClients.entries()) - .flatMap(([origin, scope]) => scope[kDispatches].map(dispatch => ({ ...dispatch, origin }))) - .filter(({ pending }) => pending) - } + const prefix = 'CacheStorage.delete' + webidl.argumentLengthCheck(arguments, 1, prefix) - assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { - const pending = this.pendingInterceptors() + cacheName = webidl.converters.DOMString(cacheName, prefix, 'cacheName') - if (pending.length === 0) { - return - } + return this.#caches.delete(cacheName) + } + + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys + * @returns {Promise} + */ + async keys () { + webidl.brandCheck(this, webidl.is.CacheStorage) - const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length) + // 2.1 + const keys = this.#caches.keys() - throw new UndiciError(` -${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: + // 2.2 + return [...keys] + } -${pendingInterceptorsFormatter.format(pending)} -`.trim()) + static { + webidl.is.CacheStorage = (arg) => { + return arg != null && typeof arg === 'object' && #caches in arg + } } } -module.exports = MockAgent +Object.defineProperties(CacheStorage.prototype, { + [Symbol.toStringTag]: { + value: 'CacheStorage', + configurable: true + }, + match: kEnumerableProperty, + has: kEnumerableProperty, + open: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) + +module.exports = { + CacheStorage +} /***/ }), -/***/ 7365: +/***/ 6798: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { promisify } = __nccwpck_require__(7975) -const Client = __nccwpck_require__(3701) -const { buildMockDispatch } = __nccwpck_require__(3397) -const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected -} = __nccwpck_require__(1117) -const { MockInterceptor } = __nccwpck_require__(1511) -const Symbols = __nccwpck_require__(6443) -const { InvalidArgumentError } = __nccwpck_require__(8707) +const assert = __nccwpck_require__(4589) +const { URLSerializer } = __nccwpck_require__(1900) +const { isValidHeaderName } = __nccwpck_require__(3168) /** - * MockClient provides an API that extends the Client to influence the mockDispatches. + * @see https://url.spec.whatwg.org/#concept-url-equals + * @param {URL} A + * @param {URL} B + * @param {boolean | undefined} excludeFragment + * @returns {boolean} */ -class MockClient extends Client { - constructor (origin, opts) { - super(origin, opts) +function urlEquals (A, B, excludeFragment = false) { + const serializedA = URLSerializer(A, excludeFragment) - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } + const serializedB = URLSerializer(B, excludeFragment) - this[kMockAgent] = opts.agent - this[kOrigin] = origin - this[kDispatches] = [] - this[kConnected] = 1 - this[kOriginalDispatch] = this.dispatch - this[kOriginalClose] = this.close.bind(this) + return serializedA === serializedB +} - this.dispatch = buildMockDispatch.call(this) - this.close = this[kClose] - } +/** + * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 + * @param {string} header + */ +function getFieldValues (header) { + assert(header !== null) - get [Symbols.kConnected] () { - return this[kConnected] + const values = [] + + for (let value of header.split(',')) { + value = value.trim() + + if (isValidHeaderName(value)) { + values.push(value) + } } - /** - * Sets up the base interceptor for mocking replies from undici. - */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) - } + return values +} + +module.exports = { + urlEquals, + getFieldValues +} + + +/***/ }), + +/***/ 1276: +/***/ ((module) => { + +"use strict"; + - async [kClose] () { - await promisify(this[kOriginalClose])() - this[kConnected] = 0 - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) - } -} +// https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size +const maxAttributeValueSize = 1024 -module.exports = MockClient +// https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size +const maxNameValuePairSize = 4096 + +module.exports = { + maxAttributeValueSize, + maxNameValuePairSize +} /***/ }), -/***/ 2429: +/***/ 9061: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { UndiciError } = __nccwpck_require__(8707) +const { parseSetCookie } = __nccwpck_require__(1978) +const { stringify } = __nccwpck_require__(7797) +const { webidl } = __nccwpck_require__(7879) -const kMockNotMatchedError = Symbol.for('undici.error.UND_MOCK_ERR_MOCK_NOT_MATCHED') +const globalHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.util.MakeTypeAssertion(globalThis.Headers)) +const undiciHeadersBrandCheck = (arg) => webidl.brandCheck(arg, webidl.is.Headers) + +function brandCheckHeaders (arg) { + try { + undiciHeadersBrandCheck(arg) + return + } catch { + } + + globalHeadersBrandCheck(arg) +} /** - * The request does not match any registered mock dispatches. + * @typedef {Object} Cookie + * @property {string} name + * @property {string} value + * @property {Date|number} [expires] + * @property {number} [maxAge] + * @property {string} [domain] + * @property {string} [path] + * @property {boolean} [secure] + * @property {boolean} [httpOnly] + * @property {'Strict'|'Lax'|'None'} [sameSite] + * @property {string[]} [unparsed] */ -class MockNotMatchedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, MockNotMatchedError) - this.name = 'MockNotMatchedError' - this.message = message || 'The request does not match any registered mock dispatches' - this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' - } - static [Symbol.hasInstance] (instance) { - return instance && instance[kMockNotMatchedError] === true - } +/** + * @param {Headers} headers + * @returns {Record} + */ +function getCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, 'getCookies') - [kMockNotMatchedError] = true -} + brandCheckHeaders(headers) -module.exports = { - MockNotMatchedError -} + const cookie = headers.get('cookie') + // A null prototype keeps a cookie named `__proto__` from hitting the + // Object.prototype setter, which would silently drop it. + /** @type {Record} */ + const out = { __proto__: null } -/***/ }), + if (!cookie) { + return out + } -/***/ 1511: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + for (const piece of cookie.split(';')) { + const [name, ...value] = piece.split('=') -"use strict"; + out[name.trim()] = value.join('=') + } + return out +} -const { getResponseData, buildKey, addMockDispatch } = __nccwpck_require__(3397) -const { - kDispatches, - kDispatchKey, - kDefaultHeaders, - kDefaultTrailers, - kContentLength, - kMockDispatch -} = __nccwpck_require__(1117) -const { InvalidArgumentError } = __nccwpck_require__(8707) -const { buildURL } = __nccwpck_require__(3440) +/** + * @param {Headers} headers + * @param {string} name + * @param {{ path?: string, domain?: string }|undefined} attributes + * @returns {void} + */ +function deleteCookie (headers, name, attributes) { + brandCheckHeaders(headers) + + const prefix = 'deleteCookie' + webidl.argumentLengthCheck(arguments, 2, prefix) + + name = webidl.converters.DOMString(name, prefix, 'name') + attributes = webidl.converters.DeleteCookieAttributes(attributes) + + // Matches behavior of + // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 + setCookie(headers, { + name, + value: '', + expires: new Date(0), + ...attributes + }) +} /** - * Defines the scope API for an interceptor reply + * @param {Headers} headers + * @returns {Cookie[]} */ -class MockScope { - constructor (mockDispatch) { - this[kMockDispatch] = mockDispatch - } +function getSetCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, 'getSetCookies') - /** - * Delay a reply by a set amount in ms. - */ - delay (waitInMs) { - if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { - throw new InvalidArgumentError('waitInMs must be a valid integer > 0') - } + brandCheckHeaders(headers) - this[kMockDispatch].delay = waitInMs - return this - } + const cookies = headers.getSetCookie() - /** - * For a defined reply, never mark as consumed. - */ - persist () { - this[kMockDispatch].persist = true - return this + if (!cookies) { + return [] } - /** - * Allow one to define a reply for a set amount of matching requests. - */ - times (repeatTimes) { - if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { - throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') - } + return cookies.map((pair) => parseSetCookie(pair)) +} - this[kMockDispatch].times = repeatTimes - return this - } +/** + * Parses a cookie string + * @param {string} cookie + */ +function parseCookie (cookie) { + cookie = webidl.converters.DOMString(cookie) + + return parseSetCookie(cookie) } /** - * Defines an interceptor for a Mock + * @param {Headers} headers + * @param {Cookie} cookie + * @returns {void} */ -class MockInterceptor { - constructor (opts, mockDispatches) { - if (typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object') - } - if (typeof opts.path === 'undefined') { - throw new InvalidArgumentError('opts.path must be defined') - } - if (typeof opts.method === 'undefined') { - opts.method = 'GET' - } - // See https://github.com/nodejs/undici/issues/1245 - // As per RFC 3986, clients are not supposed to send URI - // fragments to servers when they retrieve a document, - if (typeof opts.path === 'string') { - if (opts.query) { - opts.path = buildURL(opts.path, opts.query) - } else { - // Matches https://github.com/nodejs/undici/blob/main/lib/web/fetch/index.js#L1811 - const parsedURL = new URL(opts.path, 'data://') - opts.path = parsedURL.pathname + parsedURL.search - } - } - if (typeof opts.method === 'string') { - opts.method = opts.method.toUpperCase() - } +function setCookie (headers, cookie) { + webidl.argumentLengthCheck(arguments, 2, 'setCookie') - this[kDispatchKey] = buildKey(opts) - this[kDispatches] = mockDispatches - this[kDefaultHeaders] = {} - this[kDefaultTrailers] = {} - this[kContentLength] = false + brandCheckHeaders(headers) + + cookie = webidl.converters.Cookie(cookie) + + const str = stringify(cookie) + + if (str) { + headers.append('set-cookie', str, true) } +} - createMockScopeDispatchData ({ statusCode, data, responseOptions }) { - const responseData = getResponseData(data) - const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {} - const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers } - const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers } +webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: () => null + } +]) - return { statusCode, data, headers, trailers } +webidl.converters.Cookie = webidl.dictionaryConverter([ + { + converter: webidl.converters.DOMString, + key: 'name' + }, + { + converter: webidl.converters.DOMString, + key: 'value' + }, + { + converter: webidl.nullableConverter((value) => { + if (typeof value === 'number') { + return webidl.converters['unsigned long long'](value) + } + + return new Date(value) + }), + key: 'expires', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters['long long']), + key: 'maxAge', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'secure', + defaultValue: () => null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'httpOnly', + defaultValue: () => null + }, + { + converter: webidl.converters.USVString, + key: 'sameSite', + allowedValues: ['Strict', 'Lax', 'None'] + }, + { + converter: webidl.sequenceConverter(webidl.converters.DOMString), + key: 'unparsed', + defaultValue: () => [] } +]) - validateReplyParameters (replyParameters) { - if (typeof replyParameters.statusCode === 'undefined') { - throw new InvalidArgumentError('statusCode must be defined') - } - if (typeof replyParameters.responseOptions !== 'object' || replyParameters.responseOptions === null) { - throw new InvalidArgumentError('responseOptions must be an object') - } - } +module.exports = { + getCookies, + deleteCookie, + getSetCookies, + setCookie, + parseCookie +} - /** - * Mock an undici request with a defined reply. - */ - reply (replyOptionsCallbackOrStatusCode) { - // Values of reply aren't available right now as they - // can only be available when the reply callback is invoked. - if (typeof replyOptionsCallbackOrStatusCode === 'function') { - // We'll first wrap the provided callback in another function, - // this function will properly resolve the data from the callback - // when invoked. - const wrappedDefaultsCallback = (opts) => { - // Our reply options callback contains the parameter for statusCode, data and options. - const resolvedData = replyOptionsCallbackOrStatusCode(opts) - // Check if it is in the right format - if (typeof resolvedData !== 'object' || resolvedData === null) { - throw new InvalidArgumentError('reply options callback must return an object') - } +/***/ }), - const replyParameters = { data: '', responseOptions: {}, ...resolvedData } - this.validateReplyParameters(replyParameters) - // Since the values can be obtained immediately we return them - // from this higher order function that will be resolved later. - return { - ...this.createMockScopeDispatchData(replyParameters) - } - } +/***/ 1978: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback) - return new MockScope(newMockDispatch) - } +"use strict"; - // We can have either one or three parameters, if we get here, - // we should have 1-3 parameters. So we spread the arguments of - // this function to obtain the parameters, since replyData will always - // just be the statusCode. - const replyParameters = { - statusCode: replyOptionsCallbackOrStatusCode, - data: arguments[1] === undefined ? '' : arguments[1], - responseOptions: arguments[2] === undefined ? {} : arguments[2] - } - this.validateReplyParameters(replyParameters) - // Send in-already provided data like usual - const dispatchData = this.createMockScopeDispatchData(replyParameters) - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData) - return new MockScope(newMockDispatch) +const { collectASequenceOfCodePointsFast } = __nccwpck_require__(8116) +const { maxNameValuePairSize, maxAttributeValueSize } = __nccwpck_require__(1276) +const { isCTLExcludingHtab } = __nccwpck_require__(7797) +const assert = __nccwpck_require__(4589) + +/** + * @description Parses the field-value attributes of a set-cookie header string. + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} header + * @returns {import('./index').Cookie|null} if the header is invalid, null will be returned + */ +function parseSetCookie (header) { + // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F + // character (CTL characters excluding HTAB): Abort these steps and + // ignore the set-cookie-string entirely. + if (isCTLExcludingHtab(header)) { + return null } - /** - * Mock an undici request with a defined error. - */ - replyWithError (error) { - if (typeof error === 'undefined') { - throw new InvalidArgumentError('error must be defined') - } + let nameValuePair = '' + let unparsedAttributes = '' + let name = '' + let value = '' - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }) - return new MockScope(newMockDispatch) - } + // 2. If the set-cookie-string contains a %x3B (";") character: + if (header.includes(';')) { + // 1. The name-value-pair string consists of the characters up to, + // but not including, the first %x3B (";"), and the unparsed- + // attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question). + const position = { position: 0 } - /** - * Set default reply headers on the interceptor for subsequent replies - */ - defaultReplyHeaders (headers) { - if (typeof headers === 'undefined') { - throw new InvalidArgumentError('headers must be defined') - } + nameValuePair = collectASequenceOfCodePointsFast(';', header, position) + unparsedAttributes = header.slice(position.position) + } else { + // Otherwise: - this[kDefaultHeaders] = headers - return this + // 1. The name-value-pair string consists of all the characters + // contained in the set-cookie-string, and the unparsed- + // attributes is the empty string. + nameValuePair = header } - /** - * Set default reply trailers on the interceptor for subsequent replies - */ - defaultReplyTrailers (trailers) { - if (typeof trailers === 'undefined') { - throw new InvalidArgumentError('trailers must be defined') - } + // 3. If the name-value-pair string lacks a %x3D ("=") character, then + // the name string is empty, and the value string is the value of + // name-value-pair. + if (!nameValuePair.includes('=')) { + value = nameValuePair + } else { + // Otherwise, the name string consists of the characters up to, but + // not including, the first %x3D ("=") character, and the (possibly + // empty) value string consists of the characters after the first + // %x3D ("=") character. + const position = { position: 0 } + name = collectASequenceOfCodePointsFast( + '=', + nameValuePair, + position + ) + value = nameValuePair.slice(position.position + 1) + } - this[kDefaultTrailers] = trailers - return this + // 4. Remove any leading or trailing WSP characters from the name + // string and the value string. + name = name.trim() + value = value.trim() + + // 5. If the sum of the lengths of the name string and the value string + // is more than 4096 octets, abort these steps and ignore the set- + // cookie-string entirely. + if (name.length + value.length > maxNameValuePairSize) { + return null } - /** - * Set reply content length header for replies on the interceptor - */ - replyContentLength () { - this[kContentLength] = true - return this + // 6. The cookie-name is the name string, and the cookie-value is the + // value string. + // https://datatracker.ietf.org/doc/html/rfc6265 + // To maximize compatibility with user agents, servers that wish to + // store arbitrary data in a cookie-value SHOULD encode that data, for + // example, using Base64 [RFC4648]. + return { + name, value, ...parseUnparsedAttributes(unparsedAttributes) } } -module.exports.MockInterceptor = MockInterceptor -module.exports.MockScope = MockScope - +/** + * Parses the remaining attributes of a set-cookie header + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} unparsedAttributes + * @param {Object.} [cookieAttributeList={}] + */ +function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { + while (true) { + // 1. If the unparsed-attributes string is empty, skip the rest of + // these steps. + if (unparsedAttributes.length === 0) { + return cookieAttributeList + } -/***/ }), + // 2. Discard the first character of the unparsed-attributes (which + // will be a %x3B (";") character). + assert(unparsedAttributes[0] === ';') + unparsedAttributes = unparsedAttributes.slice(1) -/***/ 4004: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let cookieAv = '' -"use strict"; + // 3. If the remaining unparsed-attributes contains a %x3B (";") + // character: + if (unparsedAttributes.includes(';')) { + // 1. Consume the characters of the unparsed-attributes up to, but + // not including, the first %x3B (";") character. + cookieAv = collectASequenceOfCodePointsFast( + ';', + unparsedAttributes, + { position: 0 } + ) + unparsedAttributes = unparsedAttributes.slice(cookieAv.length) + } else { + // Otherwise: + // 1. Consume the remainder of the unparsed-attributes. + cookieAv = unparsedAttributes + unparsedAttributes = '' + } -const { promisify } = __nccwpck_require__(7975) -const Pool = __nccwpck_require__(628) -const { buildMockDispatch } = __nccwpck_require__(3397) -const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected -} = __nccwpck_require__(1117) -const { MockInterceptor } = __nccwpck_require__(1511) -const Symbols = __nccwpck_require__(6443) -const { InvalidArgumentError } = __nccwpck_require__(8707) + // Let the cookie-av string be the characters consumed in this step. -/** - * MockPool provides an API that extends the Pool to influence the mockDispatches. - */ -class MockPool extends Pool { - constructor (origin, opts) { - super(origin, opts) + let attributeName = '' + let attributeValue = '' - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } + // 4. If the cookie-av string contains a %x3D ("=") character: + if (cookieAv.includes('=')) { + // 1. The (possibly empty) attribute-name string consists of the + // characters up to, but not including, the first %x3D ("=") + // character, and the (possibly empty) attribute-value string + // consists of the characters after the first %x3D ("=") + // character. + const position = { position: 0 } - this[kMockAgent] = opts.agent - this[kOrigin] = origin - this[kDispatches] = [] - this[kConnected] = 1 - this[kOriginalDispatch] = this.dispatch - this[kOriginalClose] = this.close.bind(this) + attributeName = collectASequenceOfCodePointsFast( + '=', + cookieAv, + position + ) + attributeValue = cookieAv.slice(position.position + 1) + } else { + // Otherwise: - this.dispatch = buildMockDispatch.call(this) - this.close = this[kClose] - } + // 1. The attribute-name string consists of the entire cookie-av + // string, and the attribute-value string is empty. + attributeName = cookieAv + } - get [Symbols.kConnected] () { - return this[kConnected] - } + // 5. Remove any leading or trailing WSP characters from the attribute- + // name string and the attribute-value string. + attributeName = attributeName.trim() + attributeValue = attributeValue.trim() - /** - * Sets up the base interceptor for mocking replies from undici. - */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) - } + // 6. If the attribute-value is longer than 1024 octets, ignore the + // cookie-av string and return to Step 1 of this algorithm. + if (attributeValue.length > maxAttributeValueSize) { + continue + } - async [kClose] () { - await promisify(this[kOriginalClose])() - this[kConnected] = 0 - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) - } -} + // 7. Process the attribute-name and attribute-value according to the + // requirements in the following subsections. (Notice that + // attributes with unrecognized attribute-names are ignored.) + const attributeNameLowercase = attributeName.toLowerCase() -module.exports = MockPool + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 + // If the attribute-name case-insensitively matches the string + // "Expires", the user agent MUST process the cookie-av as follows. + if (attributeNameLowercase === 'expires') { + // 1. Let the expiry-time be the result of parsing the attribute-value + // as cookie-date (see Section 5.1.1). + const expiryTime = new Date(attributeValue) + // 2. If the attribute-value failed to parse as a cookie date, ignore + // the cookie-av. + if (!Number.isNaN(expiryTime.getTime())) { + cookieAttributeList.expires = expiryTime + } + } else if (attributeNameLowercase === 'max-age') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 + // If the attribute-name case-insensitively matches the string "Max- + // Age", the user agent MUST process the cookie-av as follows. -/***/ }), + // 1. If the first character of the attribute-value is not a DIGIT or a + // "-" character, ignore the cookie-av. + const charCode = attributeValue.charCodeAt(0) + const startsWithDigit = charCode >= 48 && charCode <= 57 + const startsWithSignedDigit = attributeValue[0] === '-' && attributeValue.length > 1 -/***/ 1117: -/***/ ((module) => { + if (!startsWithDigit && !startsWithSignedDigit) { + continue + } -"use strict"; + // 2. If the remainder of attribute-value contains a non-DIGIT + // character, ignore the cookie-av. + if (/[^\d]/.test(attributeValue.slice(1))) { + continue + } + // 3. Let delta-seconds be the attribute-value converted to an integer. + const deltaSeconds = Number(attributeValue) -module.exports = { - kAgent: Symbol('agent'), - kOptions: Symbol('options'), - kFactory: Symbol('factory'), - kDispatches: Symbol('dispatches'), - kDispatchKey: Symbol('dispatch key'), - kDefaultHeaders: Symbol('default headers'), - kDefaultTrailers: Symbol('default trailers'), - kContentLength: Symbol('content length'), - kMockAgent: Symbol('mock agent'), - kMockAgentSet: Symbol('mock agent set'), - kMockAgentGet: Symbol('mock agent get'), - kMockDispatch: Symbol('mock dispatch'), - kClose: Symbol('close'), - kOriginalClose: Symbol('original agent close'), - kOrigin: Symbol('origin'), - kIsMockActive: Symbol('is mock active'), - kNetConnect: Symbol('net connect'), - kGetNetConnect: Symbol('get net connect'), - kConnected: Symbol('connected') -} + // 4. Let cookie-age-limit be the maximum age of the cookie (which + // SHOULD be 400 days or less, see Section 4.1.2.2). + // 5. Set delta-seconds to the smaller of its present value and cookie- + // age-limit. + // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) -/***/ }), + // 6. If delta-seconds is less than or equal to zero (0), let expiry- + // time be the earliest representable date and time. Otherwise, let + // the expiry-time be the current date and time plus delta-seconds + // seconds. + // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds -/***/ 3397: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 7. Append an attribute to the cookie-attribute-list with an + // attribute-name of Max-Age and an attribute-value of expiry-time. + cookieAttributeList.maxAge = deltaSeconds + } else if (attributeNameLowercase === 'domain') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 + // If the attribute-name case-insensitively matches the string "Domain", + // the user agent MUST process the cookie-av as follows. -"use strict"; + // 1. Let cookie-domain be the attribute-value. + let cookieDomain = attributeValue + // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be + // cookie-domain without its leading %x2E ("."). + if (cookieDomain[0] === '.') { + cookieDomain = cookieDomain.slice(1) + } -const { MockNotMatchedError } = __nccwpck_require__(2429) -const { - kDispatches, - kMockAgent, - kOriginalDispatch, - kOrigin, - kGetNetConnect -} = __nccwpck_require__(1117) -const { buildURL } = __nccwpck_require__(3440) -const { STATUS_CODES } = __nccwpck_require__(7067) -const { - types: { - isPromise - } -} = __nccwpck_require__(7975) + // 3. Convert the cookie-domain to lower case. + cookieDomain = cookieDomain.toLowerCase() -function matchValue (match, value) { - if (typeof match === 'string') { - return match === value - } - if (match instanceof RegExp) { - return match.test(value) - } - if (typeof match === 'function') { - return match(value) === true - } - return false -} + // 4. Append an attribute to the cookie-attribute-list with an + // attribute-name of Domain and an attribute-value of cookie-domain. + cookieAttributeList.domain = cookieDomain + } else if (attributeNameLowercase === 'path') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 + // If the attribute-name case-insensitively matches the string "Path", + // the user agent MUST process the cookie-av as follows. -function lowerCaseEntries (headers) { - return Object.fromEntries( - Object.entries(headers).map(([headerName, headerValue]) => { - return [headerName.toLocaleLowerCase(), headerValue] - }) - ) -} + // 1. If the attribute-value is empty or if the first character of the + // attribute-value is not %x2F ("/"): + let cookiePath = '' + if (attributeValue.length === 0 || attributeValue[0] !== '/') { + // 1. Let cookie-path be the default-path. + cookiePath = '/' + } else { + // Otherwise: -/** - * @param {import('../../index').Headers|string[]|Record} headers - * @param {string} key - */ -function getHeaderByName (headers, key) { - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { - return headers[i + 1] + // 1. Let cookie-path be the attribute-value. + cookiePath = attributeValue } - } - return undefined - } else if (typeof headers.get === 'function') { - return headers.get(key) - } else { - return lowerCaseEntries(headers)[key.toLocaleLowerCase()] - } -} + // 2. Append an attribute to the cookie-attribute-list with an + // attribute-name of Path and an attribute-value of cookie-path. + cookieAttributeList.path = cookiePath + } else if (attributeNameLowercase === 'secure') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 + // If the attribute-name case-insensitively matches the string "Secure", + // the user agent MUST append an attribute to the cookie-attribute-list + // with an attribute-name of Secure and an empty attribute-value. -/** @param {string[]} headers */ -function buildHeadersFromArray (headers) { // fetch HeadersList - const clone = headers.slice() - const entries = [] - for (let index = 0; index < clone.length; index += 2) { - entries.push([clone[index], clone[index + 1]]) - } - return Object.fromEntries(entries) -} + cookieAttributeList.secure = true + } else if (attributeNameLowercase === 'httponly') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 + // If the attribute-name case-insensitively matches the string + // "HttpOnly", the user agent MUST append an attribute to the cookie- + // attribute-list with an attribute-name of HttpOnly and an empty + // attribute-value. -function matchHeaders (mockDispatch, headers) { - if (typeof mockDispatch.headers === 'function') { - if (Array.isArray(headers)) { // fetch HeadersList - headers = buildHeadersFromArray(headers) - } - return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) - } - if (typeof mockDispatch.headers === 'undefined') { - return true - } - if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { - return false - } + cookieAttributeList.httpOnly = true + } else if (attributeNameLowercase === 'samesite') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 + // If the attribute-name case-insensitively matches the string + // "SameSite", the user agent MUST process the cookie-av as follows: - for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { - const headerValue = getHeaderByName(headers, matchHeaderName) + const attributeValueLowercase = attributeValue.toLowerCase() + + // 1. If cookie-av's attribute-value is a case-insensitive match for + // "None", append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of "None". + if (attributeValueLowercase === 'none') { + cookieAttributeList.sameSite = 'None' + } else if (attributeValueLowercase === 'strict') { + // 2. If cookie-av's attribute-value is a case-insensitive match for + // "Strict", append an attribute to the cookie-attribute-list with + // an attribute-name of "SameSite" and an attribute-value of + // "Strict". + cookieAttributeList.sameSite = 'Strict' + } else if (attributeValueLowercase === 'lax') { + // 3. If cookie-av's attribute-value is a case-insensitive match for + // "Lax", append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of "Lax". + cookieAttributeList.sameSite = 'Lax' + } + } else { + cookieAttributeList.unparsed ??= [] - if (!matchValue(matchHeaderValue, headerValue)) { - return false + cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`) } - } - return true -} -function safeUrl (path) { - if (typeof path !== 'string') { - return path + // 8. Return to Step 1 of this algorithm. } +} - const pathSegments = path.split('?') +module.exports = { + parseSetCookie, + parseUnparsedAttributes +} - if (pathSegments.length !== 2) { - return path - } - const qp = new URLSearchParams(pathSegments.pop()) - qp.sort() - return [...pathSegments, qp.toString()].join('?') -} +/***/ }), -function matchKey (mockDispatch, { path, method, body, headers }) { - const pathMatch = matchValue(mockDispatch.path, path) - const methodMatch = matchValue(mockDispatch.method, method) - const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true - const headersMatch = matchHeaders(mockDispatch, headers) - return pathMatch && methodMatch && bodyMatch && headersMatch -} +/***/ 7797: +/***/ ((module) => { -function getResponseData (data) { - if (Buffer.isBuffer(data)) { - return data - } else if (data instanceof Uint8Array) { - return data - } else if (data instanceof ArrayBuffer) { - return data - } else if (typeof data === 'object') { - return JSON.stringify(data) - } else { - return data.toString() - } -} +"use strict"; -function getMockDispatch (mockDispatches, key) { - const basePath = key.query ? buildURL(key.path, key.query) : key.path - const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath - // Match path - let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) - } +/** + * @param {string} value + * @returns {boolean} + */ +function isCTLExcludingHtab (value) { + for (let i = 0; i < value.length; ++i) { + const code = value.charCodeAt(i) - // Match method - matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}' on path '${resolvedPath}'`) + if ( + (code >= 0x00 && code <= 0x08) || + (code >= 0x0A && code <= 0x1F) || + code === 0x7F + ) { + return true + } } + return false +} - // Match body - matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}' on path '${resolvedPath}'`) - } +/** + CHAR = + token = 1* + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + * @param {string} name + */ +function validateCookieName (name) { + for (let i = 0; i < name.length; ++i) { + const code = name.charCodeAt(i) - // Match headers - matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)) - if (matchedMockDispatches.length === 0) { - const headers = typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers - throw new MockNotMatchedError(`Mock dispatch not matched for headers '${headers}' on path '${resolvedPath}'`) + if ( + code < 0x21 || // exclude CTLs (0-31), SP and HT + code > 0x7E || // exclude non-ascii and DEL + code === 0x22 || // " + code === 0x28 || // ( + code === 0x29 || // ) + code === 0x3C || // < + code === 0x3E || // > + code === 0x40 || // @ + code === 0x2C || // , + code === 0x3B || // ; + code === 0x3A || // : + code === 0x5C || // \ + code === 0x2F || // / + code === 0x5B || // [ + code === 0x5D || // ] + code === 0x3F || // ? + code === 0x3D || // = + code === 0x7B || // { + code === 0x7D // } + ) { + throw new Error('Invalid cookie name') + } } - - return matchedMockDispatches[0] } -function addMockDispatch (mockDispatches, key, data) { - const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false } - const replyData = typeof data === 'function' ? { callback: data } : { ...data } - const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } } - mockDispatches.push(newMockDispatch) - return newMockDispatch -} +/** + cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + ; US-ASCII characters excluding CTLs, + ; whitespace DQUOTE, comma, semicolon, + ; and backslash + * @param {string} value + */ +function validateCookieValue (value) { + let len = value.length + let i = 0 -function deleteMockDispatch (mockDispatches, key) { - const index = mockDispatches.findIndex(dispatch => { - if (!dispatch.consumed) { - return false + // if the value is wrapped in DQUOTE + if (value[0] === '"') { + if (len === 1 || value[len - 1] !== '"') { + throw new Error('Invalid cookie value') } - return matchKey(dispatch, key) - }) - if (index !== -1) { - mockDispatches.splice(index, 1) + --len + ++i } -} -function buildKey (opts) { - const { path, method, body, headers, query } = opts - return { - path, - method, - body, - headers, - query - } -} + while (i < len) { + const code = value.charCodeAt(i++) -function generateKeyValues (data) { - const keys = Object.keys(data) - const result = [] - for (let i = 0; i < keys.length; ++i) { - const key = keys[i] - const value = data[key] - const name = Buffer.from(`${key}`) - if (Array.isArray(value)) { - for (let j = 0; j < value.length; ++j) { - result.push(name, Buffer.from(`${value[j]}`)) - } - } else { - result.push(name, Buffer.from(`${value}`)) + if ( + code < 0x21 || // exclude CTLs (0-31) + code > 0x7E || // non-ascii and DEL (127) + code === 0x22 || // " + code === 0x2C || // , + code === 0x3B || // ; + code === 0x5C // \ + ) { + throw new Error('Invalid cookie value') } } - return result } /** - * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status - * @param {number} statusCode + * path-value = + * @param {string} path */ -function getStatusText (statusCode) { - return STATUS_CODES[statusCode] || 'unknown' -} +function validateCookiePath (path) { + for (let i = 0; i < path.length; ++i) { + const code = path.charCodeAt(i) -async function getResponse (body) { - const buffers = [] - for await (const data of body) { - buffers.push(data) + if ( + code < 0x20 || // exclude CTLs (0-31) + code > 0x7E || // exclude non-ascii and DEL + code === 0x3B // ; + ) { + throw new Error('Invalid cookie path') + } } - return Buffer.concat(buffers).toString('utf8') } /** - * Mock dispatch function used to simulate undici dispatches + * ::= | + * + * ::= any one of the 52 alphabetic characters A through Z in + * upper case and a through z in lower case + * + * ::= any one of the ten digits 0 through 9r + * + * @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5 + * @param {number} code */ -function mockDispatch (opts, handler) { - // Get mock dispatch from built key - const key = buildKey(opts) - const mockDispatch = getMockDispatch(this[kDispatches], key) - - mockDispatch.timesInvoked++ - - // Here's where we resolve a callback if a callback is present for the dispatch data. - if (mockDispatch.data.callback) { - mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) } - } - - // Parse mockDispatch data - const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch - const { timesInvoked, times } = mockDispatch - - // If it's used up and not persistent, mark as consumed - mockDispatch.consumed = !persist && timesInvoked >= times - mockDispatch.pending = timesInvoked < times +function isLetterOrDigit (code) { + return ( + (code >= 0x30 && code <= 0x39) || // 0-9 + (code >= 0x41 && code <= 0x5A) || // A-Z + (code >= 0x61 && code <= 0x7A) // a-z + ) +} - // If specified, trigger dispatch error - if (error !== null) { - deleteMockDispatch(this[kDispatches], key) - handler.onError(error) - return true +/** + * Validates a cookie domain against the "preferred name syntax". + * + * ::= | " " + * ::=