Node.js v20.4.0 (Current)
Rafael Gonzaga
Notable Changes
Mock Timers
The new feature allows developers to write more reliable and predictable tests for time-dependent functionality.
It includes MockTimers
with the ability to mock setTimeout
, setInterval
from globals
, node:timers
, and node:timers/promises
.
The feature provides a simple API to advance time, enable specific timers, and release all timers.
import function assert(value: unknown, message?: string | Error): asserts value
An alias of
{@link
ok
}
.assert from 'node:assert';
import { function test(name?: string, fn?: test.TestFn): Promise<void> (+3 overloads)
The `test()` function is the value imported from the `test` module. Each
invocation of this function results in reporting the test to the `TestsStream`.
The `TestContext` object passed to the `fn` argument can be used to perform
actions related to the current test. Examples include skipping the test, adding
additional diagnostic information, or creating subtests.
`test()` returns a `Promise` that fulfills once the test completes.
if `test()` is called within a suite, it fulfills immediately.
The return value can usually be discarded for top level tests.
However, the return value from subtests should be used to prevent the parent
test from finishing first and cancelling the subtest
as shown in the following example.
```js
test('top level test', async (t) => {
// The setTimeout() in the following subtest would cause it to outlive its
// parent test if 'await' is removed on the next line. Once the parent test
// completes, it will cancel any outstanding subtests.
await t.test('longer running subtest', async (t) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
});
});
});
```
The `timeout` option can be used to fail the test if it takes longer than `timeout` milliseconds to complete. However, it is not a reliable mechanism for
canceling tests because a running test might block the application thread and
thus prevent the scheduled cancellation.test } from 'node:test';
function test(name?: string, fn?: test.TestFn): Promise<void> (+3 overloads)
The `test()` function is the value imported from the `test` module. Each
invocation of this function results in reporting the test to the `TestsStream`.
The `TestContext` object passed to the `fn` argument can be used to perform
actions related to the current test. Examples include skipping the test, adding
additional diagnostic information, or creating subtests.
`test()` returns a `Promise` that fulfills once the test completes.
if `test()` is called within a suite, it fulfills immediately.
The return value can usually be discarded for top level tests.
However, the return value from subtests should be used to prevent the parent
test from finishing first and cancelling the subtest
as shown in the following example.
```js
test('top level test', async (t) => {
// The setTimeout() in the following subtest would cause it to outlive its
// parent test if 'await' is removed on the next line. Once the parent test
// completes, it will cancel any outstanding subtests.
await t.test('longer running subtest', async (t) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
});
});
});
```
The `timeout` option can be used to fail the test if it takes longer than `timeout` milliseconds to complete. However, it is not a reliable mechanism for
canceling tests because a running test might block the application thread and
thus prevent the scheduled cancellation.test('mocks setTimeout to be executed synchronously without having to actually wait for it', context: test.TestContext
context => {
const const fn: test.Mock<(...args: any[]) => undefined>
fn = context: test.TestContext
context.test.TestContext.mock: test.MockTracker
Each test provides its own MockTracker instance.mock.test.MockTracker.fn<(...args: any[]) => undefined>(original?: ((...args: any[]) => undefined) | undefined, options?: test.MockFunctionOptions): test.Mock<(...args: any[]) => undefined> (+1 overload)
This function is used to create a mock function.
The following example creates a mock function that increments a counter by one
on each invocation. The `times` option is used to modify the mock behavior such
that the first two invocations add two to the counter instead of one.
```js
test('mocks a counting function', (t) => {
let cnt = 0;
function addOne() {
cnt++;
return cnt;
}
function addTwo() {
cnt += 2;
return cnt;
}
const fn = t.mock.fn(addOne, addTwo, { times: 2 });
assert.strictEqual(fn(), 2);
assert.strictEqual(fn(), 4);
assert.strictEqual(fn(), 5);
assert.strictEqual(fn(), 6);
});
```fn();
// Optionally choose what to mock
context: test.TestContext
context.test.TestContext.mock: test.MockTracker
Each test provides its own MockTracker instance.mock.test.MockTracker.timers: test.MockTimers
timers.test.MockTimers.enable(options?: test.MockTimersOptions): void
Enables timer mocking for the specified timers.
**Note:** When you enable mocking for a specific timer, its associated
clear function will also be implicitly mocked.
**Note:** Mocking `Date` will affect the behavior of the mocked timers
as they use the same internal clock.
Example usage without setting initial time:
```js
import { mock } from 'node:test';
mock.timers.enable({ apis: ['setInterval', 'Date'], now: 1234 });
```
The above example enables mocking for the `Date` constructor, `setInterval` timer and
implicitly mocks the `clearInterval` function. Only the `Date` constructor from `globalThis`,
`setInterval` and `clearInterval` functions from `node:timers`, `node:timers/promises`, and `globalThis` will be mocked.
Example usage with initial time set
```js
import { mock } from 'node:test';
mock.timers.enable({ apis: ['Date'], now: 1000 });
```
Example usage with initial Date object as time set
```js
import { mock } from 'node:test';
mock.timers.enable({ apis: ['Date'], now: new Date() });
```
Alternatively, if you call `mock.timers.enable()` without any parameters:
All timers (`'setInterval'`, `'clearInterval'`, `'Date'`, `'setImmediate'`, `'clearImmediate'`, `'setTimeout'`, and `'clearTimeout'`)
will be mocked.
The `setInterval`, `clearInterval`, `setTimeout`, and `clearTimeout` functions from `node:timers`, `node:timers/promises`,
and `globalThis` will be mocked.
The `Date` constructor from `globalThis` will be mocked.
If there is no initial epoch set, the initial date will be based on 0 in the Unix epoch. This is `January 1st, 1970, 00:00:00 UTC`. You can
set an initial date by passing a now property to the `.enable()` method. This value will be used as the initial date for the mocked Date
object. It can either be a positive integer, or another Date object.enable(['setTimeout']);
const const nineSecs: 9000
nineSecs = 9000;
function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+2 overloads)
Schedules execution of a one-time `callback` after `delay` milliseconds.
The `callback` will likely not be invoked in precisely `delay` milliseconds.
Node.js makes no guarantees about the exact timing of when callbacks will fire,
nor of their ordering. The callback will be called as close as possible to the
time specified.
When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
will be set to `1`. Non-integer delays are truncated to an integer.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setTimeout()`.setTimeout(const fn: test.Mock<(...args: any[]) => undefined>
fn, const nineSecs: 9000
nineSecs);
const const threeSeconds: 3000
threeSeconds = 3000;
context: test.TestContext
context.test.TestContext.mock: test.MockTracker
Each test provides its own MockTracker instance.mock.test.MockTracker.timers: test.MockTimers
timers.test.MockTimers.tick(milliseconds: number): void
Advances time for all mocked timers.
**Note:** This diverges from how `setTimeout` in Node.js behaves and accepts
only positive numbers. In Node.js, `setTimeout` with negative numbers is
only supported for web compatibility reasons.
The following example mocks a `setTimeout` function and
by using `.tick` advances in
time triggering all pending timers.
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout'] });
setTimeout(fn, 9999);
assert.strictEqual(fn.mock.callCount(), 0);
// Advance in time
context.mock.timers.tick(9999);
assert.strictEqual(fn.mock.callCount(), 1);
});
```
Alternativelly, the `.tick` function can be called many times
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout'] });
const nineSecs = 9000;
setTimeout(fn, nineSecs);
const twoSeconds = 3000;
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
assert.strictEqual(fn.mock.callCount(), 1);
});
```
Advancing time using `.tick` will also advance the time for any `Date` object
created after the mock was enabled (if `Date` was also set to be mocked).
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] });
setTimeout(fn, 9999);
assert.strictEqual(fn.mock.callCount(), 0);
assert.strictEqual(Date.now(), 0);
// Advance in time
context.mock.timers.tick(9999);
assert.strictEqual(fn.mock.callCount(), 1);
assert.strictEqual(Date.now(), 9999);
});
```tick(const threeSeconds: 3000
threeSeconds);
context: test.TestContext
context.test.TestContext.mock: test.MockTracker
Each test provides its own MockTracker instance.mock.test.MockTracker.timers: test.MockTimers
timers.test.MockTimers.tick(milliseconds: number): void
Advances time for all mocked timers.
**Note:** This diverges from how `setTimeout` in Node.js behaves and accepts
only positive numbers. In Node.js, `setTimeout` with negative numbers is
only supported for web compatibility reasons.
The following example mocks a `setTimeout` function and
by using `.tick` advances in
time triggering all pending timers.
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout'] });
setTimeout(fn, 9999);
assert.strictEqual(fn.mock.callCount(), 0);
// Advance in time
context.mock.timers.tick(9999);
assert.strictEqual(fn.mock.callCount(), 1);
});
```
Alternativelly, the `.tick` function can be called many times
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout'] });
const nineSecs = 9000;
setTimeout(fn, nineSecs);
const twoSeconds = 3000;
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
assert.strictEqual(fn.mock.callCount(), 1);
});
```
Advancing time using `.tick` will also advance the time for any `Date` object
created after the mock was enabled (if `Date` was also set to be mocked).
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] });
setTimeout(fn, 9999);
assert.strictEqual(fn.mock.callCount(), 0);
assert.strictEqual(Date.now(), 0);
// Advance in time
context.mock.timers.tick(9999);
assert.strictEqual(fn.mock.callCount(), 1);
assert.strictEqual(Date.now(), 9999);
});
```tick(const threeSeconds: 3000
threeSeconds);
context: test.TestContext
context.test.TestContext.mock: test.MockTracker
Each test provides its own MockTracker instance.mock.test.MockTracker.timers: test.MockTimers
timers.test.MockTimers.tick(milliseconds: number): void
Advances time for all mocked timers.
**Note:** This diverges from how `setTimeout` in Node.js behaves and accepts
only positive numbers. In Node.js, `setTimeout` with negative numbers is
only supported for web compatibility reasons.
The following example mocks a `setTimeout` function and
by using `.tick` advances in
time triggering all pending timers.
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout'] });
setTimeout(fn, 9999);
assert.strictEqual(fn.mock.callCount(), 0);
// Advance in time
context.mock.timers.tick(9999);
assert.strictEqual(fn.mock.callCount(), 1);
});
```
Alternativelly, the `.tick` function can be called many times
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout'] });
const nineSecs = 9000;
setTimeout(fn, nineSecs);
const twoSeconds = 3000;
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
context.mock.timers.tick(twoSeconds);
assert.strictEqual(fn.mock.callCount(), 1);
});
```
Advancing time using `.tick` will also advance the time for any `Date` object
created after the mock was enabled (if `Date` was also set to be mocked).
```js
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => {
const fn = context.mock.fn();
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] });
setTimeout(fn, 9999);
assert.strictEqual(fn.mock.callCount(), 0);
assert.strictEqual(Date.now(), 0);
// Advance in time
context.mock.timers.tick(9999);
assert.strictEqual(fn.mock.callCount(), 1);
assert.strictEqual(Date.now(), 9999);
});
```tick(const threeSeconds: 3000
threeSeconds);
function assert(value: unknown, message?: string | Error): asserts value
An alias of
{@link
ok
}
.assert.function assert.strictEqual<1>(actual: unknown, expected: 1, message?: string | Error): asserts actual is 1
Tests strict equality between the `actual` and `expected` parameters as
determined by [`Object.is()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
```js
import assert from 'node:assert/strict';
assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
//
// 1 !== 2
assert.strictEqual(1, 1);
// OK
assert.strictEqual('Hello foobar', 'Hello World!');
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
// + actual - expected
//
// + 'Hello foobar'
// - 'Hello World!'
// ^
const apples = 1;
const oranges = 2;
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identical
```
If the values are not strictly equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a
default error message is assigned. If the `message` parameter is an instance of an `Error` then it will be thrown
instead of the `AssertionError`.strictEqual(const fn: test.Mock<(...args: any[]) => undefined>
fn.mock: test.MockFunctionContext<(...args: any[]) => undefined>
mock.test.MockFunctionContext<(...args: any[]) => undefined>.callCount(): number
This function returns the number of times that this mock has been invoked. This
function is more efficient than checking `ctx.calls.length` because `ctx.calls` is a getter that creates a copy of the internal call tracking array.callCount(), 1);
});
This feature was contributed by Erick Wendel in #47775.
Support to the explicit resource management proposal
Node is adding support to the explicit resource management
proposal to its resources allowing users of TypeScript/babel to use using
/await using
with
V8 support for everyone else on the way.
This feature was contributed by Moshe Atlow and Benjamin Gruenbaum in #48518.
Other notable changes
- [
fe333d2584
] - crypto: update root certificates to NSS 3.90 (Node.js GitHub Bot) #48416 - [
60c2ea4e79
] - doc: add vmoroz to collaborators (Vladimir Morozov) #48527 - [
5cacdf9e6b
] - doc: add kvakil to collaborators (Keyhan Vakil) #48449 - [
504d1d7bdc
] - (SEMVER-MINOR) tls: add ALPNCallback server option for dynamic ALPN negotiation (Tim Perry) #45190
Commits
- [
8a611a387f
] - benchmark: add bar.R (Rafael Gonzaga) #47729 - [
12fa716cf9
] - benchmark: refactor crypto oneshot (Filip Skokan) #48267 - [
d6ecbde592
] - benchmark: add crypto.create*Key (Filip Skokan) #48284 - [
e60b6dedd8
] - bootstrap: unify snapshot builder and embedder entry points (Joyee Cheung) #48242 - [
40662957b1
] - bootstrap: simplify initialization of source map handlers (Joyee Cheung) #48304 - [
6551538079
] - build: fixconfigure --link-module
(Richard Lau) #48522 - [
f7f32089e7
] - build: sync libuv header change (Jiawen Geng) #48429 - [
f60205c915
] - build: update action to close stale PRs (Michael Dawson) #48196 - [
4f4d0b802e
] - child_process: improve spawn performance on Linux (Keyhan Vakil) #48523 - [
fe333d2584
] - crypto: update root certificates to NSS 3.90 (Node.js GitHub Bot) #48416 - [
89aaf16237
] - crypto: remove OPENSSL_FIPS guard for OpenSSL 3 (Richard Lau) #48392 - [
6199e1946c
] - deps: upgrade to libuv 1.46.0 (Santiago Gimeno) #48618 - [
1b2b930fda
] - deps: add loong64 config into openssl gypi (Shi Pujin) #48043 - [
ba8d048929
] - deps: update acorn to 8.9.0 (Node.js GitHub Bot) #48484 - [
d96f921d06
] - deps: update zlib to 1.2.13.1-motley-f81f385 (Node.js GitHub Bot) #48541 - [
ed1d047e8f
] - deps: update googletest to ec4fed9 (Node.js GitHub Bot) #48538 - [
f43d718c67
] - deps: update minimatch to 9.0.2 (Node.js GitHub Bot) #48542 - [
2f66147cbf
] - deps: update corepack to 0.19.0 (Node.js GitHub Bot) #48540 - [
d91b0fde73
] - deps: V8: cherry-pick 1a782f6543ae (Keyhan Vakil) #48523 - [
112335e342
] - deps: update corepack to 0.18.1 (Node.js GitHub Bot) #48483 - [
2b141c413f
] - deps: update icu to 73.2 (Node.js GitHub Bot) #48502 - [
188b34d4a1
] - deps: upgrade npm to 9.7.2 (npm team) #48514 - [
bf0444b5d9
] - deps: update zlib to 1.2.13.1-motley-3ca9f16 (Node.js GitHub Bot) #48413 - [
b339d80a56
] - deps: upgrade npm to 9.7.1 (npm team) #48378 - [
4132931b87
] - deps: update simdutf to 3.2.14 (Node.js GitHub Bot) #48344 - [
8cd56c1e85
] - deps: update ada to 2.5.1 (Node.js GitHub Bot) #48319 - [
78cffcd645
] - deps: update zlib to 982b036 (Node.js GitHub Bot) #48327 - [
6d00c2e33b
] - doc: fix options order (Luigi Pinca) #48617 - [
7ad2d3a5d1
] - doc: update security release stewards (Rafael Gonzaga) #48569 - [
cc3a056fdd
] - doc: update return type for describe (Shrujal Shah) #48572 - [
99ae0b98af
] - doc: run license-builder (github-actions[bot]) #48552 - [
9750d8205c
] - doc: add description of autoAllocateChunkSize in ReadableStream (Debadree Chatterjee) #48004 - [
417927bb41
] - doc: fixfilename
type inwatch
result (Dmitry Semigradsky) #48032 - [
ca2ae86bd7
] - doc: unnestmime
andMIMEParams
from MIMEType constructor (Dmitry Semigradsky) #47950 - [
bda1228135
] - doc: update security-release-process.md (Rafael Gonzaga) #48504 - [
60c2ea4e79
] - doc: add vmoroz to collaborators (Vladimir Morozov) #48527 - [
37bc0eac4a
] - doc: improve inspector.close() description (mary marchini) #48494 - [
2a403cdad5
] - doc: link to Runtime Keys in export conditions (Jacob Hummer) #48408 - [
e2d579e644
] - doc: update fs flags documentation (sinkhaha) #48463 - [
38bf290115
] - doc: reviseerror.md
introduction (Antoine du Hamel) #48423 - [
641a2e9c6d
] - doc: add preveen-stack to triagers (Preveen P) #48387 - [
4ab5e8d2e3
] - doc: refine when file is undefined in test events (Moshe Atlow) #48451 - [
5cacdf9e6b
] - doc: add kvakil to collaborators (Keyhan Vakil) #48449 - [
b9c643e3ef
] - doc: add additional info on TSFN dispatch (Michael Dawson) #48367 - [
17a0e1d1bf
] - doc: add link for news from security wg (Michael Dawson) #48396 - [
3a62994a4f
] - doc: fix typo in events.md (Darshan Sen) #48436 - [
e10a4cdf68
] - doc: run license-builder (github-actions[bot]) #48336 - [
19fde638fd
] - fs: call the callback with an error if writeSync fails (killa) #47949 - [
4cad9fd8bd
] - fs: remove unneeded return statement (Luigi Pinca) #48526 - [
d367b73f43
] - fs: use kResistStopPropagation (Chemi Atlow) #48521 - [
e50c3169af
] - fs, stream: initialSymbol.dispose
andSymbol.asyncDispose
support (Moshe Atlow) #48518 - [
7d8a0b6eb7
] - http: null the joinDuplicateHeaders property on cleanup (Luigi Pinca) #48608 - [
94ebb02f59
] - http: server add async dispose (atlowChemi) #48548 - [
c6a69e31a3
] - http: remove useless ternary in test (geekreal) #48481 - [
2f0f40328f
] - http: fix for handling on boot timers headers and request (Franciszek Koltuniuk) #48291 - [
5378ad8ab1
] - http2: server addasyncDispose
(atlowChemi) #48548 - [
97a58c5970
] - https: server addasyncDispose
(atlowChemi) #48548 - [
40ae6eb6aa
] - https: fix connection checking interval not clearing on server close (Nitzan Uziely) #48383 - [
15530fea4c
] - lib: merge cjs and esm package json reader caches (Yagiz Nizipli) #48477 - [
32bda81c31
] - lib: reduce url getters onmakeRequireFunction
(Yagiz Nizipli) #48492 - [
0da03f01ba
] - lib: remove duplicated requires in check_syntax (Yagiz Nizipli) #48508 - [
97b00c347d
] - lib: add option to force handling stopped events (Chemi Atlow) #48301 - [
fe16749649
] - lib: fix output message when repl is used with pm (Rafael Gonzaga) #48438 - [
8c2c02d28a
] - lib: create weakRef only if any signals provided (Chemi Atlow) #48448 - [
b6ae411ea9
] - lib: remove obsolete deletion of bufferBinding.zeroFill (Chengzhong Wu) #47881 - [
562b3d4856
] - lib: move web global bootstrapping to the expected file (Chengzhong Wu) #47881 - [
f9c0d5acac
] - lib: fix blob.stream() causing hanging promises (Debadree Chatterjee) #48232 - [
0162a0f5bf
] - lib: add support for inherited custom inspection methods (Antoine du Hamel) #48306 - [
159ab6627a
] - lib: reduce URL invocations on http2 origins (Yagiz Nizipli) #48338 - [
f0709fdc59
] - module: add SourceMap.findOrigin (Isaac Z. Schlueter) #47790 - [
4ec2d925b1
] - module: reduce url invocations in esm/load.js (Yagiz Nizipli) #48337 - [
2c363971cc
] - net: improve network family autoselection handle handling (Paolo Insogna) #48464 - [
dbf9e9ffc8
] - node-api: provide napi_define_properties fast path (Gabriel Schulhof) #48440 - [
87ad657777
] - node-api: implement external strings (Gabriel Schulhof) #48339 - [
4efa6807ea
] - permission: handle end nodes with children cases (Rafael Gonzaga) #48531 - [
84fe811108
] - repl: display dynamic import variant in static import error messages (Hemanth HM) #48129 - [
bdcc037470
] - report: disable js stack when no context is entered (Chengzhong Wu) #48495 - [
97bd9ccd04
] - src: fix uninitialized field access in AsyncHooks (Jan Olaf Krems) #48566 - [
404958fc96
] - src: fix Coverity issue regarding unnecessary copy (Yagiz Nizipli) #48565 - [
c4b8edea24
] - src: refactorSplitString
in util (Yagiz Nizipli) #48491 - [
5bc13a4772
] - src: revert IS_RELEASE (Rafael Gonzaga) #48505 - [
4971e46051
] - src: add V8 fast api toguessHandleType
(Yagiz Nizipli) #48349 - [
954e46e792
] - src: return uint32 forguessHandleType
(Yagiz Nizipli) #48349 - [
05009675da
] - src: make realm binding data store weak (Chengzhong Wu) #47688 - [
120ac74352
] - src: remove aliased buffer weak callback (Chengzhong Wu) #47688 - [
6591826e99
] - src: handle wasm out of bound in osx will raise SIGBUS correctly (Congcong Cai) #46561 - [
1b84ddeec2
] - src: implement constants binding directly (Joyee Cheung) #48186 - [
06d49c1f10
] - src: implement natives binding without special casing (Joyee Cheung) #48186 - [
325441abf5
] - src: add missing to_ascii method in dns queries (Daniel Lemire) #48354 - [
84d0eb74b8
] - stream: fix premature pipeline end (Robert Nagy) #48435 - [
3df7368735
] - test: add missing assertions to test-runner-cli (Moshe Atlow) #48593 - [
07eb310b0d
] - test: remove test-crypto-keygen flaky designation (Luigi Pinca) #48575 - [
75aa0a7682
] - test: remove test-timers-immediate-queue flaky designation (Luigi Pinca) #48575 - [
a9756f3126
] - test: add Symbol.dispose support to mock timers (Benjamin Gruenbaum) #48549 - [
0f912a7248
] - test: mark test-child-process-stdio-reuse-readable-stdio flaky (Luigi Pinca) #48537 - [
30f4bc4985
] - test: make IsolateData per-isolate in cctest (Joyee Cheung) #48450 - [
407ce3fdcb
] - test: define NAPI_VERSION before including node_api.h (Chengzhong Wu) #48376 - [
24a8fa95f0
] - test: remove unnecessary noop function args tomustNotCall()
(Antoine du Hamel) #48513 - [
09af579775
] - test: skip test-runner-watch-mode on IBMi (Moshe Atlow) #48473 - [
77cb1ee0b2
] - test: add missing <algorithm> include for std::find (Sam James) #48380 - [
7c790ca03c
] - test: fix flaky test-watch-mode (Moshe Atlow) #48147 - [
1398829746
] - test: fixtest-net-autoselectfamily
for kernel without IPv6 support (Livia Medeiros) #48265 - [
764119ba4b
] - test: update url web-platform tests (Yagiz Nizipli) #48319 - [
f1ead59629
] - test: ignore the copied entry_point.c (Luigi Pinca) #48297 - [
fc5d1bddcb
] - test: refactor test-gc-http-client-timeout (Luigi Pinca) #48292 - [
46a3d068a0
] - test: update encoding web-platform tests (Yagiz Nizipli) #48320 - [
141e5aad83
] - test: update FileAPI web-platform tests (Yagiz Nizipli) #48322 - [
83cfc67099
] - test: update user-timing web-platform tests (Yagiz Nizipli) #48321 - [
2c56835a33
] - test_runner: fixedtest
shorthands return type (Shocker) #48555 - [
7d01c8894a
] - (SEMVER-MINOR) test_runner: add initial draft for fakeTimers (Erick Wendel) #47775 - [
de4f14c249
] - test_runner: add enqueue and dequeue events (Moshe Atlow) #48428 - [
5ebe3a4ea7
] - test_runner: make--test-name-pattern
recursive (Moshe Atlow) #48382 - [
93bf447308
] - test_runner: refactor coverage report output for readability (Damien Seguin) #47791 - [
504d1d7bdc
] - (SEMVER-MINOR) tls: add ALPNCallback server option for dynamic ALPN negotiation (Tim Perry) #45190 - [
203c3cf4ca
] - tools: update lint-md-dependencies (Node.js GitHub Bot) #48544 - [
333907b19d
] - tools: speedup compilation of js2c output (Keyhan Vakil) #48160 - [
10bd5f4d97
] - tools: update lint-md-dependencies (Node.js GitHub Bot) #48486 - [
52de27b9fe
] - tools: pin ruff version number (Rich Trott) #48505 - [
4345526644
] - tools: replace sed with perl (Luigi Pinca) #48499 - [
6c590835f3
] - tools: automate update openssl v16 (Marco Ippolito) #48377 - [
90b5335338
] - tools: update eslint to 8.43.0 (Node.js GitHub Bot) #48487 - [
cd83530a11
] - tools: update doc to to-vfile@8.0.0 (Node.js GitHub Bot) #48485 - [
e500b439bd
] - tools: prepare tools/doc for to-vfile 8.0.0 (Rich Trott) #48485 - [
d623616813
] - tools: update lint-md-dependencies (Node.js GitHub Bot) #48417 - [
a2e107dde4
] - tools: update create-or-update-pull-request-action (Richard Lau) #48398 - [
8009e2c3be
] - tools: update eslint-plugin-jsdoc (Richard Lau) #48393 - [
10385c8565
] - tools: add version update to external dependencies (Andrea Fassina) #48081 - [
b1cef81b18
] - tools: update eslint to 8.42.0 (Node.js GitHub Bot) #48328 - [
0923dc0b8e
] - tools: disable jsdoc/no-defaults rule (Luigi Pinca) #48328 - [
b03146da85
] - typings: remove unused primordials (Yagiz Nizipli) #48509 - [
e9c9d187b9
] - typings: fix JSDoc in ESM loader modules (Antoine du Hamel) #48424 - [
fafe651d23
] - url: conform to origin getter spec changes (Yagiz Nizipli) #48319
Windows 32-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0-x86.msi
Windows 64-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0-x64.msi
Windows ARM 64-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0-arm64.msi
Windows 32-bit Binary: https://nodejs.org/dist/v20.4.0/win-x86/node.exe
Windows 64-bit Binary: https://nodejs.org/dist/v20.4.0/win-x64/node.exe
Windows ARM 64-bit Binary: https://nodejs.org/dist/v20.4.0/win-arm64/node.exe
macOS 64-bit Installer: https://nodejs.org/dist/v20.4.0/node-v20.4.0.pkg
macOS Apple Silicon 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-darwin-arm64.tar.gz
macOS Intel 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-darwin-x64.tar.gz
Linux 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-x64.tar.xz
Linux PPC LE 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-ppc64le.tar.xz
Linux s390x 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-s390x.tar.xz
AIX 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-aix-ppc64.tar.gz
ARMv7 32-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-armv7l.tar.xz
ARMv8 64-bit Binary: https://nodejs.org/dist/v20.4.0/node-v20.4.0-linux-arm64.tar.xz
Source Code: https://nodejs.org/dist/v20.4.0/node-v20.4.0.tar.gz
Other release files: https://nodejs.org/dist/v20.4.0/
Documentation: https://nodejs.org/docs/v20.4.0/api/
SHASUMS
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
d41a6396dbb29dbeab84d8bc8916bf9ddb6564793f2ac907868023e0ed53bb5a node-v20.4.0-aix-ppc64.tar.gz
aebab3e1a9a9e36cf42262f525440fa107f62f528681691c4640673e3b1d860e node-v20.4.0-arm64.msi
34f51397b6aad957b1a8eb70d13da5baf357ead124c1e429a7e939aa61266c06 node-v20.4.0-darwin-arm64.tar.gz
60b39a297eb673ef07c8fbc620be545269a3bb3f13d0aefa50185bde0b0b0eb1 node-v20.4.0-darwin-arm64.tar.xz
fe765474a8651b85cee04a64e8473089196b922a36621f464a985a5f4891a054 node-v20.4.0-darwin-x64.tar.gz
5587e6dc98f5ac64ae568468419092c937fa4dec3af91d2d8a18b2255769a88f node-v20.4.0-darwin-x64.tar.xz
7f917743676afae38f9027b2d8d8b85fbc0e213bf3dc7b0dc54de4d8a02f41d7 node-v20.4.0-headers.tar.gz
8a5f76a2fd6552f537461d1c2538a1a350b6b7ae38a1daa84fff74e3fab355e7 node-v20.4.0-headers.tar.xz
6ed340475a8bd5db5f04fe943b8fb89b7b2a8fd919f91217c6386dfa59865ba3 node-v20.4.0-linux-arm64.tar.gz
757f9c541f3e5da6e5ce06813d0ba206d4d013c008d7c59a7411512c1abfd0be node-v20.4.0-linux-arm64.tar.xz
9b7e8d9ecffcb9039cb3cc7d51181f1f8ae9072a738787e5bb5994a8f3f548c3 node-v20.4.0-linux-armv7l.tar.gz
29f9d67081c3a811b02786d2a9f9288c2a576ec2cb8f62acfe294a8d62f6b1b7 node-v20.4.0-linux-armv7l.tar.xz
71bef4eb631ccd0129f14066ed963613f59772b1f804ad99e06f4d25a5178cf0 node-v20.4.0-linux-ppc64le.tar.gz
d7ef827dd81536f8c52eca6e2688574bff53328754ccbcf23ec0a49f366be2cc node-v20.4.0-linux-ppc64le.tar.xz
0a60c9b6b9430a004a8dcbf31b59c41bd406ed7ed66fbf2537ffab58cb12d918 node-v20.4.0-linux-s390x.tar.gz
1a2fed46ad35821fb4a4e0a6ba0682a4cac76bd59c9bed271128da9b608933a8 node-v20.4.0-linux-s390x.tar.xz
2a9b03dd17fa6d9241b93e244d7e8f2524c4019fb5cfe3a99e59da1ee983cb9a node-v20.4.0-linux-x64.tar.gz
6b49a007f409fb7620350285cfc909fbc909604fd0ff5a87a1730365514b3712 node-v20.4.0-linux-x64.tar.xz
5b787126a671595ea0b4aa03dc9c6aaaccb2f4f1649c171afd1c3fe70bf3e1f9 node-v20.4.0.pkg
ee5a8b8fc18e57e1613480f4d87734190b9d3873b9c4696badf74bbc8310469d node-v20.4.0.tar.gz
09bd0b73c526b63c029d5ddfd885d10962e7ad87c975b94583c1f8ce90ee5348 node-v20.4.0.tar.xz
e5dc496965f5a5699d3c29ac8ee93574f051655d7c03201aba1419f7150087ad node-v20.4.0-win-arm64.7z
ee84dba7bc7bf25977cca5bf83bf8fcab8e46f36efd7ccbe54e3d62eebb42518 node-v20.4.0-win-arm64.zip
97bf0aecb90aa5907fa4a7afdf8dde0a08f4f37043525c22a79d5f0512dfa4c1 node-v20.4.0-win-x64.7z
91a51aaa9152db510704b4274cffd84c6e3572e1678e055e0d9c5cf7951ebc2a node-v20.4.0-win-x64.zip
61cf8648275341e5f144749d11779087d73aa9f58e059d08fce6edbb1217b49d node-v20.4.0-win-x86.7z
d5483af890061e3b068077fa46d31a6948e62c3fb6bceaa6d453537de79cd126 node-v20.4.0-win-x86.zip
3e3ccf5f9c32e52a4f8631dfdbe5cc44eee9d891d05fdd8d0b1359f00b7f9013 node-v20.4.0-x64.msi
3db2515d260fd2568e715896044f7e3d41dc8a4d0a10604c77466c160096f59a node-v20.4.0-x86.msi
691013e2f9687732ffbcfaaa5a59f6bad669266354f9da25088bc328ce5e70b1 win-arm64/node.exe
26977faa070f622c775ac338b51aae98a410b42e7eadeeecfc7f9893ead83d29 win-arm64/node.lib
13f10b8230ea61207589dcb075ab6706b1bf94b4c30e5b62cfbf62d34a047055 win-arm64/node_pdb.7z
aa91088403af0cf43d35272b9bd36e6a41effbbaef276c1e26cea0c04170de06 win-arm64/node_pdb.zip
8419696dafcdd2c8ab41a0e3cc3c731933f47beee3da8459d802ef53332b867c win-x64/node.exe
634e16fe60b1c7a043c53cea124af0b4122e3a8d6cbda5130f58593dfae3d50b win-x64/node.lib
f51c6b94dcb1c5f683255e89463b3bc909774a0d0f7d9117e68a688e535e3b4f win-x64/node_pdb.7z
c2bd95feceaeae6e10f081d5d1c7beb0e619b3a9ca920ec01b952e48442e51ef win-x64/node_pdb.zip
fc6d68673f6582c0ef04caad96ead0e40832e060fd89f483d442201c97a7e6ae win-x86/node.exe
200b17477721475de86ddabbdecd5970c59723b74890c19398fdc47013593af5 win-x86/node.lib
0b7d7c7666bb81b008257a5cda9e2d5ba25d4a5623d87b62963ba221c8b12036 win-x86/node_pdb.7z
3dc2a339c5535218b79e95bfb5759c5e36757001e1236953da86f40e20855fb3 win-x86/node_pdb.zip
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCAAdFiEEiQwI24V5Fi/uDfnbi+q0389VXvQFAmSldu8ACgkQi+q0389V
XvQrYQv9GJkxaG49BxIknAhkP05PF/H2HMqXy+jY9uJy9xAROsfBwKw8k+aMue7S
dF3xRZB3NIALZNptTDFoqu0GplcC0xUNPJr2/MAzVEX9neXEnzHtvfxd1bH/8wlz
sOUBB3degVeF/fcuWbbTA4Lq9MibAmVmm5YDXQjQpLC7jaWmuOqJvWz2qiqiP8d8
mLG+x7u36uGPXVkEFFwfjw8QabQ3FszQVM5vTbr1jdJsYUVd+k6ag9mOaRs0sB8O
CUC1ZYCXSf8CcTLziZLXB0GYMswR656LHJO7CrVgpRyi21SsF/z0f+XVjDdsrYtC
7yINviNo9Q1xBJYL5hrQYFxa8lg60ujOZIFwUfMu+S4ZSFROxHpS2x2vg93m8ON8
qbxWMx1H8dj7ubBOSOY3aXnC+WFDbt9TLu9CApvqZ27tsLjGhSi/mjNPqqT97Ek0
Bsf8o8BuAsWi3LOt11t5Mpn5H51GsLJ+9NvN5kMh0KgUgi/+qc5xeGbFUh8HaHU0
7sHCBsHg
=P4sp
-----END PGP SIGNATURE-----