Skip to content

Commit c344b88

Browse files
authored
chore(deps): bump engine support matrix (#831)
BREAKING CHANGE: drop support for Node.js 20 and 25 BREAKING CHANGE: Switching to built-in proxy support, meaning that setting `NODE_USE_ENV_PROXY` in the env is now required.
2 parents 964d8cf + 9239990 commit c344b88

9 files changed

Lines changed: 471 additions & 1463 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ jobs:
4747
fail-fast: false
4848
matrix:
4949
node:
50-
- 20
5150
- 22
5251
- 24
52+
- 26
5353
platform:
5454
- ubuntu-latest
5555
- macos-latest

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ same major line. Should you need to upgrade to a new major, use an explicit
352352
empty password, explicitly set `COREPACK_NPM_PASSWORD` to an empty string.
353353

354354
- `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` are supported through
355-
[`proxy-from-env`](https://github.com/Rob--W/proxy-from-env).
355+
[`NODE_USE_ENV_PROXY=1`](https://nodejs.org/api/cli.html#node_use_env_proxy1).
356356

357357
- `COREPACK_INTEGRITY_KEYS` can be set to an empty string or `0` to
358358
instruct Corepack to skip integrity checks, or to a JSON string containing

package.json

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,39 @@
1010
"url": "https://github.com/nodejs/corepack.git"
1111
},
1212
"engines": {
13-
"node": "^20.10.0 || ^22.11.0 || >=24.0.0"
13+
"node": "^22.22.0 || ^24.15.0 || >=26.0.0"
1414
},
1515
"exports": {
1616
"./package.json": "./package.json"
1717
},
1818
"license": "MIT",
19-
"packageManager": "yarn@4.11.0+sha224.209a3e277c6bbc03df6e4206fbfcb0c1621c27ecf0688f79a0c619f0",
19+
"packageManager": "yarn@4.14.1+sha224.88b7a7244bbd9040380c417f7eb556d85c67640b651f113cb4c72113",
2020
"devDependencies": {
2121
"@types/debug": "^4.1.5",
22-
"@types/node": "^20.4.6",
22+
"@types/node": "^22.0.0",
2323
"@types/proxy-from-env": "^1",
2424
"@types/semver": "^7.1.0",
2525
"@types/which": "^3.0.0",
2626
"@yarnpkg/eslint-config": "^3.0.0",
2727
"@yarnpkg/fslib": "^3.0.0-rc.48",
2828
"@zkochan/cmd-shim": "^6.0.0",
29-
"better-sqlite3": "^11.7.2",
3029
"clipanion": "patch:clipanion@npm%3A3.2.1#~/.yarn/patches/clipanion-npm-3.2.1-fc9187f56c.patch",
3130
"debug": "^4.1.1",
3231
"esbuild": "^0.27.0",
3332
"eslint": "^9.22.0",
34-
"proxy-from-env": "^1.1.0",
3533
"semver": "^7.6.3",
3634
"supports-color": "^10.0.0",
3735
"tar": "^7.5.11",
3836
"tsx": "^4.16.2",
3937
"typescript": "^5.7.3",
40-
"undici": "^6.24.0",
4138
"v8-compile-cache": "^2.3.0",
4239
"vitest": "^3.0.5",
4340
"which": "^5.0.0"
4441
},
45-
"resolutions": {
46-
"undici-types": "6.x"
42+
"dependenciesMeta": {
43+
"esbuild": {
44+
"built": true
45+
}
4746
},
4847
"scripts": {
4948
"build": "run clean && run build:bundle && tsx ./mkshims.ts",

sources/corepackUtils.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ export async function runVersion(locator: Locator, installSpec: InstallSpec & {s
409409
if (!binPath)
410410
throw new Error(`Assertion failed: Unable to locate path for bin '${binName}'`);
411411

412-
// @ts-expect-error - Missing types
413412
if (!Module.enableCompileCache) {
414413
// Node.js segfaults when using npm@>=9.7.0 and v8-compile-cache
415414
// $ docker run -it node:20.3.0-slim corepack npm@9.7.1 --version
@@ -443,9 +442,7 @@ export async function runVersion(locator: Locator, installSpec: InstallSpec & {s
443442
// the stack trace of the package manager.
444443
process.nextTick(Module.runMain, binPath);
445444

446-
// @ts-expect-error - No types
447445
if (Module.flushCompileCache) {
448-
// @ts-expect-error - No types
449446
setImmediate(Module.flushCompileCache);
450447
}
451448
}

sources/httpUtils.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ async function fetch(input: string | URL, init?: RequestInit) {
1010
if (process.env.COREPACK_ENABLE_NETWORK === `0`)
1111
throw new UsageError(`Network access disabled by the environment; can't reach ${input}`);
1212

13-
const agent = await getProxyAgent(input);
14-
1513
if (typeof input === `string`)
1614
input = new URL(input);
1715

@@ -42,7 +40,6 @@ async function fetch(input: string | URL, init?: RequestInit) {
4240
try {
4341
response = await globalThis.fetch(input, {
4442
...init,
45-
dispatcher: agent,
4643
headers,
4744
});
4845
} catch (error) {
@@ -91,31 +88,3 @@ export async function fetchUrlStream(input: string | URL, init?: RequestInit) {
9188
const stream = Readable.fromWeb(webStream);
9289
return stream;
9390
}
94-
95-
let ProxyAgent: typeof import('undici').ProxyAgent;
96-
97-
async function getProxyAgent(input: string | URL) {
98-
const {getProxyForUrl} = await import(`proxy-from-env`);
99-
100-
// @ts-expect-error - The internal implementation is compatible with a WHATWG URL instance
101-
const proxy = getProxyForUrl(input);
102-
103-
if (!proxy) return undefined;
104-
105-
if (ProxyAgent == null) {
106-
// Doing a deep import here since undici isn't tree-shakeable
107-
const [api, Dispatcher, _ProxyAgent] = await Promise.all([
108-
// @ts-expect-error internal module is untyped
109-
import(`undici/lib/api/index.js`),
110-
// @ts-expect-error internal module is untyped
111-
import(`undici/lib/dispatcher/dispatcher.js`),
112-
// @ts-expect-error internal module is untyped
113-
import(`undici/lib/dispatcher/proxy-agent.js`),
114-
]);
115-
116-
Object.assign(Dispatcher.default.prototype, api.default);
117-
ProxyAgent = _ProxyAgent.default;
118-
}
119-
120-
return new ProxyAgent(proxy);
121-
}

tests/_registryServer.mjs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,8 @@ if (process.env.AUTH_TYPE === `PROXY`) {
186186
clientSocket.pipe(serverSocket);
187187
});
188188
});
189-
proxy.listen(0, `localhost`);
189+
proxy.listen(new URL(process.env.HTTP_PROXY).port, `localhost`);
190190
await once(proxy, `listening`);
191-
const {address, port} = proxy.address();
192-
process.env.ALL_PROXY = `http://${address.includes(`:`) ? `[${address}]` : address}:${port}`;
193191

194192
proxy.unref();
195193
}

tests/main.test.ts

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -682,10 +682,7 @@ describe(`when called on a project without any defined packageManager`, () => {
682682
});
683683
});
684684

685-
it(`should modify package.json if enabled by .corepack.env`, async t => {
686-
// Skip that test on Node.js 18.x as it lacks support for .env files.
687-
if (process.version.startsWith(`v18.`)) t.skip();
688-
685+
it(`should modify package.json if enabled by .corepack.env`, async () => {
689686
await xfs.mktempPromise(async cwd => {
690687
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
691688
// empty package.json file
@@ -1007,7 +1004,10 @@ it(`should support hydrating package managers if cache folder was removed`, asyn
10071004
});
10081005
});
10091006

1010-
it(`should support hydrating multiple package managers from cached archives`, async () => {
1007+
it(`should support hydrating multiple package managers from cached archives`, async t => {
1008+
// Skip that test on Windows as it times out
1009+
if (process.platform === `win32`) t.skip();
1010+
10111011
await xfs.mktempPromise(async cwd => {
10121012
await expect(runCli(cwd, [`pack`, `yarn@2.2.2`, `pnpm@5.8.0`])).resolves.toMatchObject({
10131013
exitCode: 0,
@@ -1343,10 +1343,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
13431343
});
13441344
});
13451345

1346-
it(`from .corepack.env file`, async t => {
1347-
// Skip that test on Node.js 18.x as it lacks support for .env files.
1348-
if (process.version.startsWith(`v18.`)) t.skip();
1349-
1346+
it(`from .corepack.env file`, async () => {
13501347
await xfs.mktempPromise(async cwd => {
13511348
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
13521349
});
@@ -1366,10 +1363,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
13661363
});
13671364
});
13681365

1369-
it(`from env file defined by COREPACK_ENV_FILE`, async t => {
1370-
// Skip that test on Node.js 18.x as it lacks support for .env files.
1371-
if (process.version.startsWith(`v18.`)) t.skip();
1372-
1366+
it(`from env file defined by COREPACK_ENV_FILE`, async () => {
13731367
await xfs.mktempPromise(async cwd => {
13741368
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
13751369
});
@@ -1416,10 +1410,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
14161410
});
14171411
});
14181412

1419-
it(`should ignore .corepack.env file if COREPACK_ENV_FILE is set to 0`, async t => {
1420-
// Skip that test on Node.js 18.x as it lacks support for .env files.
1421-
if (process.version.startsWith(`v18.`)) t.skip();
1422-
1413+
it(`should ignore .corepack.env file if COREPACK_ENV_FILE is set to 0`, async () => {
14231414
await xfs.mktempPromise(async cwd => {
14241415
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
14251416
});
@@ -1442,10 +1433,7 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
14421433
});
14431434
});
14441435

1445-
it(`from env file defined by COREPACK_ENV_FILE`, async t => {
1446-
// Skip that test on Node.js 18.x as it lacks support for .env files.
1447-
if (process.version.startsWith(`v18.`)) t.skip();
1448-
1436+
it(`from env file defined by COREPACK_ENV_FILE`, async () => {
14491437
process.env.COREPACK_ENV_FILE = `.other.env`;
14501438
await xfs.mktempPromise(async cwd => {
14511439
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
@@ -1470,6 +1458,10 @@ describe(`should pick up COREPACK_INTEGRITY_KEYS from env`, () => {
14701458
for (const authType of [`COREPACK_NPM_REGISTRY`, `COREPACK_NPM_TOKEN`, `COREPACK_NPM_PASSWORD`, `PROXY`]) {
14711459
describe(`custom registry with auth ${authType}`, () => {
14721460
beforeEach(() => {
1461+
if (authType === `PROXY`) {
1462+
process.env.HTTP_PROXY = `http://localhost:23456`; // Arbitrary port number that's hopefully free
1463+
process.env.NODE_USE_ENV_PROXY = `1`;
1464+
}
14731465
process.env.AUTH_TYPE = authType; // See `_registryServer.mjs`
14741466
process.env.COREPACK_INTEGRITY_KEYS = ``;
14751467
});

tests/recordRequests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use strict";
22
const path = require(`node:path`);
33
const crypto = require(`node:crypto`);
4-
const SQLite3 = require(`better-sqlite3`);
4+
const {DatabaseSync: SQLite3} = require(`node:sqlite`);
55

66
const db = new SQLite3(path.join(__dirname, `nocks.db`));
77
process.once(`exit`, () => {

0 commit comments

Comments
 (0)