diff --git a/.pnp.cjs b/.pnp.cjs index de9373a8d7f9..d07d62a00835 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -7918,16 +7918,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["@types/tunnel", [\ - ["npm:0.0.0", {\ - "packageLocation": "./.yarn/cache/@types-tunnel-npm-0.0.0-60b0691686-bd3a79bd7b.zip/node_modules/@types/tunnel/",\ - "packageDependencies": [\ - ["@types/node", "npm:18.19.17"],\ - ["@types/tunnel", "npm:0.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["@types/unist", [\ ["npm:2.0.3", {\ "packageLocation": "./.yarn/cache/@types-unist-npm-2.0.3-4b26dedfde-c13ec9068d.zip/node_modules/@types/unist/",\ @@ -9468,7 +9458,6 @@ const RAW_RUNTIME_STATE = ["@types/semver", "npm:7.5.8"],\ ["@types/tar", "npm:4.0.4"],\ ["@types/treeify", "npm:1.0.0"],\ - ["@types/tunnel", "npm:0.0.0"],\ ["@yarnpkg/cli", "virtual:712d04b0098634bdb13868ff8f85b327022bd7d3880873ada8c0ae56847ed36cf9da1fd74a88519380129cec528fe2bd2201426bc28ac9d4a8cc6734ff25c538#workspace:packages/yarnpkg-cli"],\ ["@yarnpkg/core", "workspace:packages/yarnpkg-core"],\ ["@yarnpkg/fslib", "workspace:packages/yarnpkg-fslib"],\ @@ -9492,6 +9481,7 @@ const RAW_RUNTIME_STATE = ]],\ ["fast-glob", "npm:3.3.2"],\ ["got", "npm:11.8.2"],\ + ["hpagent", "npm:1.2.0"],\ ["lodash", "npm:4.17.21"],\ ["micromatch", "npm:4.0.5"],\ ["p-limit", "npm:2.2.0"],\ @@ -9503,8 +9493,7 @@ const RAW_RUNTIME_STATE = ["tar", "npm:6.1.11"],\ ["tinylogic", "npm:2.0.0"],\ ["treeify", "npm:1.1.0"],\ - ["tslib", "npm:2.6.2"],\ - ["tunnel", "npm:0.0.6"]\ + ["tslib", "npm:2.6.2"]\ ],\ "linkType": "SOFT"\ }]\ @@ -25667,6 +25656,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["hpagent", [\ + ["npm:1.2.0", {\ + "packageLocation": "./.yarn/cache/hpagent-npm-1.2.0-0f725aa4fe-bad186449d.zip/node_modules/hpagent/",\ + "packageDependencies": [\ + ["hpagent", "npm:1.2.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["htm", [\ ["npm:3.1.1", {\ "packageLocation": "./.yarn/cache/htm-npm-3.1.1-e3b831f850-cb862dc5c9.zip/node_modules/htm/",\ diff --git a/.yarn/cache/@types-tunnel-npm-0.0.0-60b0691686-bd3a79bd7b.zip b/.yarn/cache/@types-tunnel-npm-0.0.0-60b0691686-bd3a79bd7b.zip deleted file mode 100644 index a9650fd99fc0..000000000000 Binary files a/.yarn/cache/@types-tunnel-npm-0.0.0-60b0691686-bd3a79bd7b.zip and /dev/null differ diff --git a/.yarn/cache/hpagent-npm-1.2.0-0f725aa4fe-bad186449d.zip b/.yarn/cache/hpagent-npm-1.2.0-0f725aa4fe-bad186449d.zip new file mode 100644 index 000000000000..fa1fac30f7fb Binary files /dev/null and b/.yarn/cache/hpagent-npm-1.2.0-0f725aa4fe-bad186449d.zip differ diff --git a/.yarn/versions/562a0ff0.yml b/.yarn/versions/562a0ff0.yml new file mode 100644 index 000000000000..4e49cece1c7b --- /dev/null +++ b/.yarn/versions/562a0ff0.yml @@ -0,0 +1,35 @@ +releases: + "@yarnpkg/cli": patch + "@yarnpkg/core": patch + "@yarnpkg/plugin-essentials": patch + "@yarnpkg/plugin-git": patch + "@yarnpkg/plugin-github": patch + "@yarnpkg/plugin-http": patch + "@yarnpkg/plugin-npm": patch + "@yarnpkg/plugin-npm-cli": patch + "@yarnpkg/plugin-typescript": patch + +declined: + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-exec" + - "@yarnpkg/plugin-file" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-jsr" + - "@yarnpkg/plugin-link" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/doctor" + - "@yarnpkg/extensions" + - "@yarnpkg/nm" + - "@yarnpkg/pnpify" + - "@yarnpkg/sdks" diff --git a/packages/acceptance-tests/pkg-tests-core/sources/utils/tests.ts b/packages/acceptance-tests/pkg-tests-core/sources/utils/tests.ts index cd25152a65c8..daf123a33193 100644 --- a/packages/acceptance-tests/pkg-tests-core/sources/utils/tests.ts +++ b/packages/acceptance-tests/pkg-tests-core/sources/utils/tests.ts @@ -9,6 +9,7 @@ import {IncomingMessage, ServerResponse} from 'http'; import http from 'http'; import invariant from 'invariant'; import {AddressInfo} from 'net'; +import net from 'net'; import os from 'os'; import pem from 'pem'; import semver from 'semver'; @@ -808,6 +809,110 @@ export const startPackageServer = ({type}: {type: keyof typeof packageServerUrls }); }; +const proxyServerUrls: { + http: Promise | null; + https: Promise | null; +} = {http: null, https: null}; + +export const startProxyServer = ({type = `http`}: {type?: keyof typeof proxyServerUrls} = {}): Promise => { + const serverUrl = proxyServerUrls[type]; + if (serverUrl !== null) + return serverUrl; + + const sendError = (res: ServerResponse, statusCode: number, errorMessage: string): void => { + res.writeHead(statusCode); + res.end(errorMessage); + }; + + return proxyServerUrls[type] = new Promise((resolve, reject) => { + const listener: http.RequestListener = (req, res) => { + void (async () => { + try { + if (!req.url) { + sendError(res, 400, `Missing URL in request`); + return; + } + + const url = new URL(req.url); + const options = { + hostname: url.hostname, + port: url.port || (url.protocol === `https:` ? 443 : 80), + path: `${url.pathname}${url.search}`, + method: req.method, + headers: {...req.headers}, + }; + + delete options.headers[`proxy-authorization`]; + delete options.headers[`proxy-connection`]; + options.headers.connection = `close`; + + const proxyReq = (url.protocol === `https:` ? https : http).request(options, proxyRes => { + res.writeHead(proxyRes.statusCode || 500, proxyRes.headers); + proxyRes.pipe(res); + }); + + req.pipe(proxyReq); + + proxyReq.on(`error`, err => { + sendError(res, 502, `Proxy error: ${err.message}`); + }); + } catch (error) { + sendError(res, 500, `Proxy server error: ${error.message}`); + } + })(); + }; + + (async () => { + let server: https.Server | http.Server; + + if (type === `https`) { + const certs = await getHttpsCertificates(); + + server = https.createServer({ + cert: certs.server.certificate, + key: certs.server.clientKey, + ca: certs.ca.certificate, + }, listener); + } else { + server = http.createServer(listener); + } + + // Handle the CONNECT method using the 'connect' event + server.on(`connect`, (req, clientSocket, head) => { + // Parse the target and establish the connection + const [targetHost, targetPort] = (req.url || ``).split(`:`); + const port = parseInt(targetPort) || 443; + + const serverSocket = net.connect(port, targetHost, () => { + clientSocket.write( + `HTTP/1.1 200 Connection Established\r\n` + + `\r\n`, + ); + + serverSocket.write(head); + + serverSocket.pipe(clientSocket); + clientSocket.pipe(serverSocket); + }); + + serverSocket.on(`error`, () => { + clientSocket.end(); + }); + clientSocket.on(`error`, () => { + serverSocket.end(); + }); + }); + + // We don't want the server to prevent the process from exiting + server.unref(); + server.listen(() => { + const {port} = server.address() as AddressInfo; + resolve(`${type}://localhost:${port}`); + }); + })(); + }); +}; + export interface PackageDriver { (packageJson: Record, subDefinition: Record | RunFunction, fn?: RunFunction): any; getPackageManagerName: () => string; diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/proxy.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/proxy.test.ts new file mode 100644 index 000000000000..9162c06412a6 --- /dev/null +++ b/packages/acceptance-tests/pkg-tests-specs/sources/proxy.test.ts @@ -0,0 +1,221 @@ +import {ppath} from '@yarnpkg/fslib'; +import {fs, tests} from 'pkg-tests-core'; + +const {writeFile} = fs; +const {startPackageServer, startProxyServer, getHttpsCertificates, validLogins} = tests; + +describe(`Proxy tests`, () => { + test( + `it should install packages from an HTTP server through an HTTP proxy`, + makeTemporaryEnv( + { + dependencies: {[`@private/package`]: `1.0.0`}, + }, + async ({path, run, source}) => { + const url = await startPackageServer(); + const proxyUrl = await startProxyServer(); + + await writeFile(ppath.join(path, `.yarnrc.yml`), [ + `httpProxy: "${proxyUrl}"`, + `npmScopes:`, + ` private:`, + ` npmRegistryServer: "${url}"`, + ` npmAuthToken: ${validLogins.fooUser.npmAuthToken}`, + ].join(`\n`)); + + await run(`install`); + + await expect(source(`require('@private/package')`)).resolves.toMatchObject({ + name: `@private/package`, + version: `1.0.0`, + }); + }, + ), + ); + + test( + `it should install packages from an HTTPS server through an HTTP proxy`, + makeTemporaryEnv( + { + dependencies: {[`@private/package`]: `1.0.0`}, + }, + async ({path, run, source}) => { + const url = await startPackageServer({type: `https`}); + const proxyUrl = await startProxyServer(); + const certs = await getHttpsCertificates(); + + const caPath = ppath.join(path, `rootCA.crt`); + + await writeFile(caPath, certs.ca.certificate); + await writeFile(ppath.join(path, `.yarnrc.yml`), [ + `httpsProxy: "${proxyUrl}"`, + `httpsCaFilePath: ${caPath}`, + `npmScopes:`, + ` private:`, + ` npmRegistryServer: "${url}"`, + ` npmAuthToken: ${validLogins.fooUser.npmAuthToken}`, + ].join(`\n`)); + + await run(`install`); + + await expect(source(`require('@private/package')`)).resolves.toMatchObject({ + name: `@private/package`, + version: `1.0.0`, + }); + }, + ), + ); + + test( + `it should install packages from an HTTPS server through an HTTP proxy with enableStrictSsl: false`, + makeTemporaryEnv( + { + dependencies: {[`@private/package`]: `1.0.0`}, + }, + async ({path, run, source}) => { + const url = await startPackageServer({type: `https`}); + const proxyUrl = await startProxyServer(); + + await writeFile(ppath.join(path, `.yarnrc.yml`), [ + `httpsProxy: "${proxyUrl}"`, + `enableStrictSsl: false`, + `npmScopes:`, + ` private:`, + ` npmRegistryServer: "${url}"`, + ` npmAuthToken: ${validLogins.fooUser.npmAuthToken}`, + ].join(`\n`)); + + await run(`install`); + + await expect(source(`require('@private/package')`)).resolves.toMatchObject({ + name: `@private/package`, + version: `1.0.0`, + }); + }, + ), + ); + + test( + `it should install packages from an HTTP server through an HTTPS proxy`, + makeTemporaryEnv( + { + dependencies: {[`@private/package`]: `1.0.0`}, + }, + async ({path, run, source}) => { + const url = await startPackageServer(); + const proxyUrl = await startProxyServer({type: `https`}); + const certs = await getHttpsCertificates(); + + const caPath = ppath.join(path, `rootCA.crt`); + + await writeFile(caPath, certs.ca.certificate); + await writeFile(ppath.join(path, `.yarnrc.yml`), [ + `httpProxy: "${proxyUrl}"`, + `httpsCaFilePath: ${caPath}`, + `npmScopes:`, + ` private:`, + ` npmRegistryServer: "${url}"`, + ` npmAuthToken: ${validLogins.fooUser.npmAuthToken}`, + ].join(`\n`)); + + await run(`install`); + + await expect(source(`require('@private/package')`)).resolves.toMatchObject({ + name: `@private/package`, + version: `1.0.0`, + }); + }, + ), + ); + + test( + `it should install packages from an HTTP server through an HTTPS proxy with enableStrictSsl: false`, + makeTemporaryEnv( + { + dependencies: {[`@private/package`]: `1.0.0`}, + }, + async ({path, run, source}) => { + const url = await startPackageServer(); + const proxyUrl = await startProxyServer({type: `https`}); + + await writeFile(ppath.join(path, `.yarnrc.yml`), [ + `httpProxy: "${proxyUrl}"`, + `enableStrictSsl: false`, + `npmScopes:`, + ` private:`, + ` npmRegistryServer: "${url}"`, + ` npmAuthToken: ${validLogins.fooUser.npmAuthToken}`, + ].join(`\n`)); + + await run(`install`); + + await expect(source(`require('@private/package')`)).resolves.toMatchObject({ + name: `@private/package`, + version: `1.0.0`, + }); + }, + ), + ); + + test( + `it should install packages from an HTTPS server through an HTTPS proxy`, + makeTemporaryEnv( + { + dependencies: {[`@private/package`]: `1.0.0`}, + }, + async ({path, run, source}) => { + const url = await startPackageServer({type: `https`}); + const proxyUrl = await startProxyServer({type: `https`}); + const certs = await getHttpsCertificates(); + + const caPath = ppath.join(path, `rootCA.crt`); + + await writeFile(caPath, certs.ca.certificate); + await writeFile(ppath.join(path, `.yarnrc.yml`), [ + `httpsProxy: "${proxyUrl}"`, + `httpsCaFilePath: ${caPath}`, + `npmScopes:`, + ` private:`, + ` npmRegistryServer: "${url}"`, + ` npmAuthToken: ${validLogins.fooUser.npmAuthToken}`, + ].join(`\n`)); + + await run(`install`); + + await expect(source(`require('@private/package')`)).resolves.toMatchObject({ + name: `@private/package`, + version: `1.0.0`, + }); + }, + ), + ); + + test( + `it should install packages from an HTTPS server through an HTTPS proxy with enableStrictSsl: false`, + makeTemporaryEnv( + { + dependencies: {[`@private/package`]: `1.0.0`}, + }, + async ({path, run, source}) => { + const url = await startPackageServer({type: `https`}); + const proxyUrl = await startProxyServer({type: `https`}); + + await writeFile(ppath.join(path, `.yarnrc.yml`), [ + `httpsProxy: "${proxyUrl}"`, + `enableStrictSsl: false`, + `npmScopes:`, + ` private:`, + ` npmRegistryServer: "${url}"`, + ` npmAuthToken: ${validLogins.fooUser.npmAuthToken}`, + ].join(`\n`)); + + await run(`install`); + + await expect(source(`require('@private/package')`)).resolves.toMatchObject({ + name: `@private/package`, + version: `1.0.0`, + }); + }, + ), + ); +}); diff --git a/packages/docusaurus/static/configuration/yarnrc.json b/packages/docusaurus/static/configuration/yarnrc.json index 07f342f90a27..168f5dd5669c 100644 --- a/packages/docusaurus/static/configuration/yarnrc.json +++ b/packages/docusaurus/static/configuration/yarnrc.json @@ -35,13 +35,6 @@ "enum": ["required-only", "match-spec", "always"], "default": "always" }, - "httpsCaFilePath": { - "_package": "@yarnpkg/core", - "title": "Path to a file containing one or multiple Certificate Authority signing certificates.", - "type": "string", - "format": "uri-reference", - "examples": ["./exampleCA.pem"] - }, "changesetBaseRefs": { "_package": "@yarnpkg/plugin-git", "title": "List of git refs against which Yarn will compare your branch when it needs to detect changes.", @@ -267,7 +260,6 @@ "httpProxy": { "_package": "@yarnpkg/core", "title": "Proxy to use when making an HTTP request.", - "description": "Only HTTP proxies are supported at the moment.", "type": "string", "format": "uri", "examples": ["http://proxy:4040"] @@ -284,6 +276,13 @@ "type": "number", "default": 60000 }, + "httpsCaFilePath": { + "_package": "@yarnpkg/core", + "title": "Path to a file containing one or multiple Certificate Authority signing certificates.", + "type": "string", + "format": "uri-reference", + "examples": ["./exampleCA.pem"] + }, "httpsCertFilePath": { "_package": "@yarnpkg/core", "title": "Path to a file containing a certificate chain in PEM format.", @@ -301,7 +300,6 @@ "httpsProxy": { "_package": "@yarnpkg/core", "title": "Define a proxy to use when making an HTTPS request.", - "description": "Only HTTP proxies are supported at the moment.", "type": "string", "format": "uri", "examples": ["http://proxy:4040"] @@ -424,15 +422,15 @@ "^(.+)$": { "type": "object", "properties": { - "httpsCaFilePath": { - "$ref": "#/properties/httpsCaFilePath" - }, "enableNetwork": { "$ref": "#/properties/enableNetwork" }, "httpProxy": { "$ref": "#/properties/httpProxy" }, + "httpsCaFilePath": { + "$ref": "#/properties/httpsCaFilePath" + }, "httpsCertFilePath": { "$ref": "#/properties/httpsCertFilePath" }, diff --git a/packages/yarnpkg-core/package.json b/packages/yarnpkg-core/package.json index 45cc9204a441..cb9bd79c9298 100644 --- a/packages/yarnpkg-core/package.json +++ b/packages/yarnpkg-core/package.json @@ -27,6 +27,7 @@ "dotenv": "^16.3.1", "fast-glob": "^3.2.2", "got": "^11.7.0", + "hpagent": "^1.2.0", "lodash": "^4.17.15", "micromatch": "^4.0.2", "p-limit": "^2.2.0", @@ -35,8 +36,7 @@ "tar": "^6.0.5", "tinylogic": "^2.0.0", "treeify": "^1.1.0", - "tslib": "^2.4.0", - "tunnel": "^0.0.6" + "tslib": "^2.4.0" }, "devDependencies": { "@octokit/webhooks-types": "^7.3.1", @@ -50,7 +50,6 @@ "@types/micromatch": "^4.0.1", "@types/node": "^18.17.15", "@types/tar": "^4.0.4", - "@types/tunnel": "^0.0.0", "@yarnpkg/cli": "workspace:^", "@yarnpkg/plugin-link": "workspace:^", "@yarnpkg/plugin-npm": "workspace:^", diff --git a/packages/yarnpkg-core/sources/httpUtils.ts b/packages/yarnpkg-core/sources/httpUtils.ts index abfe34a5b18d..c83815ac3f2c 100644 --- a/packages/yarnpkg-core/sources/httpUtils.ts +++ b/packages/yarnpkg-core/sources/httpUtils.ts @@ -1,19 +1,19 @@ -import {PortablePath, xfs} from '@yarnpkg/fslib'; -import type {ExtendOptions, RequestError} from 'got'; -import {Agent as HttpsAgent} from 'https'; -import {Agent as HttpAgent, IncomingHttpHeaders} from 'http'; -import micromatch from 'micromatch'; -import tunnel, {ProxyOptions} from 'tunnel'; - -import {ConfigurationValueMap, Configuration} from './Configuration'; -import {MessageName} from './MessageName'; -import {WrapNetworkRequestInfo} from './Plugin'; -import {ReportError} from './Report'; -import * as formatUtils from './formatUtils'; -import {MapValue, MapValueToObjectValue} from './miscUtils'; -import * as miscUtils from './miscUtils'; - -export type {RequestError} from 'got'; +import {PortablePath, xfs} from '@yarnpkg/fslib'; +import type {ExtendOptions, RequestError} from 'got'; +import {HttpProxyAgent, HttpsProxyAgent} from 'hpagent'; +import {Agent as HttpsAgent, type RequestOptions} from 'https'; +import {Agent as HttpAgent, IncomingHttpHeaders} from 'http'; +import micromatch from 'micromatch'; + +import {ConfigurationValueMap, Configuration} from './Configuration'; +import {MessageName} from './MessageName'; +import {WrapNetworkRequestInfo} from './Plugin'; +import {ReportError} from './Report'; +import * as formatUtils from './formatUtils'; +import {MapValue, MapValueToObjectValue} from './miscUtils'; +import * as miscUtils from './miscUtils'; + +export type {RequestError} from 'got'; const cache = new Map(); const fileCache = new Map | Buffer>(); @@ -21,19 +21,6 @@ const fileCache = new Map | Buffer>(); const globalHttpAgent = new HttpAgent({keepAlive: true}); const globalHttpsAgent = new HttpsAgent({keepAlive: true}); -function parseProxy(specifier: string) { - const url = new URL(specifier); - const proxy: ProxyOptions = {host: url.hostname, headers: {}}; - - if (url.port) - proxy.port = Number(url.port); - - if (url.username && url.password) - proxy.proxyAuth = `${url.username}:${url.password}`; - - return {proxy}; -} - async function getCachedFile(filePath: PortablePath) { return miscUtils.getFactoryWithDefault(fileCache, filePath, () => { return xfs.readFilePromise(filePath).then(file => { @@ -251,16 +238,7 @@ async function requestImpl(target: string | URL, body: Body, {configuration, hea if (url.protocol === `http:` && !micromatch.isMatch(url.hostname, configuration.get(`unsafeHttpWhitelist`))) throw new ReportError(MessageName.NETWORK_UNSAFE_HTTP, `Unsafe http requests must be explicitly whitelisted in your configuration (${url.hostname})`); - const agent = { - http: networkConfig.httpProxy - ? tunnel.httpOverHttp(parseProxy(networkConfig.httpProxy)) - : globalHttpAgent, - https: networkConfig.httpsProxy - ? tunnel.httpsOverHttp(parseProxy(networkConfig.httpsProxy)) as HttpsAgent - : globalHttpsAgent, - }; - - const gotOptions: ExtendOptions = {agent, headers, method}; + const gotOptions: ExtendOptions = {headers, method}; gotOptions.responseType = jsonResponse ? `json` : `buffer`; @@ -293,11 +271,37 @@ async function requestImpl(target: string | URL, body: Body, {configuration, hea ? await getCachedFile(httpsKeyFilePath) : undefined; + const proxyRequestOptions: RequestOptions = { + rejectUnauthorized, + ca: certificateAuthority, + cert: certificate, + key, + }; + + const agent = { + http: networkConfig.httpProxy + ? new HttpProxyAgent({ + proxy: networkConfig.httpProxy, + // @ts-expect-error: hpagent actually supports all RequestOptions, but the types don't reflect that + proxyRequestOptions, + }) + : globalHttpAgent, + https: networkConfig.httpsProxy + ? new HttpsProxyAgent({ + proxy: networkConfig.httpsProxy, + // @ts-expect-error: hpagent actually supports all RequestOptions, but the types don't reflect that + proxyRequestOptions, + }) + : globalHttpsAgent, + }; + + const gotClient = got.extend({ timeout: { socket: socketTimeout, }, retry, + agent, https: { rejectUnauthorized, certificateAuthority, diff --git a/yarn.lock b/yarn.lock index 459ace878a39..b8be6a5f9d4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5174,15 +5174,6 @@ __metadata: languageName: node linkType: hard -"@types/tunnel@npm:^0.0.0": - version: 0.0.0 - resolution: "@types/tunnel@npm:0.0.0" - dependencies: - "@types/node": "npm:*" - checksum: 10/bd3a79bd7be258cf709fb6bd83a0c3c43d83762a4f5faef3f3319ee04d2af5c00f798145dfd77a16ade46ce9aa5e755e7674cb43789516d304ff37d219beca32 - languageName: node - linkType: hard - "@types/unist@npm:*, @types/unist@npm:^3.0.0": version: 3.0.2 resolution: "@types/unist@npm:3.0.2" @@ -5646,7 +5637,6 @@ __metadata: "@types/semver": "npm:^7.1.0" "@types/tar": "npm:^4.0.4" "@types/treeify": "npm:^1.0.0" - "@types/tunnel": "npm:^0.0.0" "@yarnpkg/cli": "workspace:^" "@yarnpkg/fslib": "workspace:^" "@yarnpkg/libzip": "workspace:^" @@ -5666,6 +5656,7 @@ __metadata: esbuild: "npm:esbuild-wasm@^0.23.0" fast-glob: "npm:^3.2.2" got: "npm:^11.7.0" + hpagent: "npm:^1.2.0" lodash: "npm:^4.17.15" micromatch: "npm:^4.0.2" p-limit: "npm:^2.2.0" @@ -5678,7 +5669,6 @@ __metadata: tinylogic: "npm:^2.0.0" treeify: "npm:^1.1.0" tslib: "npm:^2.4.0" - tunnel: "npm:^0.0.6" languageName: unknown linkType: soft @@ -11949,6 +11939,13 @@ __metadata: languageName: node linkType: hard +"hpagent@npm:^1.2.0": + version: 1.2.0 + resolution: "hpagent@npm:1.2.0" + checksum: 10/bad186449da7e3456788a8cbae459fc6c0a855d5872a7f460c48ce4a613020d8d914839dad10047297099299c4f9e6c65a0eec3f5886af196c0a516e4ad8a845 + languageName: node + linkType: hard + "htm@npm:^3.0.0": version: 3.1.1 resolution: "htm@npm:3.1.1" @@ -20557,7 +20554,7 @@ pem@dexus/pem: languageName: node linkType: hard -"tunnel@npm:0.0.6, tunnel@npm:^0.0.6": +"tunnel@npm:0.0.6": version: 0.0.6 resolution: "tunnel@npm:0.0.6" checksum: 10/cf1ffed5e67159b901a924dbf94c989f20b2b3b65649cfbbe4b6abb35955ce2cf7433b23498bdb2c5530ab185b82190fce531597b3b4a649f06a907fc8702405