From 5ba41b196f0c95b5a1db913959b1ed14006f750e Mon Sep 17 00:00:00 2001 From: Clement Yan Date: Thu, 24 Apr 2025 20:12:34 +0800 Subject: [PATCH 1/5] feat(core): Replace tunnel with hpagent for proxying --- .pnp.cjs | 24 ++++++++---------- ...tunnel-npm-0.0.0-60b0691686-bd3a79bd7b.zip | Bin 2648 -> 0 bytes ...pagent-npm-1.2.0-0f725aa4fe-bad186449d.zip | Bin 0 -> 18207 bytes packages/yarnpkg-core/package.json | 5 ++-- packages/yarnpkg-core/sources/httpUtils.ts | 21 +++------------ yarn.lock | 21 +++++++-------- 6 files changed, 26 insertions(+), 45 deletions(-) delete mode 100644 .yarn/cache/@types-tunnel-npm-0.0.0-60b0691686-bd3a79bd7b.zip create mode 100644 .yarn/cache/hpagent-npm-1.2.0-0f725aa4fe-bad186449d.zip 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 a9650fd99fc03b6b269eca993136a8669a1cc41a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2648 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 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 => { @@ -253,10 +240,10 @@ async function requestImpl(target: string | URL, body: Body, {configuration, hea const agent = { http: networkConfig.httpProxy - ? tunnel.httpOverHttp(parseProxy(networkConfig.httpProxy)) + ? new HttpProxyAgent({proxy: networkConfig.httpProxy}) : globalHttpAgent, https: networkConfig.httpsProxy - ? tunnel.httpsOverHttp(parseProxy(networkConfig.httpsProxy)) as HttpsAgent + ? new HttpsProxyAgent({proxy: networkConfig.httpsProxy}) : globalHttpsAgent, }; 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 From 11cc4f62ab2ca2227ec5d7df92c3a79062a448c5 Mon Sep 17 00:00:00 2001 From: Clement Yan Date: Thu, 1 May 2025 18:30:20 +0800 Subject: [PATCH 2/5] feat(core): Use network config for HTTPS proxies --- packages/yarnpkg-core/sources/httpUtils.ts | 65 ++++++++++++++-------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/packages/yarnpkg-core/sources/httpUtils.ts b/packages/yarnpkg-core/sources/httpUtils.ts index ee4728fe5a75..c83815ac3f2c 100644 --- a/packages/yarnpkg-core/sources/httpUtils.ts +++ b/packages/yarnpkg-core/sources/httpUtils.ts @@ -1,17 +1,17 @@ -import {PortablePath, xfs} from '@yarnpkg/fslib'; -import type {ExtendOptions, RequestError} from 'got'; -import {HttpProxyAgent, HttpsProxyAgent} from 'hpagent'; -import {Agent as HttpsAgent} 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'; +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'; @@ -238,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 - ? new HttpProxyAgent({proxy: networkConfig.httpProxy}) - : globalHttpAgent, - https: networkConfig.httpsProxy - ? new HttpsProxyAgent({proxy: networkConfig.httpsProxy}) - : globalHttpsAgent, - }; - - const gotOptions: ExtendOptions = {agent, headers, method}; + const gotOptions: ExtendOptions = {headers, method}; gotOptions.responseType = jsonResponse ? `json` : `buffer`; @@ -280,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, From 4ba4a837d1f9cef2f54fd44cb5f30322b0933c38 Mon Sep 17 00:00:00 2001 From: Clement Yan Date: Thu, 1 May 2025 18:46:04 +0800 Subject: [PATCH 3/5] test: Add tests for proxy --- .../pkg-tests-core/sources/utils/tests.ts | 105 +++++++++ .../pkg-tests-specs/sources/proxy.test.ts | 221 ++++++++++++++++++ 2 files changed, 326 insertions(+) create mode 100644 packages/acceptance-tests/pkg-tests-specs/sources/proxy.test.ts 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`, + }); + }, + ), + ); +}); From f0aa2d0f8aed667bd5037bd9d08b69473776d86d Mon Sep 17 00:00:00 2001 From: Clement Yan Date: Thu, 1 May 2025 18:59:50 +0800 Subject: [PATCH 4/5] docs: Update docs for httpProxy and httpsProxy --- .../static/configuration/yarnrc.json | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) 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" }, From c1d85304ef4c9a627cacd8ebca7c48eea1df915b Mon Sep 17 00:00:00 2001 From: Clement Yan Date: Thu, 1 May 2025 19:15:08 +0800 Subject: [PATCH 5/5] versions --- .yarn/versions/562a0ff0.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .yarn/versions/562a0ff0.yml 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"