From ec74b93b389026cfe200d2d4040bbfea7d631385 Mon Sep 17 00:00:00 2001 From: Dima Demakov Date: Mon, 27 Nov 2023 16:57:21 +0100 Subject: [PATCH 01/38] doc: remove flicker on page load on dark theme Theme applying logic get loaded and executed in async mode, so often there is a delay in applying the proper theme to a page which leads to flicker on dark theme. Resolved by moving critical logic to the page head PR-URL: https://github.com/nodejs/node/pull/50942 Reviewed-By: Moshe Atlow Reviewed-By: Claudio Wunder --- doc/api_assets/api.js | 6 ------ doc/template.html | 13 +++++++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/api_assets/api.js b/doc/api_assets/api.js index 8b40042f85cbae..394b5ba990946c 100644 --- a/doc/api_assets/api.js +++ b/doc/api_assets/api.js @@ -24,12 +24,6 @@ ); } } - - if (mq.matches) { - document.documentElement.classList.add('dark-mode'); - } - } else if (storedTheme === 'dark') { - document.documentElement.classList.add('dark-mode'); } if (themeToggleButton) { diff --git a/doc/template.html b/doc/template.html index fb334852aba434..658c8d94cd0723 100644 --- a/doc/template.html +++ b/doc/template.html @@ -10,6 +10,19 @@ + __JS_FLAVORED_DYNAMIC_CSS__ From c1ee506454548c618bd10db308f44525053d8b23 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Mon, 27 Nov 2023 14:29:46 -0500 Subject: [PATCH 02/38] fs: remove workaround for `esm` package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50907 Reviewed-By: Robert Nagy Reviewed-By: Luigi Pinca Reviewed-By: Moshe Atlow Reviewed-By: Vinícius Lourenço Claro Cardoso --- lib/internal/fs/utils.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 9f5ad9bf5f6c0e..6e2ae69555130d 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -497,10 +497,6 @@ function Stats(dev, mode, nlink, uid, gid, rdev, blksize, ObjectSetPrototypeOf(Stats.prototype, StatsBase.prototype); ObjectSetPrototypeOf(Stats, StatsBase); -// HACK: Workaround for https://github.com/standard-things/esm/issues/821. -// TODO(ronag): Remove this as soon as `esm` publishes a fixed version. -Stats.prototype.isFile = StatsBase.prototype.isFile; - Stats.prototype._checkModeProperty = function(property) { if (isWindows && (property === S_IFIFO || property === S_IFBLK || property === S_IFSOCK)) { From eecab883f088e212d628b4eca648e35e98df2722 Mon Sep 17 00:00:00 2001 From: theanarkh Date: Tue, 28 Nov 2023 11:57:50 +0800 Subject: [PATCH 03/38] doc: add doc for Unix abstract socket PR-URL: https://github.com/nodejs/node/pull/50904 Refs: https://github.com/nodejs/node/pull/49667 Reviewed-By: Luigi Pinca Reviewed-By: Paolo Insogna --- doc/api/net.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/api/net.md b/doc/api/net.md index 23f2096049b0e0..fc260b9f636266 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -38,7 +38,10 @@ it will unlink the Unix domain socket as well. For example, socket outside of these abstractions, the user will need to remove it. The same applies when a Node.js API creates a Unix domain socket but the program then crashes. In short, a Unix domain socket will be visible in the file system and -will persist until unlinked. +will persist until unlinked. On Linux, You can use Unix abstract socket by adding +`\0` to the beginning of the path, such as `\0abstract`. The path to the Unix +abstract socket is not visible in the file system and it will disappear automatically +when all open references to the socket are closed. On Windows, the local domain is implemented using a named pipe. The path _must_ refer to an entry in `\\?\pipe\` or `\\.\pipe\`. Any characters are permitted, From 94462d42f501df60c9ac4243b37d39ddc3ca92ad Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 28 Nov 2023 18:18:02 +0100 Subject: [PATCH 04/38] test: consolidate utf8 text fixtures in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We previously used a text that appears to be an excerpt of https://zh.wikipedia.org/wiki/%E5%8D%97%E8%B6%8A%E5%9B%BD and can have copyright/license complications. It may also include some geopolitical nuances. The text has been repeated through out the code base without much reuse. This patch consolidates the fixtures by adding a common helper string as `fixtures.utf8TestText` which is identical to a copy in test/fixtures/utf8_test_text.txt. It also updates the text to a copy of 蘭亭集序, It was chosen because: 1. It's a well-known Chinese classical piece written in 353 CE and therefore in public domain. The string is copied from https://zh.wikisource.org/zh-hant/%E8%98%AD%E4%BA%AD%E9%9B%86%E5%BA%8F which contains a disclaimer of copyright for this reason. 2. The text is in suitable length for general UTF8 string read/write tests (including punctuations, 389 code points and 1167 bytes). 3. This is also commonly used as reference text for Chinese text layout tests. 4. It's a timeless and harmless preface for a collection of poems, written by a uncontroversial figure who passed away >1600 years ago and contains no geopolitical nuances. Background and an English translation of this text can be found at https://en.wikipedia.org/wiki/Lantingji_Xu PR-URL: https://github.com/nodejs/node/pull/50732 Reviewed-By: Yagiz Nizipli --- test/common/fixtures.js | 21 +++++++++++++++++++ test/fixtures/utf8_test_text.txt | 1 + test/parallel/test-fs-append-file-sync.js | 11 +++------- test/parallel/test-fs-append-file.js | 10 ++------- .../test-fs-write-file-typedarrays.js | 10 ++------- test/parallel/test-fs-write-file.js | 10 ++------- test/parallel/test-http-chunked.js | 12 ++--------- test/parallel/test-stdin-from-file.js | 14 +------------ 8 files changed, 34 insertions(+), 55 deletions(-) create mode 100644 test/fixtures/utf8_test_text.txt diff --git a/test/common/fixtures.js b/test/common/fixtures.js index 3ee87e8b2d7b59..75815b035ba186 100644 --- a/test/common/fixtures.js +++ b/test/common/fixtures.js @@ -28,6 +28,23 @@ function readFixtureKeys(enc, ...names) { return names.map((name) => readFixtureKey(name, enc)); } +// This should be in sync with test/fixtures/utf8_test_text.txt. +// We copy them here as a string because this is supposed to be used +// in fs API tests. +const utf8TestText = '永和九年,嵗在癸丑,暮春之初,會於會稽山隂之蘭亭,脩稧事也。' + + '羣賢畢至,少長咸集。此地有崇山峻領,茂林脩竹;又有清流激湍,' + + '暎帶左右。引以為流觴曲水,列坐其次。雖無絲竹管弦之盛,一觴一詠,' + + '亦足以暢敘幽情。是日也,天朗氣清,恵風和暢;仰觀宇宙之大,' + + '俯察品類之盛;所以遊目騁懐,足以極視聽之娛,信可樂也。夫人之相與,' + + '俯仰一世,或取諸懐抱,悟言一室之內,或因寄所託,放浪形骸之外。' + + '雖趣舎萬殊,靜躁不同,當其欣扵所遇,暫得扵己,怏然自足,' + + '不知老之將至。及其所之既惓,情隨事遷,感慨係之矣。向之所欣,' + + '俛仰之閒以為陳跡,猶不能不以之興懐;況脩短隨化,終期扵盡。' + + '古人云:「死生亦大矣。」豈不痛哉!每攬昔人興感之由,若合一契,' + + '未嘗不臨文嗟悼,不能喻之扵懐。固知一死生為虛誕,齊彭殤為妄作。' + + '後之視今,亦由今之視昔,悲夫!故列敘時人,錄其所述,雖世殊事異,' + + '所以興懐,其致一也。後之攬者,亦將有感扵斯文。'; + module.exports = { fixturesDir, path: fixturesPath, @@ -35,4 +52,8 @@ module.exports = { readSync: readFixtureSync, readKey: readFixtureKey, readKeys: readFixtureKeys, + utf8TestText, + get utf8TestTextPath() { + return fixturesPath('utf8_test_text.txt'); + }, }; diff --git a/test/fixtures/utf8_test_text.txt b/test/fixtures/utf8_test_text.txt new file mode 100644 index 00000000000000..f4b6fc9bcfcb5e --- /dev/null +++ b/test/fixtures/utf8_test_text.txt @@ -0,0 +1 @@ +永和九年,嵗在癸丑,暮春之初,會於會稽山隂之蘭亭,脩稧事也。羣賢畢至,少長咸集。此地有崇山峻領,茂林脩竹;又有清流激湍,暎帶左右。引以為流觴曲水,列坐其次。雖無絲竹管弦之盛,一觴一詠,亦足以暢敘幽情。是日也,天朗氣清,恵風和暢;仰觀宇宙之大,俯察品類之盛;所以遊目騁懐,足以極視聽之娛,信可樂也。夫人之相與,俯仰一世,或取諸懐抱,悟言一室之內,或因寄所託,放浪形骸之外。雖趣舎萬殊,靜躁不同,當其欣扵所遇,暫得扵己,怏然自足,不知老之將至。及其所之既惓,情隨事遷,感慨係之矣。向之所欣,俛仰之閒以為陳跡,猶不能不以之興懐;況脩短隨化,終期扵盡。古人云:「死生亦大矣。」豈不痛哉!每攬昔人興感之由,若合一契,未嘗不臨文嗟悼,不能喻之扵懐。固知一死生為虛誕,齊彭殤為妄作。後之視今,亦由今之視昔,悲夫!故列敘時人,錄其所述,雖世殊事異,所以興懐,其致一也。後之攬者,亦將有感扵斯文。 \ No newline at end of file diff --git a/test/parallel/test-fs-append-file-sync.js b/test/parallel/test-fs-append-file-sync.js index fd6ee690f4ab7d..f32b4585354561 100644 --- a/test/parallel/test-fs-append-file-sync.js +++ b/test/parallel/test-fs-append-file-sync.js @@ -27,15 +27,10 @@ const fs = require('fs'); const currentFileData = 'ABCD'; const m = 0o600; const num = 220; -const data = '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,疆域包括今天中国的广东、' + - '广西两省区的大部份地区,福建省、湖南、贵州、云南的一小部份地区和越南的北部。' + - '南越国是秦朝灭亡后,由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。' + - '前196年和前179年,南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + - '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + - '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + - '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; - const tmpdir = require('../common/tmpdir'); +const fixtures = require('../common/fixtures'); +const data = fixtures.utf8TestText; + tmpdir.refresh(); // Test that empty file will be created and have content added. diff --git a/test/parallel/test-fs-append-file.js b/test/parallel/test-fs-append-file.js index 2151b5cedd1c9a..1e20625e5b9697 100644 --- a/test/parallel/test-fs-append-file.js +++ b/test/parallel/test-fs-append-file.js @@ -27,14 +27,8 @@ const fs = require('fs'); const tmpdir = require('../common/tmpdir'); const currentFileData = 'ABCD'; - -const s = '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,疆域包括今天中国的广东、' + - '广西两省区的大部份地区,福建省、湖南、贵州、云南的一小部份地区和越南的北部。' + - '南越国是秦朝灭亡后,由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。' + - '前196年和前179年,南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + - '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + - '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + - '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; +const fixtures = require('../common/fixtures'); +const s = fixtures.utf8TestText; tmpdir.refresh(); diff --git a/test/parallel/test-fs-write-file-typedarrays.js b/test/parallel/test-fs-write-file-typedarrays.js index e398579f123ab1..a05385048ad48f 100644 --- a/test/parallel/test-fs-write-file-typedarrays.js +++ b/test/parallel/test-fs-write-file-typedarrays.js @@ -7,14 +7,8 @@ const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); const filename = tmpdir.resolve('test.txt'); - -const s = '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,疆域包括今天中国的广东、' + - '广西两省区的大部份地区,福建省、湖南、贵州、云南的一小部份地区和越南的北部。' + - '南越国是秦朝灭亡后,由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。' + - '前196年和前179年,南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + - '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + - '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + - '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; +const fixtures = require('../common/fixtures'); +const s = fixtures.utf8TestText; // The length of the buffer should be a multiple of 8 // as required by common.getArrayBufferViews() diff --git a/test/parallel/test-fs-write-file.js b/test/parallel/test-fs-write-file.js index 404caa4636de04..120b9ec9ef6c1c 100644 --- a/test/parallel/test-fs-write-file.js +++ b/test/parallel/test-fs-write-file.js @@ -28,14 +28,8 @@ const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); const filename = tmpdir.resolve('test.txt'); - -const s = '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,疆域包括今天中国的广东、' + - '广西两省区的大部份地区,福建省、湖南、贵州、云南的一小部份地区和越南的北部。' + - '南越国是秦朝灭亡后,由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。' + - '前196年和前179年,南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + - '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + - '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + - '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; +const fixtures = require('../common/fixtures'); +const s = fixtures.utf8TestText; fs.writeFile(filename, s, common.mustSucceed(() => { fs.readFile(filename, common.mustSucceed((buffer) => { diff --git a/test/parallel/test-http-chunked.js b/test/parallel/test-http-chunked.js index 264a87be6adc7f..cfa34e3afedb74 100644 --- a/test/parallel/test-http-chunked.js +++ b/test/parallel/test-http-chunked.js @@ -23,16 +23,8 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); - -const UTF8_STRING = '南越国是前203年至前111年存在于岭南地区的一个国家,' + - '国都位于番禺,疆域包括今天中国的广东、广西两省区的大部份地区,福建省、湖南、' + - '贵州、云南的一小部份地区和越南的北部。南越国是秦朝灭亡后,' + - '由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。前196年和前179年,' + - '南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + - '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。' + - '南越国共存在93年,历经五代君主。南越国是岭南地区的第一个有记载的政权国家,' + - '采用封建制和郡县制并存的制度,它的建立保证了秦末乱世岭南地区社会秩序的稳定,' + - '有效的改善了岭南地区落后的政治、经济现状。'; +const fixtures = require('../common/fixtures'); +const UTF8_STRING = fixtures.utf8TestText; const server = http.createServer(common.mustCall((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf8' }); diff --git a/test/parallel/test-stdin-from-file.js b/test/parallel/test-stdin-from-file.js index 7c263d1858a556..67404c84c9830b 100644 --- a/test/parallel/test-stdin-from-file.js +++ b/test/parallel/test-stdin-from-file.js @@ -8,22 +8,10 @@ const fs = require('fs'); const stdoutScript = fixtures.path('echo-close-check.js'); const tmpFile = tmpdir.resolve('stdin.txt'); +const string = fixtures.utf8TestText; const cmd = `"${process.argv[0]}" "${stdoutScript}" < "${tmpFile}"`; -const string = 'abc\nümlaut.\nsomething else\n' + - '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,' + - '疆域包括今天中国的广东、广西两省区的大部份地区,福建省、湖南、贵州、' + - '云南的一小部份地区和越南的北部。南越国是秦朝灭亡后,' + - '由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。前196年和前179年,' + - '南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + - '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + - '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,' + - '采用封建制和郡县制并存的制度,' + - '它的建立保证了秦末乱世岭南地区社会秩序的稳定,' + - '有效的改善了岭南地区落后的政治、##济现状。\n'; - - tmpdir.refresh(); console.log(`${cmd}\n\n`); From 30a6f19769c479736d64770aa2bedd6298f22a6a Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 28 Nov 2023 22:34:40 +0100 Subject: [PATCH 05/38] doc: document non-node_modules-only runtime deprecation We already have this special kind of runtime deprecation for Buffer constructors which does not fit into the original description of runtiem deprecations. Document this kind of deprecation separately. PR-URL: https://github.com/nodejs/node/pull/50748 Reviewed-By: Geoffrey Booth Reviewed-By: Matteo Collina Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Benjamin Gruenbaum --- doc/api/deprecations.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 42b1e2741d1ac9..4168b88ef8b678 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -10,10 +10,11 @@ Node.js APIs might be deprecated for any of the following reasons: * An improved alternative API is available. * Breaking changes to the API are expected in a future major release. -Node.js uses three kinds of Deprecations: +Node.js uses four kinds of deprecations: * Documentation-only -* Runtime +* Application (non-`node_modules` code only) +* Runtime (all code) * End-of-Life A Documentation-only deprecation is one that is expressed only within the @@ -25,10 +26,17 @@ deprecations below. Documentation-only deprecations that support that flag are explicitly labeled as such in the [list of Deprecated APIs](#list-of-deprecated-apis). -A Runtime deprecation will, by default, generate a process warning that will -be printed to `stderr` the first time the deprecated API is used. When the -[`--throw-deprecation`][] command-line flag is used, a Runtime deprecation will -cause an error to be thrown. +An Application deprecation for only non-`node_modules` code will, by default, +generate a process warning that will be printed to `stderr` the first time +the deprecated API is used in code that's not loaded from `node_modules`. +When the [`--throw-deprecation`][] command-line flag is used, a Runtime +deprecation will cause an error to be thrown. When +[`--pending-deprecation`][] is used, warnings will also be emitted for +code loaded from `node_modules`. + +A runtime deprecation for all code is similar to the runtime deprecation +for non-`node_modules` code, except that it also emits a warning for +code loaded from `node_modules`. An End-of-Life deprecation is used when functionality is or will soon be removed from Node.js. @@ -140,7 +148,7 @@ changes: description: Documentation-only deprecation. --> -Type: Runtime (supports [`--pending-deprecation`][]) +Type: Application (non-`node_modules` code only) The `Buffer()` function and `new Buffer()` constructor are deprecated due to API usability issues that can lead to accidental security issues. From c37d18d5e1108b84c3f4048319eb082d02311051 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 17 Nov 2023 19:16:55 +0100 Subject: [PATCH 06/38] lib: streamline process.binding() handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Make processBindingAllowList a separate list from runtimeDeprecatedList and legacyWrapperList instead of being an umbrella one, so it's easier to see the stages the bindings are in. - Cache process.binding() results so we don't need to mutate runtimeDeprecatedList. PR-URL: https://github.com/nodejs/node/pull/50773 Reviewed-By: Vinícius Lourenço Claro Cardoso Reviewed-By: James M Snell --- lib/internal/bootstrap/realm.js | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/lib/internal/bootstrap/realm.js b/lib/internal/bootstrap/realm.js index 6034af9a36003c..93a939cc7e4645 100644 --- a/lib/internal/bootstrap/realm.js +++ b/lib/internal/bootstrap/realm.js @@ -87,34 +87,26 @@ ObjectDefineProperty(process, 'moduleLoadList', { // more, we just implement them as legacy wrappers instead. See the // legacyWrapperList. const processBindingAllowList = new SafeSet([ - 'async_wrap', 'buffer', 'cares_wrap', 'config', 'constants', 'contextify', - 'crypto', 'fs', 'fs_event_wrap', - 'http_parser', 'icu', 'inspector', 'js_stream', - 'natives', 'os', 'pipe_wrap', 'process_wrap', - 'signal_wrap', 'spawn_sync', 'stream_wrap', 'tcp_wrap', 'tls_wrap', 'tty_wrap', 'udp_wrap', - 'url', - 'util', 'uv', - 'v8', 'zlib', ]); @@ -148,19 +140,23 @@ const experimentalModuleList = new SafeSet(); process.binding = function binding(module) { module = String(module); + const mod = bindingObj[module]; + if (typeof mod === 'object') { + return mod; + } // Deprecated specific process.binding() modules, but not all, allow // selective fallback to internalBinding for the deprecated ones. + if (runtimeDeprecatedList.has(module)) { + process.emitWarning( + `Access to process.binding('${module}') is deprecated.`, + 'DeprecationWarning', + 'DEP0111'); + return internalBinding(module); + } + if (legacyWrapperList.has(module)) { + return requireBuiltin('internal/legacy/processbinding')[module](); + } if (processBindingAllowList.has(module)) { - if (runtimeDeprecatedList.has(module)) { - runtimeDeprecatedList.delete(module); - process.emitWarning( - `Access to process.binding('${module}') is deprecated.`, - 'DeprecationWarning', - 'DEP0111'); - } - if (legacyWrapperList.has(module)) { - return requireBuiltin('internal/legacy/processbinding')[module](); - } return internalBinding(module); } // eslint-disable-next-line no-restricted-syntax From 1e40c4a3665dd34f357db84226387d7b0a504eab Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Tue, 28 Nov 2023 23:39:29 +0100 Subject: [PATCH 07/38] tools: fix current version check PR-URL: https://github.com/nodejs/node/pull/50951 Reviewed-By: Moshe Atlow Reviewed-By: Antoine du Hamel Reviewed-By: Michael Dawson Reviewed-By: Luigi Pinca --- tools/dep_updaters/update-acorn-walk.sh | 2 +- tools/dep_updaters/update-acorn.sh | 2 +- tools/dep_updaters/update-minimatch.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/dep_updaters/update-acorn-walk.sh b/tools/dep_updaters/update-acorn-walk.sh index 844380305d0fe3..9967d63f0c6e2c 100755 --- a/tools/dep_updaters/update-acorn-walk.sh +++ b/tools/dep_updaters/update-acorn-walk.sh @@ -17,7 +17,7 @@ DEPS_DIR="$BASE_DIR/deps" . "$BASE_DIR/tools/dep_updaters/utils.sh" NEW_VERSION=$("$NODE" "$NPM" view acorn-walk dist-tags.latest) -CURRENT_VERSION=$("$NODE" "$NPM" --prefix './deps/acorn/acorn-walk/' pkg get version) +CURRENT_VERSION=$("$NODE" -p "require('./deps/acorn/acorn-walk/package.json').version") # This function exit with 0 if new version and current version are the same compare_dependency_version "acorn-walk" "$NEW_VERSION" "$CURRENT_VERSION" diff --git a/tools/dep_updaters/update-acorn.sh b/tools/dep_updaters/update-acorn.sh index 6c0f54a5447100..52c6974505beb0 100755 --- a/tools/dep_updaters/update-acorn.sh +++ b/tools/dep_updaters/update-acorn.sh @@ -17,7 +17,7 @@ DEPS_DIR="$BASE_DIR/deps" . "$BASE_DIR/tools/dep_updaters/utils.sh" NEW_VERSION=$("$NODE" "$NPM" view acorn dist-tags.latest) -CURRENT_VERSION=$("$NODE" "$NPM" --prefix './deps/acorn/acorn/' pkg get version) +CURRENT_VERSION=$("$NODE" -p "require('./deps/acorn/acorn/package.json').version") # This function exit with 0 if new version and current version are the same compare_dependency_version "acorn" "$NEW_VERSION" "$CURRENT_VERSION" diff --git a/tools/dep_updaters/update-minimatch.sh b/tools/dep_updaters/update-minimatch.sh index 6be6bdc44a7f52..2e6fdd0c11890b 100755 --- a/tools/dep_updaters/update-minimatch.sh +++ b/tools/dep_updaters/update-minimatch.sh @@ -17,7 +17,7 @@ NPM="$DEPS_DIR/npm/bin/npm-cli.js" . "$BASE_DIR/tools/dep_updaters/utils.sh" NEW_VERSION=$("$NODE" "$NPM" view minimatch dist-tags.latest) -CURRENT_VERSION=$("$NODE" "$NPM" --prefix './deps/minimatch' pkg get version) +CURRENT_VERSION=$("$NODE" -p "require('./deps/minimatch/package.json').version") # This function exit with 0 if new version and current version are the same compare_dependency_version "minimatch" "$NEW_VERSION" "$CURRENT_VERSION" From 74f5a1cbc978f94aa844c9879bda0a01bdc90e8f Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 16 Nov 2023 23:25:35 +0100 Subject: [PATCH 08/38] src: print MKSNAPSHOT debug logs to stderr PR-URL: https://github.com/nodejs/node/pull/50759 Refs: https://github.com/nodejs/node/issues/50740 Reviewed-By: Yagiz Nizipli Reviewed-By: James M Snell Reviewed-By: Darshan Sen --- src/node_realm.cc | 2 +- src/node_snapshotable.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_realm.cc b/src/node_realm.cc index 23fb6bd55213ee..6262ed8cde59f2 100644 --- a/src/node_realm.cc +++ b/src/node_realm.cc @@ -223,7 +223,7 @@ void Realm::PrintInfoForSnapshot() { fprintf(stderr, "BaseObjects of the Realm:\n"); size_t i = 0; ForEachBaseObject([&](BaseObject* obj) { - std::cout << "#" << i++ << " " << obj << ": " << obj->MemoryInfoName() + std::cerr << "#" << i++ << " " << obj << ": " << obj->MemoryInfoName() << "\n"; }); diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index 562a47ddcc9c8e..0a9c5db2af5075 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -1074,7 +1074,7 @@ ExitCode SnapshotBuilder::CreateSnapshot(SnapshotData* out, if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) { env->ForEachRealm([](Realm* realm) { realm->PrintInfoForSnapshot(); }); - printf("Environment = %p\n", env); + fprintf(stderr, "Environment = %p\n", env); } // Serialize the native states From ac3a6eefe36a7d4f5bfec5a58dfd3835445268ea Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 16 Nov 2023 18:26:45 +0100 Subject: [PATCH 09/38] test: log more information in SEA tests - Use spawnSyncAndExitWithoutError to log more information on error. - Use NODE_DEBUG_NATIVE to log internals - Skip the test when available disk space < 120MB PR-URL: https://github.com/nodejs/node/pull/50759 Refs: https://github.com/nodejs/node/issues/50740 Reviewed-By: Yagiz Nizipli Reviewed-By: James M Snell Reviewed-By: Darshan Sen --- test/common/sea.js | 9 ++++++ ...cation-disable-experimental-sea-warning.js | 25 +++++++++++----- ...est-single-executable-application-empty.js | 19 ++++++++---- ...ble-application-snapshot-and-code-cache.js | 21 +++++++++---- ...-single-executable-application-snapshot.js | 12 +++++++- ...e-executable-application-use-code-cache.js | 30 ++++++++++++++----- .../test-single-executable-application.js | 25 +++++++++++----- 7 files changed, 106 insertions(+), 35 deletions(-) diff --git a/test/common/sea.js b/test/common/sea.js index cc1890a5464012..d57c9e4238d867 100644 --- a/test/common/sea.js +++ b/test/common/sea.js @@ -2,6 +2,7 @@ const common = require('../common'); const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); const { readFileSync } = require('fs'); const { @@ -43,6 +44,14 @@ function skipIfSingleExecutableIsNotSupported() { common.skip('On s390x, postject fails with `memory access out of bounds`.'); } } + + tmpdir.refresh(); + + // The SEA tests involve making a copy of the executable and writing some fixtures + // to the tmpdir. To be safe, ensure that at least 120MB disk space is available. + if (!tmpdir.hasEnoughSpace(120 * 1024 * 1024)) { + common.skip('Available disk space < 120MB'); + } } function injectAndCodeSign(targetExecutable, resource) { diff --git a/test/sequential/test-single-executable-application-disable-experimental-sea-warning.js b/test/sequential/test-single-executable-application-disable-experimental-sea-warning.js index 0b4701b07e1c54..fdd0c23a26da3e 100644 --- a/test/sequential/test-single-executable-application-disable-experimental-sea-warning.js +++ b/test/sequential/test-single-executable-application-disable-experimental-sea-warning.js @@ -15,9 +15,8 @@ skipIfSingleExecutableIsNotSupported(); const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { execFileSync } = require('child_process'); +const { spawnSyncAndExitWithoutError } = require('../common/child_process'); const { join } = require('path'); -const { strictEqual } = require('assert'); const assert = require('assert'); const inputFile = fixtures.path('sea.js'); @@ -44,17 +43,27 @@ writeFileSync(configFile, ` // Copy input to working directory copyFileSync(inputFile, tmpdir.resolve('sea.js')); -execFileSync(process.execPath, ['--experimental-sea-config', 'sea-config.json'], { - cwd: tmpdir.path -}); +spawnSyncAndExitWithoutError( + process.execPath, + ['--experimental-sea-config', 'sea-config.json'], + { cwd: tmpdir.path }, + {}); assert(existsSync(seaPrepBlob)); copyFileSync(process.execPath, outputFile); injectAndCodeSign(outputFile, seaPrepBlob); -const singleExecutableApplicationOutput = execFileSync( +spawnSyncAndExitWithoutError( outputFile, [ '-a', '--b=c', 'd' ], - { env: { COMMON_DIRECTORY: join(__dirname, '..', 'common') } }); -strictEqual(singleExecutableApplicationOutput.toString(), 'Hello, world! 😊\n'); + { + env: { + COMMON_DIRECTORY: join(__dirname, '..', 'common'), + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + } + }, + { + stdout: 'Hello, world! 😊\n' + }); diff --git a/test/sequential/test-single-executable-application-empty.js b/test/sequential/test-single-executable-application-empty.js index 13dc2e834b7caa..047685b0074aa9 100644 --- a/test/sequential/test-single-executable-application-empty.js +++ b/test/sequential/test-single-executable-application-empty.js @@ -14,7 +14,7 @@ skipIfSingleExecutableIsNotSupported(); const tmpdir = require('../common/tmpdir'); const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { execFileSync } = require('child_process'); +const { spawnSyncAndExitWithoutError } = require('../common/child_process'); const assert = require('assert'); const configFile = tmpdir.resolve('sea-config.json'); @@ -31,13 +31,22 @@ writeFileSync(configFile, ` } `); -execFileSync(process.execPath, ['--experimental-sea-config', 'sea-config.json'], { - cwd: tmpdir.path -}); +spawnSyncAndExitWithoutError( + process.execPath, + ['--experimental-sea-config', 'sea-config.json'], + { cwd: tmpdir.path }); assert(existsSync(seaPrepBlob)); copyFileSync(process.execPath, outputFile); injectAndCodeSign(outputFile, seaPrepBlob); -execFileSync(outputFile); +spawnSyncAndExitWithoutError( + outputFile, + { + env: { + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + } + }, + {}); diff --git a/test/sequential/test-single-executable-application-snapshot-and-code-cache.js b/test/sequential/test-single-executable-application-snapshot-and-code-cache.js index 6d86d6a79d8d68..952003cf02c585 100644 --- a/test/sequential/test-single-executable-application-snapshot-and-code-cache.js +++ b/test/sequential/test-single-executable-application-snapshot-and-code-cache.js @@ -49,7 +49,11 @@ const outputFile = join(tmpdir.path, process.platform === 'win32' ? 'sea.exe' : process.execPath, ['--experimental-sea-config', 'sea-config.json'], { - cwd: tmpdir.path + cwd: tmpdir.path, + env: { + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + }, }, { stderr: /"useCodeCache" is redundant when "useSnapshot" is true/ @@ -61,8 +65,15 @@ const outputFile = join(tmpdir.path, process.platform === 'win32' ? 'sea.exe' : copyFileSync(process.execPath, outputFile); injectAndCodeSign(outputFile, seaPrepBlob); - spawnSyncAndExitWithoutError(outputFile, { - stdout: 'Hello from snapshot', - trim: true, - }); + spawnSyncAndExitWithoutError( + outputFile, + { + env: { + NODE_DEBUG_NATIVE: 'SEA,MKSNAPSHOT', + ...process.env, + } + }, { + stdout: 'Hello from snapshot', + trim: true, + }); } diff --git a/test/sequential/test-single-executable-application-snapshot.js b/test/sequential/test-single-executable-application-snapshot.js index 5c2d8c36fdd38f..402505a6122c74 100644 --- a/test/sequential/test-single-executable-application-snapshot.js +++ b/test/sequential/test-single-executable-application-snapshot.js @@ -73,7 +73,11 @@ const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'se process.execPath, ['--experimental-sea-config', 'sea-config.json'], { - cwd: tmpdir.path + cwd: tmpdir.path, + env: { + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + }, }, { stderr: /Single executable application is an experimental feature/ @@ -86,6 +90,12 @@ const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'se spawnSyncAndExitWithoutError( outputFile, + { + env: { + NODE_DEBUG_NATIVE: 'SEA,MKSNAPSHOT', + ...process.env, + } + }, { trim: true, stdout: 'Hello from snapshot', diff --git a/test/sequential/test-single-executable-application-use-code-cache.js b/test/sequential/test-single-executable-application-use-code-cache.js index 96de5769b1fe6b..af5f2855ed6318 100644 --- a/test/sequential/test-single-executable-application-use-code-cache.js +++ b/test/sequential/test-single-executable-application-use-code-cache.js @@ -15,9 +15,8 @@ skipIfSingleExecutableIsNotSupported(); const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { execFileSync } = require('child_process'); +const { spawnSyncAndExitWithoutError } = require('../common/child_process'); const { join } = require('path'); -const { strictEqual } = require('assert'); const assert = require('assert'); const inputFile = fixtures.path('sea.js'); @@ -44,17 +43,32 @@ writeFileSync(configFile, ` // Copy input to working directory copyFileSync(inputFile, tmpdir.resolve('sea.js')); -execFileSync(process.execPath, ['--experimental-sea-config', 'sea-config.json'], { - cwd: tmpdir.path -}); +spawnSyncAndExitWithoutError( + process.execPath, + ['--experimental-sea-config', 'sea-config.json'], + { + cwd: tmpdir.path, + env: { + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + }, + }); assert(existsSync(seaPrepBlob)); copyFileSync(process.execPath, outputFile); injectAndCodeSign(outputFile, seaPrepBlob); -const singleExecutableApplicationOutput = execFileSync( +spawnSyncAndExitWithoutError( outputFile, [ '-a', '--b=c', 'd' ], - { env: { COMMON_DIRECTORY: join(__dirname, '..', 'common') } }); -strictEqual(singleExecutableApplicationOutput.toString(), 'Hello, world! 😊\n'); + { + env: { + COMMON_DIRECTORY: join(__dirname, '..', 'common'), + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + } + }, + { + stdout: 'Hello, world! 😊\n' + }); diff --git a/test/sequential/test-single-executable-application.js b/test/sequential/test-single-executable-application.js index e930254cb0a7ae..6379dfd2ea4b6d 100644 --- a/test/sequential/test-single-executable-application.js +++ b/test/sequential/test-single-executable-application.js @@ -14,9 +14,8 @@ skipIfSingleExecutableIsNotSupported(); const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { execFileSync } = require('child_process'); +const { spawnSyncAndExitWithoutError } = require('../common/child_process'); const { join } = require('path'); -const { strictEqual } = require('assert'); const assert = require('assert'); const inputFile = fixtures.path('sea.js'); @@ -43,17 +42,27 @@ writeFileSync(configFile, ` // Copy input to working directory copyFileSync(inputFile, tmpdir.resolve('sea.js')); -execFileSync(process.execPath, ['--experimental-sea-config', 'sea-config.json'], { - cwd: tmpdir.path -}); +spawnSyncAndExitWithoutError( + process.execPath, + ['--experimental-sea-config', 'sea-config.json'], + { cwd: tmpdir.path }, + {}); assert(existsSync(seaPrepBlob)); copyFileSync(process.execPath, outputFile); injectAndCodeSign(outputFile, seaPrepBlob); -const singleExecutableApplicationOutput = execFileSync( +spawnSyncAndExitWithoutError( outputFile, [ '-a', '--b=c', 'd' ], - { env: { COMMON_DIRECTORY: join(__dirname, '..', 'common') } }); -strictEqual(singleExecutableApplicationOutput.toString(), 'Hello, world! 😊\n'); + { + env: { + COMMON_DIRECTORY: join(__dirname, '..', 'common'), + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + } + }, + { + stdout: 'Hello, world! 😊\n' + }); From cedc3427fa0a12c4fd00b78d204765dd2d091a20 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:11:11 +0000 Subject: [PATCH 10/38] doc: run license-builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50926 Reviewed-By: Michaël Zasso Reviewed-By: Matteo Collina Reviewed-By: Marco Ippolito Reviewed-By: Moshe Atlow Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca Reviewed-By: Benjamin Gruenbaum --- LICENSE | 75 ++++++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/LICENSE b/LICENSE index 9188c2223d1f8b..9cee50463b0ca2 100644 --- a/LICENSE +++ b/LICENSE @@ -132,52 +132,45 @@ The externally maintained libraries used by Node.js are: - ICU, located at deps/icu-small, is licensed as follows: """ - UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - - See Terms of Use - for definitions of Unicode Inc.’s Data Files and Software. - - NOTICE TO USER: Carefully read the following legal agreement. - BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S - DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), - YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE - TERMS AND CONDITIONS OF THIS AGREEMENT. - IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE - THE DATA FILES OR SOFTWARE. + UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE - Copyright © 1991-2023 Unicode, Inc. All rights reserved. - Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + Copyright © 2016-2023 Unicode, Inc. - Permission is hereby granted, free of charge, to any person obtaining - a copy of the Unicode data files and any associated documentation - (the "Data Files") or Unicode software and any associated documentation - (the "Software") to deal in the Data Files or Software - without restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, and/or sell copies of - the Data Files or Software, and to permit persons to whom the Data Files - or Software are furnished to do so, provided that either - (a) this copyright and permission notice appear with all copies - of the Data Files or Software, or - (b) this copyright and permission notice appear in associated - Documentation. - - THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS - NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL - DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THE DATA FILES OR SOFTWARE. + NOTICE TO USER: Carefully read the following legal agreement. BY + DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR + SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE + TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT + DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. - Except as contained in this notice, the name of a copyright holder - shall not be used in advertising or otherwise to promote the sale, - use or other dealings in these Data Files or Software without prior - written authorization of the copyright holder. + Permission is hereby granted, free of charge, to any person obtaining a + copy of data files and any associated documentation (the "Data Files") or + software and any associated documentation (the "Software") to deal in the + Data Files or Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, and/or sell + copies of the Data Files or Software, and to permit persons to whom the + Data Files or Software are furnished to do so, provided that either (a) + this copyright and permission notice appear with all copies of the Data + Files or Software, or (b) this copyright and permission notice appear in + associated Documentation. + + THE DATA FILES AND SOFTWARE ARE 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 OF + THIRD PARTY RIGHTS. + + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE + BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA + FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder shall + not be used in advertising or otherwise to promote the sale, use or other + dealings in these Data Files or Software without prior written + authorization of the copyright holder. ---------------------------------------------------------------------- From 759ebcaead72c0f3574bcfb80e7bffa3dc33b60f Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Wed, 29 Nov 2023 10:22:03 +0100 Subject: [PATCH 11/38] doc: reserve 121 for Electron 29 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50957 Reviewed-By: Luigi Pinca Reviewed-By: Michaël Zasso Reviewed-By: Yagiz Nizipli Reviewed-By: Richard Lau Reviewed-By: Moshe Atlow --- doc/abi_version_registry.json | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/abi_version_registry.json b/doc/abi_version_registry.json index c5fd7d2fd2a3ee..2dc7511694859d 100644 --- a/doc/abi_version_registry.json +++ b/doc/abi_version_registry.json @@ -1,5 +1,6 @@ { "NODE_MODULE_VERSION": [ + { "modules": 121,"runtime": "electron", "variant": "electron", "versions": "29" }, { "modules": 120,"runtime": "node", "variant": "v8_11.8", "versions": "21.0.0" }, { "modules": 119,"runtime": "electron", "variant": "electron", "versions": "28" }, { "modules": 118,"runtime": "electron", "variant": "electron", "versions": "27" }, From dc049acbbbf21ecbf1ee31d765b7e3f8929bd6d6 Mon Sep 17 00:00:00 2001 From: kylo5aby <109658203+zhenweijin@users.noreply.github.com> Date: Wed, 29 Nov 2023 18:09:28 +0800 Subject: [PATCH 12/38] benchmark: update number of iterations for `util.inspect` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50651 Refs: https://github.com/nodejs/node/issues/50571 Reviewed-By: James M Snell Reviewed-By: Vinícius Lourenço Claro Cardoso --- benchmark/util/inspect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark/util/inspect.js b/benchmark/util/inspect.js index ace4e588ae5135..8e453b9e226ee8 100644 --- a/benchmark/util/inspect.js +++ b/benchmark/util/inspect.js @@ -9,7 +9,7 @@ const opts = { none: undefined, }; const bench = common.createBenchmark(main, { - n: [2e4], + n: [8e4], method: [ 'Object', 'Object_empty', From 3faed331e188f7345564bee8a065cfd289510467 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Wed, 29 Nov 2023 04:15:10 -0600 Subject: [PATCH 13/38] typings: fix JSDoc in `internal/modules/esm/hooks` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50887 Reviewed-By: Yagiz Nizipli Reviewed-By: Vinícius Lourenço Claro Cardoso Reviewed-By: Jacob Smith --- lib/internal/modules/esm/hooks.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/modules/esm/hooks.js b/lib/internal/modules/esm/hooks.js index cb2bc456dbb8f1..314c49a95a4ea1 100644 --- a/lib/internal/modules/esm/hooks.js +++ b/lib/internal/modules/esm/hooks.js @@ -100,6 +100,7 @@ function defineImportAssertionAlias(context) { * @typedef {object} KeyedHook * @property {Function} fn The hook function. * @property {URL['href']} url The URL of the module. + * @property {KeyedHook?} next The next hook in the chain. */ // [2] `validate...()`s throw the wrong error @@ -688,7 +689,7 @@ function pluckHooks({ * A utility function to iterate through a hook chain, track advancement in the * chain, and generate and supply the `next` argument to the custom * hook. - * @param {Hook} current The (currently) first hook in the chain (this shifts + * @param {KeyedHook} current The (currently) first hook in the chain (this shifts * on every call). * @param {object} meta Properties that change as the current hook advances * along the chain. From 7adf239af0829775078d21c2951f6808e967b2ec Mon Sep 17 00:00:00 2001 From: "Christopher Jeffrey (JJ)" Date: Wed, 29 Nov 2023 05:28:44 -0500 Subject: [PATCH 14/38] doc: fix some errors in esm resolution algorithms PR-URL: https://github.com/nodejs/node/pull/50898 Reviewed-By: Guy Bedford Reviewed-By: Geoffrey Booth Reviewed-By: Luigi Pinca Reviewed-By: Antoine du Hamel --- doc/api/esm.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index e8f6419a429457..f19e22009586de 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -933,9 +933,9 @@ The resolver can throw the following errors: > 2. If _resolved_ is not **null** or **undefined**, return _resolved_. > 3. Otherwise, if _exports_ is an Object and all keys of _exports_ start with > _"."_, then -> 1. Let _matchKey_ be the string _"./"_ concatenated with _subpath_. +> 1. Assert: _subpath_ begins with _"./"_. > 2. Let _resolved_ be the result of **PACKAGE\_IMPORTS\_EXPORTS\_RESOLVE**( -> _matchKey_, _exports_, _packageURL_, **false**, _conditions_). +> _subpath_, _exports_, _packageURL_, **false**, _conditions_). > 3. If _resolved_ is not **null** or **undefined**, return _resolved_. > 4. Throw a _Package Path Not Exported_ error. @@ -1015,7 +1015,7 @@ _isImports_, _conditions_) > Package Target_ error. > 3. Let _resolvedTarget_ be the URL resolution of the concatenation of > _packageURL_ and _target_. -> 4. Assert: _resolvedTarget_ is contained in _packageURL_. +> 4. Assert: _packageURL_ is contained in _resolvedTarget_. > 5. If _patternMatch_ is **null**, then > 1. Return _resolvedTarget_. > 6. If _patternMatch_ split on _"/"_ or _"\\"_ contains any _""_, _"."_, @@ -1024,7 +1024,7 @@ _isImports_, _conditions_) > 7. Return the URL resolution of _resolvedTarget_ with every instance of > _"\*"_ replaced with _patternMatch_. > 2. Otherwise, if _target_ is a non-null Object, then -> 1. If _exports_ contains any index property keys, as defined in ECMA-262 +> 1. If _target_ contains any index property keys, as defined in ECMA-262 > [6.1.7 Array Index][], throw an _Invalid Package Configuration_ error. > 2. For each property _p_ of _target_, in object insertion order as, > 1. If _p_ equals _"default"_ or _conditions_ contains an entry for _p_, From 4b1bed04f79dde088b56a1a638de2bc70cdb8268 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Wed, 29 Nov 2023 15:51:55 +0200 Subject: [PATCH 15/38] deps: update undici to 5.28.0 PR-URL: https://github.com/nodejs/node/pull/50915 Reviewed-By: Matthew Aitken Reviewed-By: Antoine du Hamel --- deps/undici/src/docs/api/Client.md | 2 +- deps/undici/src/docs/api/MockPool.md | 42 +- deps/undici/src/docs/api/RetryHandler.md | 108 ++ deps/undici/src/index.js | 2 + deps/undici/src/lib/api/readable.js | 65 +- deps/undici/src/lib/client.js | 17 +- deps/undici/src/lib/core/errors.js | 16 +- deps/undici/src/lib/core/request.js | 12 +- deps/undici/src/lib/core/symbols.js | 3 +- deps/undici/src/lib/core/util.js | 34 +- deps/undici/src/lib/fetch/headers.js | 152 +- deps/undici/src/lib/fetch/index.js | 8 +- deps/undici/src/lib/fetch/request.js | 4 +- deps/undici/src/lib/fetch/util.js | 71 +- deps/undici/src/lib/fetch/webidl.js | 6 +- deps/undici/src/lib/handler/RetryHandler.js | 336 ++++ deps/undici/src/package-lock.json | 1545 +++++++++++++++-- deps/undici/src/package.json | 3 +- deps/undici/src/types/client.d.ts | 2 +- deps/undici/src/types/dispatcher.d.ts | 2 +- deps/undici/src/types/index.d.ts | 4 +- deps/undici/src/types/retry-handler.d.ts | 116 ++ deps/undici/undici.js | 240 ++- .../maintaining/maintaining-dependencies.md | 6 +- src/undici_version.h | 2 +- 25 files changed, 2377 insertions(+), 421 deletions(-) create mode 100644 deps/undici/src/docs/api/RetryHandler.md create mode 100644 deps/undici/src/lib/handler/RetryHandler.js create mode 100644 deps/undici/src/types/retry-handler.d.ts diff --git a/deps/undici/src/docs/api/Client.md b/deps/undici/src/docs/api/Client.md index 42668389a94225..b9e26f09752bd5 100644 --- a/deps/undici/src/docs/api/Client.md +++ b/deps/undici/src/docs/api/Client.md @@ -33,7 +33,7 @@ Returns: `Client` * **autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version. * **autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. * **allowH2**: `boolean` - Default: `false`. Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation. -* **maxConcurrentStreams**: `number` - Default: `100`. Dictates the maximum number of concurrent streams for a single H2 session. It can be overriden by a SETTINGS remote frame. +* **maxConcurrentStreams**: `number` - Default: `100`. Dictates the maximum number of concurrent streams for a single H2 session. It can be overridden by a SETTINGS remote frame. #### Parameter: `ConnectOptions` diff --git a/deps/undici/src/docs/api/MockPool.md b/deps/undici/src/docs/api/MockPool.md index de53914002eca3..96a986f57bb389 100644 --- a/deps/undici/src/docs/api/MockPool.md +++ b/deps/undici/src/docs/api/MockPool.md @@ -35,8 +35,7 @@ const mockPool = mockAgent.get('http://localhost:3000') ### `MockPool.intercept(options)` -This method defines the interception rules for matching against requests for a MockPool or MockPool. We can intercept multiple times on a single instance, but each intercept is only used once. -For example if you expect to make 2 requests inside a test, you need to call `intercept()` twice. Assuming you use `disableNetConnect()` you will get `MockNotMatchedError` on the second request when you only call `intercept()` once. +This method defines the interception rules for matching against requests for a MockPool or MockPool. We can intercept multiple times on a single instance, but each intercept is only used once. For example if you expect to make 2 requests inside a test, you need to call `intercept()` twice. Assuming you use `disableNetConnect()` you will get `MockNotMatchedError` on the second request when you only call `intercept()` once. When defining interception rules, all the rules must pass for a request to be intercepted. If a request is not intercepted, a real request will be attempted. @@ -54,11 +53,11 @@ Returns: `MockInterceptor` corresponding to the input options. ### Parameter: `MockPoolInterceptOptions` -* **path** `string | RegExp | (path: string) => boolean` - a matcher for the HTTP request path. +* **path** `string | RegExp | (path: string) => boolean` - a matcher for the HTTP request path. When a `RegExp` or callback is used, it will match against the request path including all query parameters in alphabetical order. When a `string` is provided, the query parameters can be conveniently specified through the `MockPoolInterceptOptions.query` setting. * **method** `string | RegExp | (method: string) => boolean` - (optional) - a matcher for the HTTP request method. Defaults to `GET`. * **body** `string | RegExp | (body: string) => boolean` - (optional) - a matcher for the HTTP request body. * **headers** `Record boolean`> - (optional) - a matcher for the HTTP request headers. To be intercepted, a request must match all defined headers. Extra headers not defined here may (or may not) be included in the request and do not affect the interception in any way. -* **query** `Record | null` - (optional) - a matcher for the HTTP request query string params. +* **query** `Record | null` - (optional) - a matcher for the HTTP request query string params. Only applies when a `string` was provided for `MockPoolInterceptOptions.path`. ### Return: `MockInterceptor` @@ -458,6 +457,41 @@ const result3 = await request('http://localhost:3000/foo') // Will not match and make attempt a real request ``` +#### Example - Mocked request with path callback + +```js +import { MockAgent, setGlobalDispatcher, request } from 'undici' +import querystring from 'querystring' + +const mockAgent = new MockAgent() +setGlobalDispatcher(mockAgent) + +const mockPool = mockAgent.get('http://localhost:3000') + +const matchPath = requestPath => { + const [pathname, search] = requestPath.split('?') + const requestQuery = querystring.parse(search) + + if (!pathname.startsWith('/foo')) { + return false + } + + if (!Object.keys(requestQuery).includes('foo') || requestQuery.foo !== 'bar') { + return false + } + + return true +} + +mockPool.intercept({ + path: matchPath, + method: 'GET' +}).reply(200, 'foo') + +const result = await request('http://localhost:3000/foo?foo=bar') +// Will match and return mocked data +``` + ### `MockPool.close()` Closes the mock pool and de-registers from associated MockAgent. diff --git a/deps/undici/src/docs/api/RetryHandler.md b/deps/undici/src/docs/api/RetryHandler.md new file mode 100644 index 00000000000000..2323ce47911e79 --- /dev/null +++ b/deps/undici/src/docs/api/RetryHandler.md @@ -0,0 +1,108 @@ +# Class: RetryHandler + +Extends: `undici.DispatcherHandlers` + +A handler class that implements the retry logic for a request. + +## `new RetryHandler(dispatchOptions, retryHandlers, [retryOptions])` + +Arguments: + +- **options** `Dispatch.DispatchOptions & RetryOptions` (required) - It is an intersection of `Dispatcher.DispatchOptions` and `RetryOptions`. +- **retryHandlers** `RetryHandlers` (required) - Object containing the `dispatch` to be used on every retry, and `handler` for handling the `dispatch` lifecycle. + +Returns: `retryHandler` + +### Parameter: `Dispatch.DispatchOptions & RetryOptions` + +Extends: [`Dispatch.DispatchOptions`](Dispatcher.md#parameter-dispatchoptions). + +#### `RetryOptions` + +- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => void` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed. +- **maxRetries** `number` (optional) - Maximum number of retries. Default: `5` +- **maxTimeout** `number` (optional) - Maximum number of milliseconds to wait before retrying. Default: `30000` (30 seconds) +- **minTimeout** `number` (optional) - Minimum number of milliseconds to wait before retrying. Default: `500` (half a second) +- **timeoutFactor** `number` (optional) - Factor to multiply the timeout by for each retry attempt. Default: `2` +- **retryAfter** `boolean` (optional) - It enables automatic retry after the `Retry-After` header is received. Default: `true` +- +- **methods** `string[]` (optional) - Array of HTTP methods to retry. Default: `['GET', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']` +- **statusCodes** `number[]` (optional) - Array of HTTP status codes to retry. Default: `[429, 500, 502, 503, 504]` +- **errorCodes** `string[]` (optional) - Array of Error codes to retry. Default: `['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN','ENETUNREACH', 'EHOSTDOWN', + +**`RetryContext`** + +- `state`: `RetryState` - Current retry state. It can be mutated. +- `opts`: `Dispatch.DispatchOptions & RetryOptions` - Options passed to the retry handler. + +### Parameter `RetryHandlers` + +- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise` (required) - Dispatch function to be called after every retry. +- **handler** Extends [`Dispatch.DispatchHandlers`](Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted. + +Examples: + +```js +const client = new Client(`http://localhost:${server.address().port}`); +const chunks = []; +const handler = new RetryHandler( + { + ...dispatchOptions, + retryOptions: { + // custom retry function + retry: function (err, state, callback) { + counter++; + + if (err.code && err.code === "UND_ERR_DESTROYED") { + callback(err); + return; + } + + if (err.statusCode === 206) { + callback(err); + return; + } + + setTimeout(() => callback(null), 1000); + }, + }, + }, + { + dispatch: (...args) => { + return client.dispatch(...args); + }, + handler: { + onConnect() {}, + onBodySent() {}, + onHeaders(status, _rawHeaders, resume, _statusMessage) { + // do something with headers + }, + onData(chunk) { + chunks.push(chunk); + return true; + }, + onComplete() {}, + onError() { + // handle error properly + }, + }, + } +); +``` + +#### Example - Basic RetryHandler with defaults + +```js +const client = new Client(`http://localhost:${server.address().port}`); +const handler = new RetryHandler(dispatchOptions, { + dispatch: client.dispatch.bind(client), + handler: { + onConnect() {}, + onBodySent() {}, + onHeaders(status, _rawHeaders, resume, _statusMessage) {}, + onData(chunk) {}, + onComplete() {}, + onError(err) {}, + }, +}); +``` diff --git a/deps/undici/src/index.js b/deps/undici/src/index.js index 7c0c8adcd6c809..26302cc8efa62b 100644 --- a/deps/undici/src/index.js +++ b/deps/undici/src/index.js @@ -15,6 +15,7 @@ const MockAgent = require('./lib/mock/mock-agent') const MockPool = require('./lib/mock/mock-pool') const mockErrors = require('./lib/mock/mock-errors') const ProxyAgent = require('./lib/proxy-agent') +const RetryHandler = require('./lib/handler/RetryHandler') const { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global') const DecoratorHandler = require('./lib/handler/DecoratorHandler') const RedirectHandler = require('./lib/handler/RedirectHandler') @@ -36,6 +37,7 @@ module.exports.Pool = Pool module.exports.BalancedPool = BalancedPool module.exports.Agent = Agent module.exports.ProxyAgent = ProxyAgent +module.exports.RetryHandler = RetryHandler module.exports.DecoratorHandler = DecoratorHandler module.exports.RedirectHandler = RedirectHandler diff --git a/deps/undici/src/lib/api/readable.js b/deps/undici/src/lib/api/readable.js index d106568cd4bad1..89913eaa621854 100644 --- a/deps/undici/src/lib/api/readable.js +++ b/deps/undici/src/lib/api/readable.js @@ -16,6 +16,8 @@ const kBody = Symbol('kBody') const kAbort = Symbol('abort') const kContentType = Symbol('kContentType') +const noop = () => {} + module.exports = class BodyReadable extends Readable { constructor ({ resume, @@ -149,37 +151,50 @@ module.exports = class BodyReadable extends Readable { return this[kBody] } - async dump (opts) { + dump (opts) { let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 const signal = opts && opts.signal - const abortFn = () => { - this.destroy() - } - let signalListenerCleanup + if (signal) { - if (typeof signal !== 'object' || !('aborted' in signal)) { - throw new InvalidArgumentError('signal must be an AbortSignal') - } - util.throwIfAborted(signal) - signalListenerCleanup = util.addAbortListener(signal, abortFn) - } - try { - for await (const chunk of this) { - util.throwIfAborted(signal) - limit -= Buffer.byteLength(chunk) - if (limit < 0) { - return + try { + if (typeof signal !== 'object' || !('aborted' in signal)) { + throw new InvalidArgumentError('signal must be an AbortSignal') } + util.throwIfAborted(signal) + } catch (err) { + return Promise.reject(err) } - } catch { - util.throwIfAborted(signal) - } finally { - if (typeof signalListenerCleanup === 'function') { - signalListenerCleanup() - } else if (signalListenerCleanup) { - signalListenerCleanup[Symbol.dispose]() - } } + + if (this.closed) { + return Promise.resolve(null) + } + + return new Promise((resolve, reject) => { + const signalListenerCleanup = signal + ? util.addAbortListener(signal, () => { + this.destroy() + }) + : noop + + this + .on('close', function () { + signalListenerCleanup() + if (signal?.aborted) { + reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) + } else { + resolve(null) + } + }) + .on('error', noop) + .on('data', function (chunk) { + limit -= chunk.length + if (limit <= 0) { + this.destroy() + } + }) + .resume() + }) } } diff --git a/deps/undici/src/lib/client.js b/deps/undici/src/lib/client.js index 968a7f920710ec..cafc03a09ff86b 100644 --- a/deps/undici/src/lib/client.js +++ b/deps/undici/src/lib/client.js @@ -1183,7 +1183,7 @@ async function connect (client) { const idx = hostname.indexOf(']') assert(idx !== -1) - const ip = hostname.substr(1, idx - 1) + const ip = hostname.substring(1, idx) assert(net.isIP(ip)) hostname = ip @@ -1682,6 +1682,7 @@ function writeH2 (client, session, request) { return false } + /** @type {import('node:http2').ClientHttp2Stream} */ let stream const h2State = client[kHTTP2SessionState] @@ -1777,14 +1778,10 @@ function writeH2 (client, session, request) { const shouldEndStream = method === 'GET' || method === 'HEAD' if (expectContinue) { headers[HTTP2_HEADER_EXPECT] = '100-continue' - /** - * @type {import('node:http2').ClientHttp2Stream} - */ stream = session.request(headers, { endStream: shouldEndStream, signal }) stream.once('continue', writeBodyH2) } else { - /** @type {import('node:http2').ClientHttp2Stream} */ stream = session.request(headers, { endStream: shouldEndStream, signal @@ -1796,7 +1793,9 @@ function writeH2 (client, session, request) { ++h2State.openStreams stream.once('response', headers => { - if (request.onHeaders(Number(headers[HTTP2_HEADER_STATUS]), headers, stream.resume.bind(stream), '') === false) { + const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers + + if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { stream.pause() } }) @@ -1972,7 +1971,11 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength, } } const onAbort = function () { - onFinished(new RequestAbortedError()) + if (finished) { + return + } + const err = new RequestAbortedError() + queueMicrotask(() => onFinished(err)) } const onFinished = function (err) { if (finished) { diff --git a/deps/undici/src/lib/core/errors.js b/deps/undici/src/lib/core/errors.js index 653782d9b5e0e6..7af704b462a41e 100644 --- a/deps/undici/src/lib/core/errors.js +++ b/deps/undici/src/lib/core/errors.js @@ -193,6 +193,19 @@ class ResponseExceededMaxSizeError extends UndiciError { } } +class RequestRetryError extends UndiciError { + constructor (message, code, { headers, data }) { + super(message) + Error.captureStackTrace(this, RequestRetryError) + this.name = 'RequestRetryError' + this.message = message || 'Request retry error' + this.code = 'UND_ERR_REQ_RETRY' + this.statusCode = code + this.data = data + this.headers = headers + } +} + module.exports = { HTTPParserError, UndiciError, @@ -212,5 +225,6 @@ module.exports = { NotSupportedError, ResponseContentLengthMismatchError, BalancedPoolMissingUpstreamError, - ResponseExceededMaxSizeError + ResponseExceededMaxSizeError, + RequestRetryError } diff --git a/deps/undici/src/lib/core/request.js b/deps/undici/src/lib/core/request.js index 7db05ce65aed4d..fbbe45a6d9c4fa 100644 --- a/deps/undici/src/lib/core/request.js +++ b/deps/undici/src/lib/core/request.js @@ -229,11 +229,7 @@ class Request { onBodySent (chunk) { if (this[kHandler].onBodySent) { - try { - this[kHandler].onBodySent(chunk) - } catch (err) { - this.onError(err) - } + return this[kHandler].onBodySent(chunk) } } @@ -243,11 +239,7 @@ class Request { } if (this[kHandler].onRequestSent) { - try { - this[kHandler].onRequestSent() - } catch (err) { - this.onError(err) - } + return this[kHandler].onRequestSent() } } diff --git a/deps/undici/src/lib/core/symbols.js b/deps/undici/src/lib/core/symbols.js index c2492f4355fd2a..1d5dc4e3db0360 100644 --- a/deps/undici/src/lib/core/symbols.js +++ b/deps/undici/src/lib/core/symbols.js @@ -57,5 +57,6 @@ module.exports = { kHTTP2BuildRequest: Symbol('http2 build request'), kHTTP1BuildRequest: Symbol('http1 build request'), kHTTP2CopyHeaders: Symbol('http2 copy headers'), - kHTTPConnVersion: Symbol('http connection version') + kHTTPConnVersion: Symbol('http connection version'), + kRetryHandlerDefaultRetry: Symbol('retry agent default retry') } diff --git a/deps/undici/src/lib/core/util.js b/deps/undici/src/lib/core/util.js index f2ead03936317b..8d5450ba0c0c0c 100644 --- a/deps/undici/src/lib/core/util.js +++ b/deps/undici/src/lib/core/util.js @@ -125,13 +125,13 @@ function getHostname (host) { const idx = host.indexOf(']') assert(idx !== -1) - return host.substr(1, idx - 1) + return host.substring(1, idx) } const idx = host.indexOf(':') if (idx === -1) return host - return host.substr(0, idx) + return host.substring(0, idx) } // IP addresses are not valid server names per RFC6066 @@ -228,7 +228,7 @@ function parseHeaders (headers, obj = {}) { if (!val) { if (Array.isArray(headers[i + 1])) { - obj[key] = headers[i + 1] + obj[key] = headers[i + 1].map(x => x.toString('utf8')) } else { obj[key] = headers[i + 1].toString('utf8') } @@ -431,16 +431,7 @@ function throwIfAborted (signal) { } } -let events function addAbortListener (signal, listener) { - if (typeof Symbol.dispose === 'symbol') { - if (!events) { - events = require('events') - } - if (typeof events.addAbortListener === 'function' && 'aborted' in signal) { - return events.addAbortListener(signal, listener) - } - } if ('addEventListener' in signal) { signal.addEventListener('abort', listener, { once: true }) return () => signal.removeEventListener('abort', listener) @@ -464,6 +455,21 @@ function toUSVString (val) { return `${val}` } +// 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 } + + 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 kEnumerableProperty = Object.create(null) kEnumerableProperty.enumerable = true @@ -497,7 +503,9 @@ module.exports = { buildURL, throwIfAborted, addAbortListener, + parseRangeHeader, nodeMajor, nodeMinor, - nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13) + nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13), + safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'] } diff --git a/deps/undici/src/lib/fetch/headers.js b/deps/undici/src/lib/fetch/headers.js index aa5e73e5d27542..69acaaad9964af 100644 --- a/deps/undici/src/lib/fetch/headers.js +++ b/deps/undici/src/lib/fetch/headers.js @@ -16,6 +16,13 @@ const assert = require('assert') const kHeadersMap = Symbol('headers map') const kHeadersSortedMap = Symbol('headers map sorted') +/** + * @param {number} code + */ +function isHTTPWhiteSpaceCharCode (code) { + return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 +} + /** * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize * @param {string} potentialValue @@ -24,12 +31,12 @@ function headerValueNormalize (potentialValue) { // To normalize a byte sequence potentialValue, remove // any leading and trailing HTTP whitespace bytes from // potentialValue. + let i = 0; let j = potentialValue.length - // Trimming the end with `.replace()` and a RegExp is typically subject to - // ReDoS. This is safer and faster. - let i = potentialValue.length - while (/[\r\n\t ]/.test(potentialValue.charAt(--i))); - return potentialValue.slice(0, i + 1).replace(/^[\r\n\t ]+/, '') + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i + + return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) } function fill (headers, object) { @@ -38,7 +45,8 @@ function fill (headers, object) { // 1. If object is a sequence, then for each header in object: // Note: webidl conversion to array has already been done. if (Array.isArray(object)) { - for (const header of object) { + for (let i = 0; i < object.length; ++i) { + const header = object[i] // 1. If header does not contain exactly two items, then throw a TypeError. if (header.length !== 2) { throw webidl.errors.exception({ @@ -48,15 +56,16 @@ function fill (headers, object) { } // 2. Append (header’s first item, header’s second item) to headers. - headers.append(header[0], header[1]) + appendHeader(headers, header[0], header[1]) } } else if (typeof object === 'object' && object !== null) { // Note: null should throw // 2. Otherwise, object is a record, then for each key → value in object, // append (key, value) to headers - for (const [key, value] of Object.entries(object)) { - headers.append(key, value) + const keys = Object.keys(object) + for (let i = 0; i < keys.length; ++i) { + appendHeader(headers, keys[i], object[keys[i]]) } } else { throw webidl.errors.conversionFailed({ @@ -67,6 +76,50 @@ function fill (headers, object) { } } +/** + * @see https://fetch.spec.whatwg.org/#concept-headers-append + */ +function appendHeader (headers, name, value) { + // 1. Normalize value. + value = headerValueNormalize(value) + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value, + type: 'header value' + }) + } + + // 3. If headers’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if headers’s guard is "request" and name is a + // forbidden header name, return. + // Note: undici does not implement forbidden header names + if (headers[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (headers[kGuard] === 'request-no-cors') { + // 5. Otherwise, if headers’s guard is "request-no-cors": + // TODO + } + + // 6. Otherwise, if headers’s guard is "response" and name is a + // forbidden response-header name, return. + + // 7. Append (name, value) to headers’s header list. + return headers[kHeadersList].append(name, value) + + // 8. If headers’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from headers +} + class HeadersList { /** @type {[string, string][]|null} */ cookies = null @@ -75,7 +128,7 @@ class HeadersList { if (init instanceof HeadersList) { this[kHeadersMap] = new Map(init[kHeadersMap]) this[kHeadersSortedMap] = init[kHeadersSortedMap] - this.cookies = init.cookies + this.cookies = init.cookies === null ? null : [...init.cookies] } else { this[kHeadersMap] = new Map(init) this[kHeadersSortedMap] = null @@ -137,7 +190,7 @@ class HeadersList { // the first such header to value and remove the // others. // 2. Otherwise, append header (name, value) to list. - return this[kHeadersMap].set(lowercaseName, { name, value }) + this[kHeadersMap].set(lowercaseName, { name, value }) } // https://fetch.spec.whatwg.org/#concept-header-list-delete @@ -150,20 +203,18 @@ class HeadersList { this.cookies = null } - return this[kHeadersMap].delete(name) + this[kHeadersMap].delete(name) } // https://fetch.spec.whatwg.org/#concept-header-list-get get (name) { - // 1. If list does not contain name, then return null. - if (!this.contains(name)) { - return null - } + const value = this[kHeadersMap].get(name.toLowerCase()) + // 1. If list does not contain name, then return null. // 2. Return the values of all headers in list whose name // is a byte-case-insensitive match for name, // separated from each other by 0x2C 0x20, in order. - return this[kHeadersMap].get(name.toLowerCase())?.value ?? null + return value === undefined ? null : value.value } * [Symbol.iterator] () { @@ -212,43 +263,7 @@ class Headers { name = webidl.converters.ByteString(name) value = webidl.converters.ByteString(value) - // 1. Normalize value. - value = headerValueNormalize(value) - - // 2. If name is not a header name or value is not a - // header value, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value: name, - type: 'header name' - }) - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value, - type: 'header value' - }) - } - - // 3. If headers’s guard is "immutable", then throw a TypeError. - // 4. Otherwise, if headers’s guard is "request" and name is a - // forbidden header name, return. - // Note: undici does not implement forbidden header names - if (this[kGuard] === 'immutable') { - throw new TypeError('immutable') - } else if (this[kGuard] === 'request-no-cors') { - // 5. Otherwise, if headers’s guard is "request-no-cors": - // TODO - } - - // 6. Otherwise, if headers’s guard is "response" and name is a - // forbidden response-header name, return. - - // 7. Append (name, value) to headers’s header list. - // 8. If headers’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from headers - return this[kHeadersList].append(name, value) + return appendHeader(this, name, value) } // https://fetch.spec.whatwg.org/#dom-headers-delete @@ -293,7 +308,7 @@ class Headers { // 7. Delete name from this’s header list. // 8. If this’s guard is "request-no-cors", then remove // privileged no-CORS request headers from this. - return this[kHeadersList].delete(name) + this[kHeadersList].delete(name) } // https://fetch.spec.whatwg.org/#dom-headers-get @@ -386,7 +401,7 @@ class Headers { // 7. Set (name, value) in this’s header list. // 8. If this’s guard is "request-no-cors", then remove // privileged no-CORS request headers from this - return this[kHeadersList].set(name, value) + this[kHeadersList].set(name, value) } // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie @@ -422,7 +437,8 @@ class Headers { const cookies = this[kHeadersList].cookies // 3. For each name of names: - for (const [name, value] of names) { + for (let i = 0; i < names.length; ++i) { + const [name, value] = names[i] // 1. If name is `set-cookie`, then: if (name === 'set-cookie') { // 1. Let values be a list of all values of headers in list whose name @@ -430,8 +446,8 @@ class Headers { // 2. For each value of values: // 1. Append (name, value) to headers. - for (const value of cookies) { - headers.push([name, value]) + for (let j = 0; j < cookies.length; ++j) { + headers.push([name, cookies[j]]) } } else { // 2. Otherwise: @@ -455,6 +471,12 @@ class Headers { keys () { webidl.brandCheck(this, Headers) + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key') + } + return makeIterator( () => [...this[kHeadersSortedMap].values()], 'Headers', @@ -465,6 +487,12 @@ class Headers { values () { webidl.brandCheck(this, Headers) + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'value') + } + return makeIterator( () => [...this[kHeadersSortedMap].values()], 'Headers', @@ -475,6 +503,12 @@ class Headers { entries () { webidl.brandCheck(this, Headers) + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key+value') + } + return makeIterator( () => [...this[kHeadersSortedMap].values()], 'Headers', diff --git a/deps/undici/src/lib/fetch/index.js b/deps/undici/src/lib/fetch/index.js index 298b3ddb27c04c..c109a01bf1f8e8 100644 --- a/deps/undici/src/lib/fetch/index.js +++ b/deps/undici/src/lib/fetch/index.js @@ -1957,7 +1957,7 @@ async function httpNetworkFetch ( path: url.pathname + url.search, origin: url.origin, method: request.method, - body: fetchParams.controller.dispatcher.isMockActive ? request.body && request.body.source : body, + body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, headers: request.headersList.entries, maxRedirections: 0, upgrade: request.mode === 'websocket' ? 'websocket' : undefined @@ -2002,7 +2002,7 @@ async function httpNetworkFetch ( location = val } - headers.append(key, val) + headers[kHeadersList].append(key, val) } } else { const keys = Object.keys(headersList) @@ -2016,7 +2016,7 @@ async function httpNetworkFetch ( location = val } - headers.append(key, val) + headers[kHeadersList].append(key, val) } } @@ -2120,7 +2120,7 @@ async function httpNetworkFetch ( const key = headersList[n + 0].toString('latin1') const val = headersList[n + 1].toString('latin1') - headers.append(key, val) + headers[kHeadersList].append(key, val) } resolve({ diff --git a/deps/undici/src/lib/fetch/request.js b/deps/undici/src/lib/fetch/request.js index 60e654eca112cd..336d361ce20b16 100644 --- a/deps/undici/src/lib/fetch/request.js +++ b/deps/undici/src/lib/fetch/request.js @@ -316,11 +316,11 @@ class Request { // 2. If method is not a method or method is a forbidden method, then // throw a TypeError. if (!isValidHTTPToken(init.method)) { - throw TypeError(`'${init.method}' is not a valid HTTP method.`) + throw new TypeError(`'${init.method}' is not a valid HTTP method.`) } if (forbiddenMethodsSet.has(method.toUpperCase())) { - throw TypeError(`'${init.method}' HTTP method is unsupported.`) + throw new TypeError(`'${init.method}' HTTP method is unsupported.`) } // 3. Normalize method. diff --git a/deps/undici/src/lib/fetch/util.js b/deps/undici/src/lib/fetch/util.js index 033fa206aedc3e..bc6fd50c68a08c 100644 --- a/deps/undici/src/lib/fetch/util.js +++ b/deps/undici/src/lib/fetch/util.js @@ -103,52 +103,57 @@ function isValidReasonPhrase (statusText) { return true } -function isTokenChar (c) { - return !( - c >= 0x7f || - c <= 0x20 || - c === '(' || - c === ')' || - c === '<' || - c === '>' || - c === '@' || - c === ',' || - c === ';' || - c === ':' || - c === '\\' || - c === '"' || - c === '/' || - c === '[' || - c === ']' || - c === '?' || - c === '=' || - c === '{' || - c === '}' - ) +/** + * @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 + } } -// See RFC 7230, Section 3.2.6. -// https://github.com/chromium/chromium/blob/d7da0240cae77824d1eda25745c4022757499131/third_party/blink/renderer/platform/network/http_parsers.cc#L321 +/** + * @param {string} characters + */ function isValidHTTPToken (characters) { - if (!characters || typeof characters !== 'string') { + if (characters.length === 0) { return false } for (let i = 0; i < characters.length; ++i) { - const c = characters.charCodeAt(i) - if (c > 0x7f || !isTokenChar(c)) { + if (!isTokenCharCode(characters.charCodeAt(i))) { return false } } return true } -// https://fetch.spec.whatwg.org/#header-name -// https://github.com/chromium/chromium/blob/b3d37e6f94f87d59e44662d6078f6a12de845d17/net/http/http_util.cc#L342 +/** + * @see https://fetch.spec.whatwg.org/#header-name + * @param {string} potentialValue + */ function isValidHeaderName (potentialValue) { - if (potentialValue.length === 0) { - return false - } - return isValidHTTPToken(potentialValue) } diff --git a/deps/undici/src/lib/fetch/webidl.js b/deps/undici/src/lib/fetch/webidl.js index 38a05e657594aa..6fcf2ab6ad4c49 100644 --- a/deps/undici/src/lib/fetch/webidl.js +++ b/deps/undici/src/lib/fetch/webidl.js @@ -427,12 +427,10 @@ webidl.converters.ByteString = function (V) { // 2. If the value of any element of x is greater than // 255, then throw a TypeError. for (let index = 0; index < x.length; index++) { - const charCode = x.charCodeAt(index) - - if (charCode > 255) { + if (x.charCodeAt(index) > 255) { throw new TypeError( 'Cannot convert argument to a ByteString because the character at ' + - `index ${index} has a value of ${charCode} which is greater than 255.` + `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` ) } } diff --git a/deps/undici/src/lib/handler/RetryHandler.js b/deps/undici/src/lib/handler/RetryHandler.js new file mode 100644 index 00000000000000..a8112b36ee443e --- /dev/null +++ b/deps/undici/src/lib/handler/RetryHandler.js @@ -0,0 +1,336 @@ +const assert = require('node:assert') + +const { kRetryHandlerDefaultRetry } = require('../core/symbols') +const { RequestRetryError } = require('../core/errors') +const { isDisturbed, parseHeaders, parseRangeHeader } = require('../core/util') + +function calculateRetryAfterHeader (retryAfter) { + const current = Date.now() + const diff = new Date(retryAfter).getTime() - current + + return diff +} + +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 + this.abort = null + this.aborted = false + this.retryOpts = { + retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], + retryAfter: retryAfter ?? true, + maxTimeout: maxTimeout ?? 30 * 1000, // 30s, + timeout: 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' + ] + } + + this.retryCount = 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 + } + }) + } + + onRequestSent () { + if (this.handler.onRequestSent) { + this.handler.onRequestSent() + } + } + + onUpgrade (statusCode, headers, socket) { + if (this.handler.onUpgrade) { + this.handler.onUpgrade(statusCode, headers, socket) + } + } + + onConnect (abort) { + if (this.aborted) { + abort(this.reason) + } else { + this.abort = abort + } + } + + onBodySent (chunk) { + return this.handler.onBodySent(chunk) + } + + static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { + const { statusCode, code, headers } = err + const { method, retryOptions } = opts + const { + maxRetries, + timeout, + maxTimeout, + timeoutFactor, + statusCodes, + errorCodes, + methods + } = retryOptions + let { counter, currentTimeout } = state + + currentTimeout = + currentTimeout != null && currentTimeout > 0 ? currentTimeout : timeout + + // Any code that is not a Undici's originated and allowed to retry + if ( + code && + code !== 'UND_ERR_REQ_RETRY' && + code !== 'UND_ERR_SOCKET' && + !errorCodes.includes(code) + ) { + cb(err) + return + } + + // 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 + } + + // 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 we reached the max number of retries + if (counter > maxRetries) { + cb(err) + return + } + + let retryAfterHeader = headers != null && headers['retry-after'] + if (retryAfterHeader) { + retryAfterHeader = Number(retryAfterHeader) + retryAfterHeader = isNaN(retryAfterHeader) + ? calculateRetryAfterHeader(retryAfterHeader) + : retryAfterHeader * 1e3 // Retry-After is in seconds + } + + const retryTimeout = + retryAfterHeader > 0 + ? Math.min(retryAfterHeader, maxTimeout) + : Math.min(currentTimeout * timeoutFactor ** counter, maxTimeout) + + state.currentTimeout = retryTimeout + + setTimeout(() => cb(null), retryTimeout) + } + + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const headers = parseHeaders(rawHeaders) + + this.retryCount += 1 + + if (statusCode >= 300) { + this.abort( + new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + + // Checkpoint for resume from where we left it + if (this.resume != null) { + this.resume = null + + if (statusCode !== 206) { + return true + } + + const contentRange = parseRangeHeader(headers['content-range']) + // If no content range + if (!contentRange) { + this.abort( + new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + + // Let's start with a weak etag check + if (this.etag != null && this.etag !== headers.etag) { + this.abort( + new RequestRetryError('ETag mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + + const { start, size, end = size } = contentRange + + assert(this.start === start, 'content-range mismatch') + assert(this.end == null || this.end === end, 'content-range mismatch') + + this.resume = resume + return true + } + + if (this.end == null) { + if (statusCode === 206) { + // First time we receive 206 + const range = parseRangeHeader(headers['content-range']) + + if (range == null) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } + + const { start, size, end = size } = range + + assert( + start != null && Number.isFinite(start) && this.start !== start, + 'content-range mismatch' + ) + assert(Number.isFinite(start)) + assert( + end != null && Number.isFinite(end) && this.end !== end, + 'invalid content-length' + ) + + this.start = start + this.end = end + } + + // 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) : null + } + + assert(Number.isFinite(this.start)) + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ) + + this.resume = resume + this.etag = headers.etag != null ? headers.etag : null + + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } + + const err = new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + + this.abort(err) + + return false + } + + onData (chunk) { + this.start += chunk.length + + return this.handler.onData(chunk) + } + + onComplete (rawTrailers) { + this.retryCount = 0 + return this.handler.onComplete(rawTrailers) + } + + onError (err) { + if (this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } + + this.retryOpts.retry( + err, + { + state: { counter: this.retryCount++, currentTimeout: this.retryAfter }, + opts: { retryOptions: this.retryOpts, ...this.opts } + }, + onRetry.bind(this) + ) + + function onRetry (err) { + if (err != null || this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } + + if (this.start !== 0) { + this.opts = { + ...this.opts, + headers: { + ...this.opts.headers, + range: `bytes=${this.start}-${this.end ?? ''}` + } + } + } + + try { + this.dispatch(this.opts, this) + } catch (err) { + this.handler.onError(err) + } + } + } +} + +module.exports = RetryHandler diff --git a/deps/undici/src/package-lock.json b/deps/undici/src/package-lock.json index faba8557bd37ed..d3360f32b9f9a4 100644 --- a/deps/undici/src/package-lock.json +++ b/deps/undici/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "undici", - "version": "5.27.2", + "version": "5.28.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "undici", - "version": "5.27.2", + "version": "5.28.0", "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" @@ -34,6 +34,7 @@ "jsdom": "^22.1.0", "jsfuzz": "^1.0.15", "mocha": "^10.0.0", + "mockttp": "^3.9.2", "p-timeout": "^3.2.0", "pre-commit": "^1.2.2", "proxy": "^1.0.2", @@ -82,12 +83,12 @@ "dev": true }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -237,12 +238,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", - "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", "dev": true, "dependencies": { - "@babel/types": "^7.23.3", + "@babel/types": "^7.23.4", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -375,9 +376,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -402,23 +403,23 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", - "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0" + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -501,9 +502,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", - "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -690,9 +691,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", + "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -716,19 +717,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", - "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/parser": "^7.23.4", + "@babel/types": "^7.23.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -760,12 +761,12 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", - "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, @@ -910,6 +911,70 @@ "node": ">=14" } }, + "node_modules/@graphql-tools/merge": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz", + "integrity": "sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg==", + "dev": true, + "dependencies": { + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz", + "integrity": "sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==", + "dev": true, + "dependencies": { + "@graphql-tools/merge": "8.3.1", + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/utils": { + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz", + "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -925,6 +990,56 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@httptoolkit/httpolyglot": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@httptoolkit/httpolyglot/-/httpolyglot-2.1.1.tgz", + "integrity": "sha512-TvJOb/9dYmOD1U8sErFKCy5BxQc7kbLuvvRLfsTr+NN9kQGNGRNyenC00mJxUn2ld/WtxPMNup3JICHPUOPXDg==", + "dev": true, + "dependencies": { + "@types/node": "^16.7.10" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@httptoolkit/httpolyglot/node_modules/@types/node": { + "version": "16.18.65", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.65.tgz", + "integrity": "sha512-5E9WgTy95B7i90oISjui9U5Zu7iExUPfU4ygtv4yXEy6zJFE3oQYHCnh5H1jZRPkjphJt2Ml3oQW6M0qtK534A==", + "dev": true + }, + "node_modules/@httptoolkit/subscriptions-transport-ws": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@httptoolkit/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.2.tgz", + "integrity": "sha512-YB+gYYVjgYUeJrGkfS91ABeNWCFU7EVcn9Cflf2UXjsIiPJEI6yPxujPcjKv9wIJpM+33KQW/qVEmc+BdIDK2w==", + "dev": true, + "dependencies": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^8.8.0" + }, + "peerDependencies": { + "graphql": "^15.7.2 || ^16.0.0" + } + }, + "node_modules/@httptoolkit/websocket-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@httptoolkit/websocket-stream/-/websocket-stream-6.0.1.tgz", + "integrity": "sha512-A0NOZI+Glp3Xgcz6Na7i7o09+/+xm2m0UCU8gdtM2nIv6/cjLmhMZMqehSpTlgbx9omtLmV8LVqOskPEyWnmZQ==", + "dev": true, + "dependencies": { + "@types/ws": "*", + "duplexify": "^3.5.1", + "inherits": "^2.0.1", + "isomorphic-ws": "^4.0.1", + "readable-stream": "^2.3.3", + "safe-buffer": "^5.1.2", + "ws": "*", + "xtend": "^4.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -1492,6 +1607,12 @@ "node": ">= 10" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, "node_modules/@tsd/typescript": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.2.2.tgz", @@ -1502,9 +1623,9 @@ } }, "node_modules/@types/babel__core": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.4.tgz", - "integrity": "sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", @@ -1542,6 +1663,15 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/escodegen": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.6.tgz", @@ -1634,18 +1764,18 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.18.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.10.tgz", - "integrity": "sha512-luANqZxPmjTll8bduz4ACs/lNTCLuWssCyjqTY9yLdsv1xnViQp3ISKwsEWOIecO13JWUqjVdig/Vjjc09o8uA==", + "version": "18.18.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", + "integrity": "sha512-vXYZGRrSCreZmq1rEjMRLXJhiy8MrIeVasx+PCVlP414N7CJLHnMf+juVvjdprHyH+XRy3zKZLHeNueOpJCn0g==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/node-forge": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.9.tgz", - "integrity": "sha512-meK88cx/sTalPSLSoCzkiUB4VPIFHmxtXm5FaaqRDqBX2i/Sy8bJ4odsan0b20RBjPh06dAQ+OTTdnyQyhJZyQ==", + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", "dev": true, "dependencies": { "@types/node": "*" @@ -1663,10 +1793,19 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { - "version": "17.0.31", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.31.tgz", - "integrity": "sha512-bocYSx4DI8TmdlvxqGpVNXOgCNR1Jj0gNPhhAY+iz1rgKDAaYrAYdFYnhDV1IFuiuVc9HkOwyDcFxaTElF3/wg==", + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -1702,6 +1841,19 @@ "node": ">=6.5" } }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", @@ -2010,6 +2162,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, "node_modules/array-includes": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", @@ -2145,6 +2303,18 @@ "node": "*" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -2154,6 +2324,15 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/async-hook-domain": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.4.tgz", @@ -2326,12 +2505,27 @@ "@babel/core": "^7.0.0" } }, + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", + "dev": true + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha512-437oANT9tP582zZMwSvZGy2nmSeAb8DW2me3y+Uv1Wp2Rulr8Mqlyrv3E7MLxmsiaPSMMDmiDVzgE+e8zlMx9g==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2358,6 +2552,15 @@ "integrity": "sha512-Y7OBvWn+JnW45JWHLY6ybYub2k9cXCMrtCyO1Hds2s6eqClqWhPnOQpgXUPjAiMHj+A8TEPIQQ1dYENnJoBOHQ==", "dev": true }, + "node_modules/basic-ftp": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", + "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2376,6 +2579,42 @@ "node": ">=10" } }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", @@ -2454,6 +2693,12 @@ "node": ">=8" } }, + "node_modules/brotli-wasm": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/brotli-wasm/-/brotli-wasm-1.3.1.tgz", + "integrity": "sha512-Vp+v3QXddvy39Ycbmvd3/Y1kUvKhwtnprzeABcKWN4jmyg6W3W5MhGPCfXBMHeSQnizgpV59iWmkSRp7ykOnDQ==", + "dev": true + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -2516,6 +2761,24 @@ "semver": "^7.0.0" } }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", + "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -2601,6 +2864,15 @@ "node": ">=6" } }, + "node_modules/caching-transform/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/caching-transform/node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -2670,10 +2942,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-keys/node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001563", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz", - "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==", + "version": "1.0.30001564", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", + "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", "dev": true, "funding": [ { @@ -2937,6 +3218,15 @@ "node": ">= 0.8" } }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -2964,42 +3254,6 @@ "typedarray": "^0.0.6" } }, - "node_modules/concat-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/concurrently": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", @@ -3089,18 +3343,73 @@ "node": "*" } }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cors-gate": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cors-gate/-/cors-gate-1.1.3.tgz", + "integrity": "sha512-RFqvbbpj02lqKDhqasBEkgzmT3RseCH3DKy5sT2W9S1mhctABKQP3ktKcnKN0h8t4pJ2SneI3hPl3TGNi/VmZA==", + "dev": true + }, "node_modules/cp-file": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", @@ -3151,6 +3460,15 @@ "node": ">= 18.18.0" } }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3186,6 +3504,15 @@ "node": ">=14" } }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", + "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/data-urls": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", @@ -3405,6 +3732,50 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/degenerator/node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/degenerator/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", @@ -3445,6 +3816,18 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/destroyable-server": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/destroyable-server/-/destroyable-server-1.0.0.tgz", + "integrity": "sha512-78rUr9j0b4bRWO0eBtqKqmb43htBwNbofRRukpo+R7PZqHD6llb7aQoNVt81U9NQGhINRKBHz7lkrxZJj9vyog==", + "dev": true, + "dependencies": { + "@types/node": "*" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -3791,6 +4174,18 @@ "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", "dev": true }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -3798,9 +4193,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.588", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.588.tgz", - "integrity": "sha512-soytjxwbgcCu7nh5Pf4S2/4wa6UIu+A3p03U2yVr53qGxi1/VTR3ENI+p50v+UxqqZAfl48j3z55ud7VHIOr9w==", + "version": "1.4.594", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz", + "integrity": "sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==", "dev": true }, "node_modules/emittery": { @@ -4819,6 +5214,12 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "dev": true + }, "node_modules/events-to-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", @@ -4873,6 +5274,126 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5080,6 +5601,15 @@ "node": ">=4" } }, + "node_modules/find-cache-dir/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/find-cache-dir/node_modules/pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -5268,6 +5798,15 @@ "node": ">= 12.20" } }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -5462,26 +6001,64 @@ "engines": { "node": ">=10" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-uri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", + "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", + "dev": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.0", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/get-uri/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "ms": "2.1.2" }, "engines": { - "node": ">= 0.4" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, + "node_modules/get-uri/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5631,6 +6208,54 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/graphql-http": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/graphql-http/-/graphql-http-1.22.0.tgz", + "integrity": "sha512-9RBUlGJWBFqz9LwfpmAbjJL/8j/HCNkZwPBU5+Bfmwez+1Ay43DocMNQYpIWsWqH0Ftv6PTNAh2aRnnMCBJgLw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "graphql": ">=0.11 <=16" + } + }, + "node_modules/graphql-subscriptions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz", + "integrity": "sha512-95yD/tKi24q8xYa7Q9rhQN16AYj5wPbrb8tmHGM3WRc9EBmWrG/0kkMl+tQG8wcEuE9ibR4zyOM31p5Sdr2v4g==", + "dev": true, + "dependencies": { + "iterall": "^1.3.0" + }, + "peerDependencies": { + "graphql": "^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -5849,6 +6474,17 @@ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, + "node_modules/http-encoding": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/http-encoding/-/http-encoding-1.5.1.tgz", + "integrity": "sha512-2m4JnG1Z5RX5pRMdccyp6rX1jVo4LO+ussQzWdwR4AmrWhtX0KP1NyslVAFAspQwMxt2P00CCWXIBKj7ILZLpQ==", + "dev": true, + "dependencies": { + "brotli-wasm": "^1.1.0", + "pify": "^5.0.0", + "zstd-codec": "^0.1.4" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -5911,6 +6547,19 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-pem": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/https-pem/-/https-pem-3.0.0.tgz", @@ -5982,12 +6631,12 @@ } }, "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" @@ -6106,6 +6755,21 @@ "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ==", "dev": true }, + "node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/irregular-plurals": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", @@ -6612,9 +7276,9 @@ "dev": true }, "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "node_modules/isexe": { @@ -6623,6 +7287,15 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "dev": true, + "peerDependencies": { + "ws": "*" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -6692,15 +7365,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/istanbul-lib-processinfo/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -6792,6 +7456,12 @@ "node": ">=8" } }, + "node_modules/iterall": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", + "dev": true + }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -7914,6 +8584,15 @@ "node": ">=4" } }, + "node_modules/load-json-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/load-json-file/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -8086,6 +8765,15 @@ "node": ">= 8.16.2" } }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/medium-zoom": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.1.0.tgz", @@ -8131,13 +8819,10 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true }, "node_modules/merge-source-map": { "version": "1.1.0", @@ -8163,6 +8848,15 @@ "node": ">= 8" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -8514,6 +9208,68 @@ "node": ">=10" } }, + "node_modules/mockttp": { + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/mockttp/-/mockttp-3.9.4.tgz", + "integrity": "sha512-EagdyT83RqAKWB2c+g3NdL1hEBcXl4Oeg6zIWDk9mq6JCAqsaIHySE78lvgGja2QjWOgosQaS1YtCaWkKaCFkw==", + "dev": true, + "dependencies": { + "@graphql-tools/schema": "^8.5.0", + "@graphql-tools/utils": "^8.8.0", + "@httptoolkit/httpolyglot": "^2.1.1", + "@httptoolkit/subscriptions-transport-ws": "^0.11.2", + "@httptoolkit/websocket-stream": "^6.0.1", + "@types/cors": "^2.8.6", + "@types/node": "*", + "base64-arraybuffer": "^0.1.5", + "body-parser": "^1.15.2", + "cacheable-lookup": "^6.0.0", + "common-tags": "^1.8.0", + "connect": "^3.7.0", + "cors": "^2.8.4", + "cors-gate": "^1.1.3", + "cross-fetch": "^3.1.5", + "destroyable-server": "^1.0.0", + "express": "^4.14.0", + "graphql": "^14.0.2 || ^15.5", + "graphql-http": "^1.22.0", + "graphql-subscriptions": "^1.1.0", + "graphql-tag": "^2.12.6", + "http-encoding": "^1.5.1", + "http2-wrapper": "^2.2.0", + "https-proxy-agent": "^5.0.1", + "isomorphic-ws": "^4.0.1", + "lodash": "^4.16.4", + "lru-cache": "^7.14.0", + "native-duplexpair": "^1.0.0", + "node-forge": "^1.2.1", + "pac-proxy-agent": "^7.0.0", + "parse-multipart-data": "^1.4.0", + "performance-now": "^2.1.0", + "portfinder": "1.0.28", + "read-tls-client-hello": "^1.0.0", + "semver": "^7.5.3", + "socks-proxy-agent": "^7.0.0", + "typed-error": "^3.0.2", + "uuid": "^8.3.2", + "ws": "^8.8.0" + }, + "bin": { + "mockttp": "dist/admin/admin-bin.js" + }, + "engines": { + "node": ">=14.14.0" + } + }, + "node_modules/mockttp/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/module-not-found-error": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", @@ -8547,18 +9303,42 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/native-duplexpair": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/native-duplexpair/-/native-duplexpair-1.0.0.tgz", + "integrity": "sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA==", + "dev": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/nested-error-stacks": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", "dev": true }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/nise": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", @@ -8599,6 +9379,21 @@ "type-detect": "4.0.8" } }, + "node_modules/nise/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -9136,6 +9931,15 @@ "node": ">=4" } }, + "node_modules/nyc/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/nyc/node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -9234,6 +10038,16 @@ "node": ">=6" } }, + "node_modules/nyc/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/nyc/node_modules/wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", @@ -9646,6 +10460,114 @@ "node": ">=6" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dev": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/pac-proxy-agent/node_modules/socks-proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", + "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "dev": true, + "dependencies": { + "degenerator": "^5.0.0", + "ip": "^1.1.8", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", @@ -9730,6 +10652,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-multipart-data": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/parse-multipart-data/-/parse-multipart-data-1.5.0.tgz", + "integrity": "sha512-ck5zaMF0ydjGfejNMnlo5YU2oJ+pT+80Jb1y4ybanT27j+zbVP/jkYmCrUGsEln0Ox/hZmuvgy8Ra7AxbXP2Mw==", + "dev": true + }, "node_modules/parse5": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", @@ -9785,13 +10713,10 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "dependencies": { - "isarray": "0.0.1" - } + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", @@ -9811,6 +10736,12 @@ "node": "*" } }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -9842,12 +10773,15 @@ } }, "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pirates": { @@ -9960,6 +10894,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/portfinder/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/pre-commit": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", @@ -10147,6 +11110,19 @@ "proxy": "bin/proxy.js" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -10246,6 +11222,21 @@ } ] }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -10273,12 +11264,15 @@ ] }, "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/randombytes": { @@ -10299,6 +11293,21 @@ "node": ">= 0.6" } }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -10406,20 +11415,39 @@ "node": ">=8" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/read-tls-client-hello": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-tls-client-hello/-/read-tls-client-hello-1.0.1.tgz", + "integrity": "sha512-OvSzfVv6Y656ekUxB7aDhWkLW7y1ck16ChfLFNJhKNADFNweH2fvyiEZkGmmdtXbOtlNuH2zVXZoFCW349M+GA==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "@types/node": "*" }, "engines": { - "node": ">= 6" + "node": ">=12.0.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -10589,6 +11617,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -11092,6 +12126,16 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/snazzy": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-9.0.0.tgz", @@ -11124,6 +12168,77 @@ "snazzy": "bin/cmd.js" } }, + "node_modules/snazzy/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dev": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socks-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/socks/node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -11338,6 +12453,20 @@ "typedarray": "^0.0.6" } }, + "node_modules/standard-json/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -11347,15 +12476,27 @@ "node": ">= 0.6" } }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { - "safe-buffer": "~5.2.0" + "safe-buffer": "~5.1.0" } }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -11554,6 +12695,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -14209,6 +15359,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typed-array-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", @@ -14274,6 +15437,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-error": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/typed-error/-/typed-error-3.2.2.tgz", + "integrity": "sha512-Z48LU67/qJ+vyA7lh3ozELqpTp3pvQoY5RtLi5wQ/UGSrEidBhlVSqhjr8B3iqbGpjqAoJYrtSYXWMDtidWGkA==", + "dev": true, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.0.0" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -14290,9 +15463,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", + "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -14491,19 +15664,18 @@ } }, "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/v8-to-istanbul": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", - "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -14524,6 +15696,24 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/value-or-promise": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", + "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/version-guard": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/version-guard/-/version-guard-1.1.1.tgz", @@ -14603,6 +15793,18 @@ "node": ">=12" } }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", @@ -14836,6 +16038,15 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -15044,6 +16255,12 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zstd-codec": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/zstd-codec/-/zstd-codec-0.1.4.tgz", + "integrity": "sha512-KYnWoFWgGtWyQEKNnUcb3u8ZtKO8dn5d8u+oGpxPlopqsPyv60U8suDyfk7Z7UtAO6Sk5i1aVcAs9RbaB1n36A==", + "dev": true } } } diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json index ea1228f94b92f8..a4d2d622737b58 100644 --- a/deps/undici/src/package.json +++ b/deps/undici/src/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "5.27.2", + "version": "5.28.0", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { @@ -118,6 +118,7 @@ "jsdom": "^22.1.0", "jsfuzz": "^1.0.15", "mocha": "^10.0.0", + "mockttp": "^3.9.2", "p-timeout": "^3.2.0", "pre-commit": "^1.2.2", "proxy": "^1.0.2", diff --git a/deps/undici/src/types/client.d.ts b/deps/undici/src/types/client.d.ts index 74948b15f3841f..56e78cc9765bf2 100644 --- a/deps/undici/src/types/client.d.ts +++ b/deps/undici/src/types/client.d.ts @@ -77,7 +77,7 @@ export declare namespace Client { */ allowH2?: boolean; /** - * @description Dictates the maximum number of concurrent streams for a single H2 session. It can be overriden by a SETTINGS remote frame. + * @description Dictates the maximum number of concurrent streams for a single H2 session. It can be overridden by a SETTINGS remote frame. * @default 100 */ maxConcurrentStreams?: number diff --git a/deps/undici/src/types/dispatcher.d.ts b/deps/undici/src/types/dispatcher.d.ts index 816db19d20d878..efc53eea79114e 100644 --- a/deps/undici/src/types/dispatcher.d.ts +++ b/deps/undici/src/types/dispatcher.d.ts @@ -211,7 +211,7 @@ declare namespace Dispatcher { /** Invoked when request is upgraded either due to a `Upgrade` header or `CONNECT` method. */ onUpgrade?(statusCode: number, headers: Buffer[] | string[] | null, socket: Duplex): void; /** Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. */ - onHeaders?(statusCode: number, headers: Buffer[] | string[] | null, resume: () => void): boolean; + onHeaders?(statusCode: number, headers: Buffer[] | string[] | null, resume: () => void, statusText: string): boolean; /** Invoked when response payload data is received. */ onData?(chunk: Buffer): boolean; /** Invoked when response payload and trailers have been received and the request has completed. */ diff --git a/deps/undici/src/types/index.d.ts b/deps/undici/src/types/index.d.ts index 4589845b4a9bd2..0ea8bdc217dbc5 100644 --- a/deps/undici/src/types/index.d.ts +++ b/deps/undici/src/types/index.d.ts @@ -14,6 +14,7 @@ import MockPool from'./mock-pool' import MockAgent from'./mock-agent' import mockErrors from'./mock-errors' import ProxyAgent from'./proxy-agent' +import RetryHandler from'./retry-handler' import { request, pipeline, stream, connect, upgrade } from './api' export * from './cookies' @@ -27,7 +28,7 @@ export * from './content-type' export * from './cache' export { Interceptable } from './mock-interceptor' -export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, setGlobalOrigin, getGlobalOrigin, MockClient, MockPool, MockAgent, mockErrors, ProxyAgent, RedirectHandler, DecoratorHandler } +export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, setGlobalOrigin, getGlobalOrigin, MockClient, MockPool, MockAgent, mockErrors, ProxyAgent, RedirectHandler, DecoratorHandler, RetryHandler } export default Undici declare namespace Undici { @@ -35,6 +36,7 @@ declare namespace Undici { var Pool: typeof import('./pool').default; var RedirectHandler: typeof import ('./handlers').RedirectHandler var DecoratorHandler: typeof import ('./handlers').DecoratorHandler + var RetryHandler: typeof import ('./retry-handler').default var createRedirectInterceptor: typeof import ('./interceptors').createRedirectInterceptor var BalancedPool: typeof import('./balanced-pool').default; var Client: typeof import('./client').default; diff --git a/deps/undici/src/types/retry-handler.d.ts b/deps/undici/src/types/retry-handler.d.ts new file mode 100644 index 00000000000000..0528eb442799cc --- /dev/null +++ b/deps/undici/src/types/retry-handler.d.ts @@ -0,0 +1,116 @@ +import Dispatcher from "./dispatcher"; + +export default RetryHandler; + +declare class RetryHandler implements Dispatcher.DispatchHandlers { + constructor( + options: Dispatcher.DispatchOptions & { + retryOptions?: RetryHandler.RetryOptions; + }, + retryHandlers: RetryHandler.RetryHandlers + ); +} + +declare namespace RetryHandler { + export type RetryState = { counter: number; currentTimeout: number }; + + export type RetryContext = { + state: RetryState; + opts: Dispatcher.DispatchOptions & { + retryOptions?: RetryHandler.RetryOptions; + }; + } + + export type OnRetryCallback = (result?: Error | null) => void; + + export type RetryCallback = ( + err: Error, + context: { + state: RetryState; + opts: Dispatcher.DispatchOptions & { + retryOptions?: RetryHandler.RetryOptions; + }; + }, + callback: OnRetryCallback + ) => number | null; + + export interface RetryOptions { + /** + * Callback to be invoked on every retry iteration. + * It receives the error, current state of the retry object and the options object + * passed when instantiating the retry handler. + * + * @type {RetryCallback} + * @memberof RetryOptions + */ + retry?: RetryCallback; + /** + * Maximum number of retries to allow. + * + * @type {number} + * @memberof RetryOptions + * @default 5 + */ + maxRetries?: number; + /** + * Max number of milliseconds allow between retries + * + * @type {number} + * @memberof RetryOptions + * @default 30000 + */ + maxTimeout?: number; + /** + * Initial number of milliseconds to wait before retrying for the first time. + * + * @type {number} + * @memberof RetryOptions + * @default 500 + */ + minTimeout?: number; + /** + * Factior to multiply the timeout factor between retries. + * + * @type {number} + * @memberof RetryOptions + * @default 2 + */ + timeoutFactor?: number; + /** + * It enables to automatically infer timeout between retries based on the `Retry-After` header. + * + * @type {boolean} + * @memberof RetryOptions + * @default true + */ + retryAfter?: boolean; + /** + * HTTP methods to retry. + * + * @type {Dispatcher.HttpMethod[]} + * @memberof RetryOptions + * @default ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], + */ + methods?: Dispatcher.HttpMethod[]; + /** + * Error codes to be retried. e.g. `ECONNRESET`, `ENOTFOUND`, `ETIMEDOUT`, `ECONNREFUSED`, etc. + * + * @type {string[]} + * @default ['ECONNRESET','ECONNREFUSED','ENOTFOUND','ENETDOWN','ENETUNREACH','EHOSTDOWN','EHOSTUNREACH','EPIPE'] + */ + errorCodes?: string[]; + /** + * HTTP status codes to be retried. + * + * @type {number[]} + * @memberof RetryOptions + * @default [500, 502, 503, 504, 429], + */ + statusCodes?: number[]; + } + + export interface RetryHandlers { + dispatch: Dispatcher["dispatch"]; + handler: Dispatcher.DispatchHandlers; + } +} diff --git a/deps/undici/undici.js b/deps/undici/undici.js index 320fcb7cefddeb..7b762bbe0b0a3a 100644 --- a/deps/undici/undici.js +++ b/deps/undici/undici.js @@ -68,7 +68,8 @@ var require_symbols = __commonJS({ kHTTP2BuildRequest: Symbol("http2 build request"), kHTTP1BuildRequest: Symbol("http1 build request"), kHTTP2CopyHeaders: Symbol("http2 copy headers"), - kHTTPConnVersion: Symbol("http connection version") + kHTTPConnVersion: Symbol("http connection version"), + kRetryHandlerDefaultRetry: Symbol("retry agent default retry") }; } }); @@ -323,6 +324,21 @@ var require_errors = __commonJS({ this.code = "UND_ERR_RES_EXCEEDED_MAX_SIZE"; } }; + var RequestRetryError = class _RequestRetryError extends UndiciError { + static { + __name(this, "RequestRetryError"); + } + constructor(message, code, { headers, data }) { + super(message); + Error.captureStackTrace(this, _RequestRetryError); + this.name = "RequestRetryError"; + this.message = message || "Request retry error"; + this.code = "UND_ERR_REQ_RETRY"; + this.statusCode = code; + this.data = data; + this.headers = headers; + } + }; module2.exports = { HTTPParserError, UndiciError, @@ -342,7 +358,8 @@ var require_errors = __commonJS({ NotSupportedError, ResponseContentLengthMismatchError, BalancedPoolMissingUpstreamError, - ResponseExceededMaxSizeError + ResponseExceededMaxSizeError, + RequestRetryError }; } }); @@ -439,12 +456,12 @@ var require_util = __commonJS({ if (host[0] === "[") { const idx2 = host.indexOf("]"); assert(idx2 !== -1); - return host.substr(1, idx2 - 1); + return host.substring(1, idx2); } const idx = host.indexOf(":"); if (idx === -1) return host; - return host.substr(0, idx); + return host.substring(0, idx); } __name(getHostname, "getHostname"); function getServerName(host) { @@ -527,7 +544,7 @@ var require_util = __commonJS({ let val = obj[key]; if (!val) { if (Array.isArray(headers[i + 1])) { - obj[key] = headers[i + 1]; + obj[key] = headers[i + 1].map((x) => x.toString("utf8")); } else { obj[key] = headers[i + 1].toString("utf8"); } @@ -689,16 +706,7 @@ var require_util = __commonJS({ } } __name(throwIfAborted, "throwIfAborted"); - var events; function addAbortListener(signal, listener) { - if (typeof Symbol.dispose === "symbol") { - if (!events) { - events = require("events"); - } - if (typeof events.addAbortListener === "function" && "aborted" in signal) { - return events.addAbortListener(signal, listener); - } - } if ("addEventListener" in signal) { signal.addEventListener("abort", listener, { once: true }); return () => signal.removeEventListener("abort", listener); @@ -717,6 +725,17 @@ var require_util = __commonJS({ return `${val}`; } __name(toUSVString, "toUSVString"); + function parseRangeHeader(range) { + if (range == null || range === "") + return { start: 0, end: null, size: null }; + 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; + } + __name(parseRangeHeader, "parseRangeHeader"); var kEnumerableProperty = /* @__PURE__ */ Object.create(null); kEnumerableProperty.enumerable = true; module2.exports = { @@ -749,9 +768,11 @@ var require_util = __commonJS({ buildURL, throwIfAborted, addAbortListener, + parseRangeHeader, nodeMajor, nodeMinor, - nodeHasAutoSelectFamily: nodeMajor > 18 || nodeMajor === 18 && nodeMinor >= 13 + nodeHasAutoSelectFamily: nodeMajor > 18 || nodeMajor === 18 && nodeMinor >= 13, + safeHTTPMethods: ["GET", "HEAD", "OPTIONS", "TRACE"] }; } }); @@ -1056,17 +1077,37 @@ var require_util2 = __commonJS({ return true; } __name(isValidReasonPhrase, "isValidReasonPhrase"); - function isTokenChar(c) { - return !(c >= 127 || c <= 32 || c === "(" || c === ")" || c === "<" || c === ">" || c === "@" || c === "," || c === ";" || c === ":" || c === "\\" || c === '"' || c === "/" || c === "[" || c === "]" || c === "?" || c === "=" || c === "{" || c === "}"); + function isTokenCharCode(c) { + switch (c) { + case 34: + case 40: + case 41: + case 44: + case 47: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 91: + case 92: + case 93: + case 123: + case 125: + return false; + default: + return c >= 33 && c <= 126; + } } - __name(isTokenChar, "isTokenChar"); + __name(isTokenCharCode, "isTokenCharCode"); function isValidHTTPToken(characters) { - if (!characters || typeof characters !== "string") { + if (characters.length === 0) { return false; } for (let i = 0; i < characters.length; ++i) { - const c = characters.charCodeAt(i); - if (c > 127 || !isTokenChar(c)) { + if (!isTokenCharCode(characters.charCodeAt(i))) { return false; } } @@ -1074,9 +1115,6 @@ var require_util2 = __commonJS({ } __name(isValidHTTPToken, "isValidHTTPToken"); function isValidHeaderName(potentialValue) { - if (potentialValue.length === 0) { - return false; - } return isValidHTTPToken(potentialValue); } __name(isValidHeaderName, "isValidHeaderName"); @@ -1829,10 +1867,9 @@ var require_webidl = __commonJS({ webidl.converters.ByteString = function(V) { const x = webidl.converters.DOMString(V); for (let index = 0; index < x.length; index++) { - const charCode = x.charCodeAt(index); - if (charCode > 255) { + if (x.charCodeAt(index) > 255) { throw new TypeError( - `Cannot convert argument to a ByteString because the character at index ${index} has a value of ${charCode} which is greater than 255.` + `Cannot convert argument to a ByteString because the character at index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` ); } } @@ -1953,27 +1990,36 @@ var require_headers = __commonJS({ var assert = require("assert"); var kHeadersMap = Symbol("headers map"); var kHeadersSortedMap = Symbol("headers map sorted"); + function isHTTPWhiteSpaceCharCode(code) { + return code === 10 || code === 13 || code === 9 || code === 32; + } + __name(isHTTPWhiteSpaceCharCode, "isHTTPWhiteSpaceCharCode"); function headerValueNormalize(potentialValue) { - let i = potentialValue.length; - while (/[\r\n\t ]/.test(potentialValue.charAt(--i))) - ; - return potentialValue.slice(0, i + 1).replace(/^[\r\n\t ]+/, ""); + let i = 0; + let j = potentialValue.length; + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) + --j; + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) + ++i; + return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j); } __name(headerValueNormalize, "headerValueNormalize"); function fill(headers, object) { if (Array.isArray(object)) { - for (const header of object) { + for (let i = 0; i < object.length; ++i) { + const header = object[i]; if (header.length !== 2) { throw webidl.errors.exception({ header: "Headers constructor", message: `expected name/value pair to be length 2, found ${header.length}.` }); } - headers.append(header[0], header[1]); + appendHeader(headers, header[0], header[1]); } } else if (typeof object === "object" && object !== null) { - for (const [key, value] of Object.entries(object)) { - headers.append(key, value); + const keys = Object.keys(object); + for (let i = 0; i < keys.length; ++i) { + appendHeader(headers, keys[i], object[keys[i]]); } } else { throw webidl.errors.conversionFailed({ @@ -1984,6 +2030,28 @@ var require_headers = __commonJS({ } } __name(fill, "fill"); + function appendHeader(headers, name, value) { + value = headerValueNormalize(value); + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: "Headers.append", + value: name, + type: "header name" + }); + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: "Headers.append", + value, + type: "header value" + }); + } + if (headers[kGuard] === "immutable") { + throw new TypeError("immutable"); + } else if (headers[kGuard] === "request-no-cors") { + } + return headers[kHeadersList].append(name, value); + } + __name(appendHeader, "appendHeader"); var HeadersList = class _HeadersList { static { __name(this, "HeadersList"); @@ -1994,7 +2062,7 @@ var require_headers = __commonJS({ if (init instanceof _HeadersList) { this[kHeadersMap] = new Map(init[kHeadersMap]); this[kHeadersSortedMap] = init[kHeadersSortedMap]; - this.cookies = init.cookies; + this.cookies = init.cookies === null ? null : [...init.cookies]; } else { this[kHeadersMap] = new Map(init); this[kHeadersSortedMap] = null; @@ -2036,7 +2104,7 @@ var require_headers = __commonJS({ if (lowercaseName === "set-cookie") { this.cookies = [value]; } - return this[kHeadersMap].set(lowercaseName, { name, value }); + this[kHeadersMap].set(lowercaseName, { name, value }); } // https://fetch.spec.whatwg.org/#concept-header-list-delete delete(name) { @@ -2045,14 +2113,12 @@ var require_headers = __commonJS({ if (name === "set-cookie") { this.cookies = null; } - return this[kHeadersMap].delete(name); + this[kHeadersMap].delete(name); } // https://fetch.spec.whatwg.org/#concept-header-list-get get(name) { - if (!this.contains(name)) { - return null; - } - return this[kHeadersMap].get(name.toLowerCase())?.value ?? null; + const value = this[kHeadersMap].get(name.toLowerCase()); + return value === void 0 ? null : value.value; } *[Symbol.iterator]() { for (const [name, { value }] of this[kHeadersMap]) { @@ -2087,25 +2153,7 @@ var require_headers = __commonJS({ webidl.argumentLengthCheck(arguments, 2, { header: "Headers.append" }); name = webidl.converters.ByteString(name); value = webidl.converters.ByteString(value); - value = headerValueNormalize(value); - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: "Headers.append", - value: name, - type: "header name" - }); - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix: "Headers.append", - value, - type: "header value" - }); - } - if (this[kGuard] === "immutable") { - throw new TypeError("immutable"); - } else if (this[kGuard] === "request-no-cors") { - } - return this[kHeadersList].append(name, value); + return appendHeader(this, name, value); } // https://fetch.spec.whatwg.org/#dom-headers-delete delete(name) { @@ -2126,7 +2174,7 @@ var require_headers = __commonJS({ if (!this[kHeadersList].contains(name)) { return; } - return this[kHeadersList].delete(name); + this[kHeadersList].delete(name); } // https://fetch.spec.whatwg.org/#dom-headers-get get(name) { @@ -2180,7 +2228,7 @@ var require_headers = __commonJS({ throw new TypeError("immutable"); } else if (this[kGuard] === "request-no-cors") { } - return this[kHeadersList].set(name, value); + this[kHeadersList].set(name, value); } // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie getSetCookie() { @@ -2199,10 +2247,11 @@ var require_headers = __commonJS({ const headers = []; const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1); const cookies = this[kHeadersList].cookies; - for (const [name, value] of names) { + for (let i = 0; i < names.length; ++i) { + const [name, value] = names[i]; if (name === "set-cookie") { - for (const value2 of cookies) { - headers.push([name, value2]); + for (let j = 0; j < cookies.length; ++j) { + headers.push([name, cookies[j]]); } } else { assert(value !== null); @@ -2214,6 +2263,14 @@ var require_headers = __commonJS({ } keys() { webidl.brandCheck(this, _Headers); + if (this[kGuard] === "immutable") { + const value = this[kHeadersSortedMap]; + return makeIterator( + () => value, + "Headers", + "key" + ); + } return makeIterator( () => [...this[kHeadersSortedMap].values()], "Headers", @@ -2222,6 +2279,14 @@ var require_headers = __commonJS({ } values() { webidl.brandCheck(this, _Headers); + if (this[kGuard] === "immutable") { + const value = this[kHeadersSortedMap]; + return makeIterator( + () => value, + "Headers", + "value" + ); + } return makeIterator( () => [...this[kHeadersSortedMap].values()], "Headers", @@ -2230,6 +2295,14 @@ var require_headers = __commonJS({ } entries() { webidl.brandCheck(this, _Headers); + if (this[kGuard] === "immutable") { + const value = this[kHeadersSortedMap]; + return makeIterator( + () => value, + "Headers", + "key+value" + ); + } return makeIterator( () => [...this[kHeadersSortedMap].values()], "Headers", @@ -5991,10 +6064,10 @@ var require_request = __commonJS({ if (init.method !== void 0) { let method = init.method; if (!isValidHTTPToken(init.method)) { - throw TypeError(`'${init.method}' is not a valid HTTP method.`); + throw new TypeError(`'${init.method}' is not a valid HTTP method.`); } if (forbiddenMethodsSet.has(method.toUpperCase())) { - throw TypeError(`'${init.method}' HTTP method is unsupported.`); + throw new TypeError(`'${init.method}' HTTP method is unsupported.`); } method = normalizeMethod(init.method); request.method = method; @@ -7132,11 +7205,7 @@ var require_request2 = __commonJS({ } onBodySent(chunk) { if (this[kHandler].onBodySent) { - try { - this[kHandler].onBodySent(chunk); - } catch (err) { - this.onError(err); - } + return this[kHandler].onBodySent(chunk); } } onRequestSent() { @@ -7144,11 +7213,7 @@ var require_request2 = __commonJS({ channels.bodySent.publish({ request: this }); } if (this[kHandler].onRequestSent) { - try { - this[kHandler].onRequestSent(); - } catch (err) { - this.onError(err); - } + return this[kHandler].onRequestSent(); } } onConnect(abort) { @@ -8939,7 +9004,7 @@ var require_client = __commonJS({ if (hostname[0] === "[") { const idx = hostname.indexOf("]"); assert(idx !== -1); - const ip = hostname.substr(1, idx - 1); + const ip = hostname.substring(1, idx); assert(net.isIP(ip)); hostname = ip; } @@ -9385,7 +9450,8 @@ upgrade: ${upgrade}\r } ++h2State.openStreams; stream.once("response", (headers2) => { - if (request.onHeaders(Number(headers2[HTTP2_HEADER_STATUS]), headers2, stream.resume.bind(stream), "") === false) { + const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers2; + if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), "") === false) { stream.pause(); } }); @@ -9529,7 +9595,11 @@ upgrade: ${upgrade}\r } }, "onDrain"); const onAbort = /* @__PURE__ */ __name(function() { - onFinished(new RequestAbortedError()); + if (finished) { + return; + } + const err = new RequestAbortedError(); + queueMicrotask(() => onFinished(err)); }, "onAbort"); const onFinished = /* @__PURE__ */ __name(function(err) { if (finished) { @@ -10930,7 +11000,7 @@ var require_fetch = __commonJS({ path: url.pathname + url.search, origin: url.origin, method: request.method, - body: fetchParams.controller.dispatcher.isMockActive ? request.body && request.body.source : body, + body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, headers: request.headersList.entries, maxRedirections: 0, upgrade: request.mode === "websocket" ? "websocket" : void 0 @@ -10963,7 +11033,7 @@ var require_fetch = __commonJS({ } else if (key.toLowerCase() === "location") { location = val; } - headers.append(key, val); + headers[kHeadersList].append(key, val); } } else { const keys = Object.keys(headersList); @@ -10974,7 +11044,7 @@ var require_fetch = __commonJS({ } else if (key.toLowerCase() === "location") { location = val; } - headers.append(key, val); + headers[kHeadersList].append(key, val); } } this.body = new Readable({ read: resume }); @@ -11042,7 +11112,7 @@ var require_fetch = __commonJS({ for (let n = 0; n < headersList.length; n += 2) { const key = headersList[n + 0].toString("latin1"); const val = headersList[n + 1].toString("latin1"); - headers.append(key, val); + headers[kHeadersList].append(key, val); } resolve({ status, diff --git a/doc/contributing/maintaining/maintaining-dependencies.md b/doc/contributing/maintaining/maintaining-dependencies.md index 29d47425ab61ba..00bd3d807def8e 100644 --- a/doc/contributing/maintaining/maintaining-dependencies.md +++ b/doc/contributing/maintaining/maintaining-dependencies.md @@ -28,7 +28,7 @@ This a list of all the dependencies: * [openssl 3.0.8][] * [postject 1.0.0-alpha.6][] * [simdutf 4.0.4][] -* [undici 5.27.2][] +* [undici 5.28.0][] * [uvwasi 0.0.19][] * [V8 11.8.172.12][] * [zlib 1.2.13.1-motley-5daffc7][] @@ -291,7 +291,7 @@ The [postject](https://github.com/nodejs/postject) dependency is used for the The [simdutf](https://github.com/simdutf/simdutf) dependency is a C++ library for fast UTF-8 decoding and encoding. -### undici 5.27.2 +### undici 5.28.0 The [undici](https://github.com/nodejs/undici) dependency is an HTTP/1.1 client, written from scratch for Node.js.. @@ -345,7 +345,7 @@ performance improvements not currently available in standard zlib. [openssl 3.0.8]: #openssl-308 [postject 1.0.0-alpha.6]: #postject-100-alpha6 [simdutf 4.0.4]: #simdutf-404 -[undici 5.27.2]: #undici-5272 +[undici 5.28.0]: #undici-5280 [update-openssl-action]: ../../../.github/workflows/update-openssl.yml [uvwasi 0.0.19]: #uvwasi-0019 [v8 11.8.172.12]: #v8-11817212 diff --git a/src/undici_version.h b/src/undici_version.h index 669a1aef41f1cf..70021854a77888 100644 --- a/src/undici_version.h +++ b/src/undici_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-undici.sh #ifndef SRC_UNDICI_VERSION_H_ #define SRC_UNDICI_VERSION_H_ -#define UNDICI_VERSION "5.27.2" +#define UNDICI_VERSION "5.28.0" #endif // SRC_UNDICI_VERSION_H_ From 246cf73631813f8ffd328067c87afbac0ffb069c Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Wed, 29 Nov 2023 11:00:57 -0500 Subject: [PATCH 16/38] lib,src: replace toUSVString with `toWellFormed()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/47342 Reviewed-By: Michaël Zasso Reviewed-By: James M Snell Reviewed-By: Matteo Collina Reviewed-By: Chengzhong Wu --- benchmark/url/usvstring.js | 27 ------------------- benchmark/util/to-usv-string.js | 21 --------------- lib/internal/file.js | 4 +-- lib/internal/url.js | 45 ++++++++++++++++--------------- lib/internal/util.js | 14 ---------- lib/util.js | 6 +++-- src/node_util.cc | 40 --------------------------- typings/internalBinding/util.d.ts | 1 - typings/primordials.d.ts | 1 + 9 files changed, 31 insertions(+), 128 deletions(-) delete mode 100644 benchmark/url/usvstring.js delete mode 100644 benchmark/util/to-usv-string.js diff --git a/benchmark/url/usvstring.js b/benchmark/url/usvstring.js deleted file mode 100644 index 93a50846fb999f..00000000000000 --- a/benchmark/url/usvstring.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; -const common = require('../common.js'); - -const inputs = { - valid: 'adsfadsfadsf', - validsurr: '\uda23\ude23\uda1f\udfaa\ud800\udfff\uda23\ude23\uda1f\udfaa' + - '\ud800\udfff', - someinvalid: 'asasfdfasd\uda23', - allinvalid: '\udc45\uda23 \udf00\udc00 \udfaa\uda12 \udc00\udfaa', - nonstring: { toString() { return 'asdf'; } }, -}; -const bench = common.createBenchmark(main, { - input: Object.keys(inputs), - n: [5e7], -}, { - flags: ['--expose-internals'], -}); - -function main({ input, n }) { - const { toUSVString } = require('internal/url'); - const str = inputs[input]; - - bench.start(); - for (let i = 0; i < n; i++) - toUSVString(str); - bench.end(n); -} diff --git a/benchmark/util/to-usv-string.js b/benchmark/util/to-usv-string.js deleted file mode 100644 index 22d23d3198d124..00000000000000 --- a/benchmark/util/to-usv-string.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -const common = require('../common'); - -const BASE = 'string\ud801'; - -const bench = common.createBenchmark(main, { - n: [1e5], - size: [10, 100, 500], -}); - -function main({ n, size }) { - const { toUSVString } = require('util'); - const str = BASE.repeat(size); - - bench.start(); - for (let i = 0; i < n; i++) { - toUSVString(str); - } - bench.end(n); -} diff --git a/lib/internal/file.js b/lib/internal/file.js index 1fc08c45a90f33..e35eb7bf70931f 100644 --- a/lib/internal/file.js +++ b/lib/internal/file.js @@ -4,6 +4,7 @@ const { DateNow, NumberIsNaN, ObjectDefineProperties, + StringPrototypeToWellFormed, SymbolToStringTag, } = primordials; @@ -15,7 +16,6 @@ const { customInspectSymbol: kInspect, kEnumerableProperty, kEmptyObject, - toUSVString, } = require('internal/util'); const { @@ -55,7 +55,7 @@ class File extends Blob { lastModified = DateNow(); } - this.#name = toUSVString(fileName); + this.#name = StringPrototypeToWellFormed(`${fileName}`); this.#lastModified = lastModified; } diff --git a/lib/internal/url.js b/lib/internal/url.js index ca41c48582b19d..cdd192daad96d7 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -26,6 +26,7 @@ const { StringPrototypeIndexOf, StringPrototypeSlice, StringPrototypeStartsWith, + StringPrototypeToWellFormed, Symbol, SymbolIterator, SymbolToStringTag, @@ -42,7 +43,6 @@ const { const { getConstructorOf, removeColors, - toUSVString, kEnumerableProperty, SideEffectFreeRegExpPrototypeSymbolReplace, } = require('internal/util'); @@ -366,7 +366,11 @@ class URLSearchParams { throw new ERR_INVALID_TUPLE('Each query pair', '[name, value]'); } // Append (innerSequence[0], innerSequence[1]) to querys list. - ArrayPrototypePush(this.#searchParams, toUSVString(pair[0]), toUSVString(pair[1])); + ArrayPrototypePush( + this.#searchParams, + StringPrototypeToWellFormed(`${pair[0]}`), + StringPrototypeToWellFormed(`${pair[1]}`), + ); } else { if (((typeof pair !== 'object' && typeof pair !== 'function') || typeof pair[SymbolIterator] !== 'function')) { @@ -377,7 +381,7 @@ class URLSearchParams { for (const element of pair) { length++; - ArrayPrototypePush(this.#searchParams, toUSVString(element)); + ArrayPrototypePush(this.#searchParams, StringPrototypeToWellFormed(`${element}`)); } // If innerSequence's size is not 2, then throw a TypeError. @@ -395,8 +399,8 @@ class URLSearchParams { const key = keys[i]; const desc = ReflectGetOwnPropertyDescriptor(init, key); if (desc !== undefined && desc.enumerable) { - const typedKey = toUSVString(key); - const typedValue = toUSVString(init[key]); + const typedKey = StringPrototypeToWellFormed(key); + const typedValue = StringPrototypeToWellFormed(`${init[key]}`); // Two different keys may become the same USVString after normalization. // In that case, we retain the later one. Refer to WPT. @@ -413,7 +417,7 @@ class URLSearchParams { } } else { // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams - init = toUSVString(init); + init = StringPrototypeToWellFormed(`${init}`); this.#searchParams = init ? parseParams(init) : []; } } @@ -468,8 +472,8 @@ class URLSearchParams { throw new ERR_MISSING_ARGS('name', 'value'); } - name = toUSVString(name); - value = toUSVString(value); + name = StringPrototypeToWellFormed(`${name}`); + value = StringPrototypeToWellFormed(`${value}`); ArrayPrototypePush(this.#searchParams, name, value); if (this.#context) { this.#context.search = this.toString(); @@ -485,10 +489,10 @@ class URLSearchParams { } const list = this.#searchParams; - name = toUSVString(name); + name = StringPrototypeToWellFormed(`${name}`); if (value !== undefined) { - value = toUSVString(value); + value = StringPrototypeToWellFormed(`${value}`); for (let i = 0; i < list.length;) { if (list[i] === name && list[i + 1] === value) { list.splice(i, 2); @@ -519,7 +523,7 @@ class URLSearchParams { } const list = this.#searchParams; - name = toUSVString(name); + name = StringPrototypeToWellFormed(`${name}`); for (let i = 0; i < list.length; i += 2) { if (list[i] === name) { return list[i + 1]; @@ -538,7 +542,7 @@ class URLSearchParams { const list = this.#searchParams; const values = []; - name = toUSVString(name); + name = StringPrototypeToWellFormed(`${name}`); for (let i = 0; i < list.length; i += 2) { if (list[i] === name) { values.push(list[i + 1]); @@ -556,10 +560,10 @@ class URLSearchParams { } const list = this.#searchParams; - name = toUSVString(name); + name = StringPrototypeToWellFormed(`${name}`); if (value !== undefined) { - value = toUSVString(value); + value = StringPrototypeToWellFormed(`${value}`); } for (let i = 0; i < list.length; i += 2) { @@ -582,8 +586,8 @@ class URLSearchParams { } const list = this.#searchParams; - name = toUSVString(name); - value = toUSVString(value); + name = StringPrototypeToWellFormed(`${name}`); + value = StringPrototypeToWellFormed(`${value}`); // If there are any name-value pairs whose name is `name`, in `list`, set // the value of the first such name-value pair to `value` and remove the @@ -773,7 +777,7 @@ class URL { throw new ERR_MISSING_ARGS('url'); } - // toUSVString is not needed. + // StringPrototypeToWellFormed is not needed. input = `${input}`; if (base !== undefined) { @@ -1006,7 +1010,7 @@ class URL { } set search(value) { - const href = bindingUrl.update(this.#context.href, updateActions.kSearch, toUSVString(value)); + const href = bindingUrl.update(this.#context.href, updateActions.kSearch, StringPrototypeToWellFormed(`${value}`)); if (href) { this.#updateContext(href); } @@ -1297,7 +1301,7 @@ function domainToASCII(domain) { if (arguments.length < 1) throw new ERR_MISSING_ARGS('domain'); - // toUSVString is not needed. + // StringPrototypeToWellFormed is not needed. return bindingUrl.domainToASCII(`${domain}`); } @@ -1305,7 +1309,7 @@ function domainToUnicode(domain) { if (arguments.length < 1) throw new ERR_MISSING_ARGS('domain'); - // toUSVString is not needed. + // StringPrototypeToWellFormed is not needed. return bindingUrl.domainToUnicode(`${domain}`); } @@ -1501,7 +1505,6 @@ function getURLOrigin(url) { } module.exports = { - toUSVString, fileURLToPath, pathToFileURL, toPathIfFileURL, diff --git a/lib/internal/util.js b/lib/internal/util.js index 80ce774a211644..b32c0e8472b320 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -62,7 +62,6 @@ const { decorated_private_symbol, }, sleep: _sleep, - toUSVString: _toUSVString, } = internalBinding('util'); const { isNativeError, isPromise } = internalBinding('types'); const { getOptionValue } = require('internal/options'); @@ -73,18 +72,6 @@ const experimentalWarnings = new SafeSet(); const colorRegExp = /\u001b\[\d\d?m/g; // eslint-disable-line no-control-regex -const unpairedSurrogateRe = - /(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/; -function toUSVString(val) { - const str = `${val}`; - // As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are - // slower than `unpairedSurrogateRe.exec()`. - const match = RegExpPrototypeExec(unpairedSurrogateRe, str); - if (!match) - return str; - return _toUSVString(str, match.index); -} - let uvBinding; function lazyUv() { @@ -913,7 +900,6 @@ module.exports = { sleep, spliceOne, setupCoverageHooks, - toUSVString, removeColors, // Symbol used to customize promisify conversion diff --git a/lib/util.js b/lib/util.js index 9ddb332f866355..633807c6419b83 100644 --- a/lib/util.js +++ b/lib/util.js @@ -44,6 +44,7 @@ const { ObjectValues, ReflectApply, StringPrototypePadStart, + StringPrototypeToWellFormed, } = primordials; const { @@ -75,7 +76,6 @@ const { getSystemErrorMap, getSystemErrorName: internalErrorName, promisify, - toUSVString, defineLazyProperties, } = require('internal/util'); @@ -411,7 +411,9 @@ module.exports = { log, promisify, stripVTControlCharacters, - toUSVString, + toUSVString(input) { + return StringPrototypeToWellFormed(`${input}`); + }, get transferableAbortSignal() { return lazyAbortController().transferableAbortSignal; }, diff --git a/src/node_util.cc b/src/node_util.cc index 9b3ba203a3a8fc..dfdd87d297e1e2 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -37,9 +37,6 @@ using v8::String; using v8::Uint32; using v8::Value; -// Used in ToUSVString(). -constexpr char16_t kUnicodeReplacementCharacter = 0xFFFD; - // If a UTF-16 character is a low/trailing surrogate. CHAR_TEST(16, IsUnicodeTrail, (ch & 0xFC00) == 0xDC00) @@ -240,40 +237,6 @@ static uint32_t FastGuessHandleType(Local receiver, const uint32_t fd) { CFunction fast_guess_handle_type_(CFunction::Make(FastGuessHandleType)); -static void ToUSVString(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - CHECK_GE(args.Length(), 2); - CHECK(args[0]->IsString()); - CHECK(args[1]->IsNumber()); - - TwoByteValue value(env->isolate(), args[0]); - - int64_t start = args[1]->IntegerValue(env->context()).FromJust(); - CHECK_GE(start, 0); - - for (size_t i = start; i < value.length(); i++) { - char16_t c = value[i]; - if (!IsUnicodeSurrogate(c)) { - continue; - } else if (IsUnicodeSurrogateTrail(c) || i == value.length() - 1) { - value[i] = kUnicodeReplacementCharacter; - } else { - char16_t d = value[i + 1]; - if (IsUnicodeTrail(d)) { - i++; - } else { - value[i] = kUnicodeReplacementCharacter; - } - } - } - - args.GetReturnValue().Set( - String::NewFromTwoByte(env->isolate(), - *value, - v8::NewStringType::kNormal, - value.length()).ToLocalChecked()); -} - void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetPromiseDetails); registry->Register(GetProxyDetails); @@ -288,7 +251,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GuessHandleType); registry->Register(FastGuessHandleType); registry->Register(fast_guess_handle_type_.GetTypeInfo()); - registry->Register(ToUSVString); } void Initialize(Local target, @@ -403,8 +365,6 @@ void Initialize(Local target, "guessHandleType", GuessHandleType, &fast_guess_handle_type_); - - SetMethodNoSideEffect(context, target, "toUSVString", ToUSVString); } } // namespace util diff --git a/typings/internalBinding/util.d.ts b/typings/internalBinding/util.d.ts index 1ac9d3a39bbb31..9034b892b26549 100644 --- a/typings/internalBinding/util.d.ts +++ b/typings/internalBinding/util.d.ts @@ -43,5 +43,4 @@ export interface UtilBinding { shouldAbortOnUncaughtToggle: [shouldAbort: 0 | 1]; WeakReference: typeof InternalUtilBinding.WeakReference; guessHandleType(fd: number): 'TCP' | 'TTY' | 'UDP' | 'FILE' | 'PIPE' | 'UNKNOWN'; - toUSVString(str: string, start: number): string; } diff --git a/typings/primordials.d.ts b/typings/primordials.d.ts index ffce093458f2b5..ce6ca86f3e633d 100644 --- a/typings/primordials.d.ts +++ b/typings/primordials.d.ts @@ -420,6 +420,7 @@ declare namespace primordials { export const StringPrototypeToLocaleUpperCase: UncurryThis export const StringPrototypeToLowerCase: UncurryThis export const StringPrototypeToUpperCase: UncurryThis + export const StringPrototypeToWellFormed: UncurryThis export const StringPrototypeValueOf: UncurryThis export const StringPrototypeReplaceAll: UncurryThis export import Symbol = globalThis.Symbol; From b7036f20282ac5582fd14a3c07c36b81bfce3ed9 Mon Sep 17 00:00:00 2001 From: Rafael Gonzaga Date: Wed, 29 Nov 2023 14:03:59 -0300 Subject: [PATCH 17/38] doc: add procedure when CVEs don't get published MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was the workaround provided by HackerOne team PR-URL: https://github.com/nodejs/node/pull/50945 Refs: https://github.com/nodejs/security-wg/issues/1058 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Michael Dawson Reviewed-By: Tobias Nießen --- doc/contributing/security-release-process.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/contributing/security-release-process.md b/doc/contributing/security-release-process.md index 4cd9835a953e94..fa94d25e6fc176 100644 --- a/doc/contributing/security-release-process.md +++ b/doc/contributing/security-release-process.md @@ -200,6 +200,12 @@ out a better way, forward the email you receive to * Request publication of [H1 CVE requests][] * (Check that the "Version Fixed" field in the CVE is correct, and provide links to the release blogs in the "Public Reference" section) + * In case the reporter doesn't accept the disclosure follow this process: + * Remove the original report reference within the reference text box and + insert the public URL you would like to be attached to this CVE. + * Then uncheck the Public Disclosure on HackerOne box at the bottom of the + page. + ![screenshot of HackerOne CVE form](https://github.com/nodejs/node/assets/26234614/e22e4f33-7948-4dd2-952e-2f9166f5568d) * [ ] PR machine-readable JSON descriptions of the vulnerabilities to the [core](https://github.com/nodejs/security-wg/tree/HEAD/vuln/core) From ca10cbb7748eeebe87117792f9d7e7d557859a3a Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Wed, 29 Nov 2023 23:04:09 +0200 Subject: [PATCH 18/38] tools: update lint-md-dependencies to rollup@4.5.2 PR-URL: https://github.com/nodejs/node/pull/50913 Reviewed-By: Moshe Atlow Reviewed-By: Luigi Pinca --- tools/lint-md/package-lock.json | 104 ++++++++++++++++---------------- tools/lint-md/package.json | 2 +- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/tools/lint-md/package-lock.json b/tools/lint-md/package-lock.json index 355fa6fb128c6d..5fafc3b177cd10 100644 --- a/tools/lint-md/package-lock.json +++ b/tools/lint-md/package-lock.json @@ -18,7 +18,7 @@ "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", - "rollup": "^4.5.0", + "rollup": "^4.5.2", "rollup-plugin-cleanup": "^3.2.1" } }, @@ -101,9 +101,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.5.0.tgz", - "integrity": "sha512-OINaBGY+Wc++U0rdr7BLuFClxcoWaVW3vQYqmQq6B3bqQ/2olkaoz+K8+af/Mmka/C2yN5j+L9scBkv4BtKsDA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.5.2.tgz", + "integrity": "sha512-ee7BudTwwrglFYSc3UnqInDDjCLWHKrFmGNi4aK7jlEyg4CyPa1DCMrZfsN1O13YT76UFEqXz2CoN7BCGpUlJw==", "cpu": [ "arm" ], @@ -114,9 +114,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.5.0.tgz", - "integrity": "sha512-UdMf1pOQc4ZmUA/NTmKhgJTBimbSKnhPS2zJqucqFyBRFPnPDtwA8MzrGNTjDeQbIAWfpJVAlxejw+/lQyBK/w==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.5.2.tgz", + "integrity": "sha512-xOuhj9HHtn8128ir8veoQsBbAUBasDbHIBniYTEx02pAmu9EXL+ZjJqngnNEy6ZgZ4h1JwL33GMNu3yJL5Mzow==", "cpu": [ "arm64" ], @@ -127,9 +127,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.5.0.tgz", - "integrity": "sha512-L0/CA5p/idVKI+c9PcAPGorH6CwXn6+J0Ys7Gg1axCbTPgI8MeMlhA6fLM9fK+ssFhqogMHFC8HDvZuetOii7w==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.5.2.tgz", + "integrity": "sha512-NTGJWoL8bKyqyWFn9/RzSv4hQ4wTbaAv0lHHRwf4OnpiiP4P8W0jiXbm8Nc5BCXKmWAwuvJY82mcIU2TayC20g==", "cpu": [ "arm64" ], @@ -140,9 +140,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.5.0.tgz", - "integrity": "sha512-QZCbVqU26mNlLn8zi/XDDquNmvcr4ON5FYAHQQsyhrHx8q+sQi/6xduoznYXwk/KmKIXG5dLfR0CvY+NAWpFYQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.5.2.tgz", + "integrity": "sha512-hlKqj7bpPvU15sZo4za14u185lpMzdwWLMc9raMqPK4wywt0wR23y1CaVQ4oAFXat3b5/gmRntyfpwWTKl+vvA==", "cpu": [ "x64" ], @@ -153,9 +153,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.5.0.tgz", - "integrity": "sha512-VpSQ+xm93AeV33QbYslgf44wc5eJGYfYitlQzAi3OObu9iwrGXEnmu5S3ilkqE3Pr/FkgOiJKV/2p0ewf4Hrtg==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.5.2.tgz", + "integrity": "sha512-7ZIZx8c3u+pfI0ohQsft/GywrXez0uR6dUP0JhBuCK3sFO5TfdLn/YApnVkvPxuTv3+YKPIZend9Mt7Cz6sS3Q==", "cpu": [ "arm" ], @@ -166,9 +166,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.5.0.tgz", - "integrity": "sha512-OrEyIfpxSsMal44JpEVx9AEcGpdBQG1ZuWISAanaQTSMeStBW+oHWwOkoqR54bw3x8heP8gBOyoJiGg+fLY8qQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.5.2.tgz", + "integrity": "sha512-7Pk/5mO11JW/cH+a8lL/i0ZxmRGrbpYqN0VwO2DHhU+SJWWOH2zE1RAcPaj8KqiwC8DCDIJOSxjV9+9lLb6aeA==", "cpu": [ "arm64" ], @@ -179,9 +179,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.5.0.tgz", - "integrity": "sha512-1H7wBbQuE6igQdxMSTjtFfD+DGAudcYWhp106z/9zBA8OQhsJRnemO4XGavdzHpGhRtRxbgmUGdO3YQgrWf2RA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.5.2.tgz", + "integrity": "sha512-KrRnuG5phJx756e62wxvWH2e+TK84MP2IVuPwfge+GBvWqIUfVzFRn09TKruuQBXzZp52Vyma7FjMDkwlA9xpg==", "cpu": [ "arm64" ], @@ -192,9 +192,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.5.0.tgz", - "integrity": "sha512-FVyFI13tXw5aE65sZdBpNjPVIi4Q5mARnL/39UIkxvSgRAIqCo5sCpCELk0JtXHGee2owZz5aNLbWNfBHzr71Q==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.5.2.tgz", + "integrity": "sha512-My+53GasPa2D2tU5dXiyHYwrELAUouSfkNlZ3bUKpI7btaztO5vpALEs3mvFjM7aKTvEbc7GQckuXeXIDKQ0fg==", "cpu": [ "x64" ], @@ -205,9 +205,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.5.0.tgz", - "integrity": "sha512-eBPYl2sLpH/o8qbSz6vPwWlDyThnQjJfcDOGFbNjmjb44XKC1F5dQfakOsADRVrXCNzM6ZsSIPDG5dc6HHLNFg==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.5.2.tgz", + "integrity": "sha512-/f0Q6Sc+Vw54Ws6N8fxaEe4R7at3b8pFyv+O/F2VaQ4hODUJcRUcCBJh6zuqtgQQt7w845VTkGLFgWZkP3tUoQ==", "cpu": [ "x64" ], @@ -218,9 +218,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.5.0.tgz", - "integrity": "sha512-xaOHIfLOZypoQ5U2I6rEaugS4IYtTgP030xzvrBf5js7p9WI9wik07iHmsKaej8Z83ZDxN5GyypfoyKV5O5TJA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.5.2.tgz", + "integrity": "sha512-NCKuuZWLht6zj7s6EIFef4BxCRX1GMr83S2W4HPCA0RnJ4iHE4FS1695q6Ewoa6A9nFjJe1//yUu0kgBU07Edw==", "cpu": [ "arm64" ], @@ -231,9 +231,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.5.0.tgz", - "integrity": "sha512-Al6quztQUrHwcOoU2TuFblUQ5L+/AmPBXFR6dUvyo4nRj2yQRK0WIUaGMF/uwKulvRcXkpHe3k9A8Vf93VDktA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.5.2.tgz", + "integrity": "sha512-J5zL3riR4AOyU/J3M/i4k/zZ8eP1yT+nTmAKztCXJtnI36jYH0eepvob22mAQ/kLwfsK2TB6dbyVY1F8c/0H5A==", "cpu": [ "ia32" ], @@ -244,9 +244,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.5.0.tgz", - "integrity": "sha512-8kdW+brNhI/NzJ4fxDufuJUjepzINqJKLGHuxyAtpPG9bMbn8P5mtaCcbOm0EzLJ+atg+kF9dwg8jpclkVqx5w==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.5.2.tgz", + "integrity": "sha512-pL0RXRHuuGLhvs7ayX/SAHph1hrDPXOM5anyYUQXWJEENxw3nfHkzv8FfVlEVcLyKPAEgDRkd6RKZq2SMqS/yg==", "cpu": [ "x64" ], @@ -5778,9 +5778,9 @@ } }, "node_modules/rollup": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.5.0.tgz", - "integrity": "sha512-41xsWhzxqjMDASCxH5ibw1mXk+3c4TNI2UjKbLxe6iEzrSQnqOzmmK8/3mufCPbzHNJ2e04Fc1ddI35hHy+8zg==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.5.2.tgz", + "integrity": "sha512-CRK1uoROBfkcqrZKyaFcqCcZWNsvJ6yVYZkqTlRocZhO2s5yER6Z3f/QaYtO8RGyloPnmhwgzuPQpNGeK210xQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -5790,18 +5790,18 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.5.0", - "@rollup/rollup-android-arm64": "4.5.0", - "@rollup/rollup-darwin-arm64": "4.5.0", - "@rollup/rollup-darwin-x64": "4.5.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.5.0", - "@rollup/rollup-linux-arm64-gnu": "4.5.0", - "@rollup/rollup-linux-arm64-musl": "4.5.0", - "@rollup/rollup-linux-x64-gnu": "4.5.0", - "@rollup/rollup-linux-x64-musl": "4.5.0", - "@rollup/rollup-win32-arm64-msvc": "4.5.0", - "@rollup/rollup-win32-ia32-msvc": "4.5.0", - "@rollup/rollup-win32-x64-msvc": "4.5.0", + "@rollup/rollup-android-arm-eabi": "4.5.2", + "@rollup/rollup-android-arm64": "4.5.2", + "@rollup/rollup-darwin-arm64": "4.5.2", + "@rollup/rollup-darwin-x64": "4.5.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.5.2", + "@rollup/rollup-linux-arm64-gnu": "4.5.2", + "@rollup/rollup-linux-arm64-musl": "4.5.2", + "@rollup/rollup-linux-x64-gnu": "4.5.2", + "@rollup/rollup-linux-x64-musl": "4.5.2", + "@rollup/rollup-win32-arm64-msvc": "4.5.2", + "@rollup/rollup-win32-ia32-msvc": "4.5.2", + "@rollup/rollup-win32-x64-msvc": "4.5.2", "fsevents": "~2.3.2" } }, diff --git a/tools/lint-md/package.json b/tools/lint-md/package.json index f59b3203f36409..cb5c7fb152778f 100644 --- a/tools/lint-md/package.json +++ b/tools/lint-md/package.json @@ -16,7 +16,7 @@ "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", - "rollup": "^4.5.0", + "rollup": "^4.5.2", "rollup-plugin-cleanup": "^3.2.1" } } From bed1b93f8a403078efbb66fea9666cb3cf2ab67d Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Wed, 29 Nov 2023 23:04:19 +0200 Subject: [PATCH 19/38] meta: move one or more collaborators to emeritus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50931 Reviewed-By: Rafael Gonzaga Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca Reviewed-By: Benjamin Gruenbaum Reviewed-By: Michael Dawson Reviewed-By: Trivikram Kamat Reviewed-By: Tobias Nießen --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f09e1044227a10..8cfddba3b61b56 100644 --- a/README.md +++ b/README.md @@ -367,8 +367,6 @@ For information about the governance of the Node.js project, see **Zeyu "Alex" Yang** <> (he/him) * [iansu](https://github.com/iansu) - **Ian Sutherland** <> -* [JacksonTian](https://github.com/JacksonTian) - - **Jackson Tian** <> * [JakobJingleheimer](https://github.com/JakobJingleheimer) - **Jacob Smith** <> (he/him) * [jasnell](https://github.com/jasnell) - @@ -569,6 +567,8 @@ For information about the governance of the Node.js project, see **Isaac Z. Schlueter** <> * [italoacasas](https://github.com/italoacasas) - **Italo A. Casas** <> (he/him) +* [JacksonTian](https://github.com/JacksonTian) - + **Jackson Tian** <> * [jasongin](https://github.com/jasongin) - **Jason Ginchereau** <> * [jbergstroem](https://github.com/jbergstroem) - From 1cf087dfb3814fc0e2195311a64885b9478a619d Mon Sep 17 00:00:00 2001 From: Deokjin Kim Date: Thu, 30 Nov 2023 22:55:06 +0900 Subject: [PATCH 20/38] lib: refactor to use validateFunction in diagnostics_channel Use validateFunction to remove duplicate implementation. PR-URL: https://github.com/nodejs/node/pull/50955 Reviewed-By: Luigi Pinca Reviewed-By: Antoine du Hamel Reviewed-By: Minwoo Jung --- lib/diagnostics_channel.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/diagnostics_channel.js b/lib/diagnostics_channel.js index 10d35054f56535..4e73b39c451427 100644 --- a/lib/diagnostics_channel.js +++ b/lib/diagnostics_channel.js @@ -381,9 +381,7 @@ class TracingChannel { } const callback = ArrayPrototypeAt(args, position); - if (typeof callback !== 'function') { - throw new ERR_INVALID_ARG_TYPE('callback', ['function'], callback); - } + validateFunction(callback, 'callback'); ArrayPrototypeSplice(args, position, 1, wrappedCallback); return start.runStores(context, () => { From 8e1a70a347b1163d09fe4351f7b4ebc4f6945202 Mon Sep 17 00:00:00 2001 From: Moshe Atlow Date: Thu, 30 Nov 2023 16:04:06 +0200 Subject: [PATCH 21/38] tools: add triggers to update release links workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/50974 Reviewed-By: Michaël Zasso Reviewed-By: Antoine du Hamel --- .github/workflows/update-release-links.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update-release-links.yml b/.github/workflows/update-release-links.yml index fc9e6ad084cd3b..3eaa61260545e8 100644 --- a/.github/workflows/update-release-links.yml +++ b/.github/workflows/update-release-links.yml @@ -1,8 +1,9 @@ name: Update release links on: + workflow_dispatch: release: - types: [published] + types: [released] permissions: contents: read From 6a087ceffa98ced96654d811048881b93aca49c2 Mon Sep 17 00:00:00 2001 From: DylanTet <100033822+DylanTet@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:26:56 -0800 Subject: [PATCH 22/38] url: throw error if argument length of revokeObjectURL is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a check to see if url wasn't included as an argument which will then throw an error. Fixes: https://github.com/nodejs/node/issues/50432 PR-URL: https://github.com/nodejs/node/pull/50433 Reviewed-By: James M Snell Reviewed-By: Vinícius Lourenço Claro Cardoso Reviewed-By: Luigi Pinca Reviewed-By: Zeyu "Alex" Yang --- lib/internal/url.js | 4 ++++ test/parallel/test-url-revokeobjecturl.js | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 test/parallel/test-url-revokeobjecturl.js diff --git a/lib/internal/url.js b/lib/internal/url.js index cdd192daad96d7..38f97926064595 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -1108,6 +1108,10 @@ function installObjectURLMethods() { } function revokeObjectURL(url) { + if (arguments.length === 0) { + throw new ERR_MISSING_ARGS('url'); + } + bindingBlob.revokeObjectURL(`${url}`); } diff --git a/test/parallel/test-url-revokeobjecturl.js b/test/parallel/test-url-revokeobjecturl.js new file mode 100644 index 00000000000000..dae980c4d0074c --- /dev/null +++ b/test/parallel/test-url-revokeobjecturl.js @@ -0,0 +1,14 @@ +'use strict'; + +require('../common'); + +// Test ensures that the function receives the url argument. + +const assert = require('node:assert'); + +assert.throws(() => { + URL.revokeObjectURL(); +}, { + code: 'ERR_MISSING_ARGS', + name: 'TypeError', +}); From 3a1c664a97e890432db3c60d2a2a733410158faf Mon Sep 17 00:00:00 2001 From: Angelo Parziale Date: Fri, 1 Dec 2023 19:27:21 +0100 Subject: [PATCH 23/38] test: replace forEach to for.. test-webcrypto-export-import-cfrg.js PR-URL: https://github.com/nodejs/node/pull/50785 Reviewed-By: James M Snell Reviewed-By: Rafael Gonzaga --- test/parallel/test-webcrypto-export-import-cfrg.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-webcrypto-export-import-cfrg.js b/test/parallel/test-webcrypto-export-import-cfrg.js index 85a1319fa8cab4..144424ce01ded2 100644 --- a/test/parallel/test-webcrypto-export-import-cfrg.js +++ b/test/parallel/test-webcrypto-export-import-cfrg.js @@ -340,15 +340,14 @@ async function testImportRaw({ name, publicUsages }) { (async function() { const tests = []; - testVectors.forEach((vector) => { - [true, false].forEach((extractable) => { + for (const vector of testVectors) { + for (const extractable of [true, false]) { tests.push(testImportSpki(vector, extractable)); tests.push(testImportPkcs8(vector, extractable)); tests.push(testImportJwk(vector, extractable)); - }); + } tests.push(testImportRaw(vector)); - }); - + } await Promise.all(tests); })().then(common.mustCall()); From f79b54e60e001fae07f46cbfbc3d0e813a794d99 Mon Sep 17 00:00:00 2001 From: Lei Shi Date: Sat, 2 Dec 2023 11:04:25 +0800 Subject: [PATCH 24/38] benchmark: update iterations in benchmark/crypto/get-ciphers.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/nodejs/node/issues/50571 PR-URL: https://github.com/nodejs/node/pull/50863 Refs: https://github.com/nodejs/node/issues/50571 Reviewed-By: Vinícius Lourenço Claro Cardoso --- benchmark/crypto/get-ciphers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark/crypto/get-ciphers.js b/benchmark/crypto/get-ciphers.js index 0ace9b49820db8..e3cd955a983dd2 100644 --- a/benchmark/crypto/get-ciphers.js +++ b/benchmark/crypto/get-ciphers.js @@ -3,7 +3,7 @@ const common = require('../common.js'); const bench = common.createBenchmark(main, { - n: [1, 5000], + n: [1, 500000], v: ['crypto', 'tls'], }); From 9bc79173a0a27941fa22262ca2385faab99d68b6 Mon Sep 17 00:00:00 2001 From: Mudit Date: Sat, 2 Dec 2023 14:53:05 +0100 Subject: [PATCH 25/38] loader: speed up line length calc used by moduleProvider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using a loader, for say TypeScript, the esm loader invokes the `lineLengths` function via `maybeCacheSourceMap` when sourcemaps are enabled. Therefore, `lineLengths` ends up getting called quite often when running large servers written in TypeScript for example. Making `lineLengths` faster should therefore speed up server startup times for anyone using a loader with node with sourcemaps enabled. The change itself is fairly simple and is all about removing creation of unnecessary memory and iterating the whole source content only once with the hope of making the function cache friendly. PR-URL: https://github.com/nodejs/node/pull/50969 Reviewed-By: Yagiz Nizipli Reviewed-By: Geoffrey Booth Reviewed-By: Antoine du Hamel Reviewed-By: Vinícius Lourenço Claro Cardoso Reviewed-By: Jacob Smith --- lib/internal/source_map/source_map_cache.js | 28 +++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/internal/source_map/source_map_cache.js b/lib/internal/source_map/source_map_cache.js index 2813da21dfdc63..963b34ebcd241e 100644 --- a/lib/internal/source_map/source_map_cache.js +++ b/lib/internal/source_map/source_map_cache.js @@ -1,12 +1,12 @@ 'use strict'; const { - ArrayPrototypeMap, + ArrayPrototypePush, JSONParse, ObjectKeys, RegExpPrototypeExec, - RegExpPrototypeSymbolSplit, SafeMap, + StringPrototypeCodePointAt, StringPrototypeSplit, } = primordials; @@ -205,14 +205,26 @@ function dataFromUrl(sourceURL, sourceMappingURL) { // from. This allows translation from byte offset V8 coverage reports, // to line/column offset Source Map V3. function lineLengths(content) { - // We purposefully keep \r as part of the line-length calculation, in - // cases where there is a \r\n separator, so that this can be taken into - // account in coverage calculations. - return ArrayPrototypeMap(RegExpPrototypeSymbolSplit(/\n|\u2028|\u2029/, content), (line) => { - return line.length; - }); + const contentLength = content.length; + const output = []; + let lineLength = 0; + for (let i = 0; i < contentLength; i++, lineLength++) { + const codePoint = StringPrototypeCodePointAt(content, i); + + // We purposefully keep \r as part of the line-length calculation, in + // cases where there is a \r\n separator, so that this can be taken into + // account in coverage calculations. + // codepoints for \n (new line), \u2028 (line separator) and \u2029 (paragraph separator) + if (codePoint === 10 || codePoint === 0x2028 || codePoint === 0x2029) { + ArrayPrototypePush(output, lineLength); + lineLength = -1; // To not count the matched codePoint such as \n character + } + } + ArrayPrototypePush(output, lineLength); + return output; } + function sourceMapFromFile(mapURL) { try { const fs = require('fs'); From 099ebdb781689926edfe46e749e54384bcb99b3e Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sat, 2 Dec 2023 16:38:58 +0200 Subject: [PATCH 26/38] deps: update undici to 5.28.1 PR-URL: https://github.com/nodejs/node/pull/50975 Reviewed-By: Filip Skokan Reviewed-By: Marco Ippolito Reviewed-By: Matteo Collina Reviewed-By: Matthew Aitken --- deps/undici/src/lib/client.js | 31 ++--- deps/undici/src/lib/core/request.js | 34 ++++- deps/undici/src/lib/fetch/request.js | 33 ++--- deps/undici/src/lib/fetch/util.js | 30 ++++- deps/undici/src/package-lock.json | 116 +++++++++--------- deps/undici/src/package.json | 2 +- deps/undici/undici.js | 108 ++++++++++------ .../maintaining/maintaining-dependencies.md | 6 +- src/undici_version.h | 2 +- 9 files changed, 216 insertions(+), 146 deletions(-) diff --git a/deps/undici/src/lib/client.js b/deps/undici/src/lib/client.js index cafc03a09ff86b..22cb39039da7fb 100644 --- a/deps/undici/src/lib/client.js +++ b/deps/undici/src/lib/client.js @@ -917,11 +917,9 @@ class Parser { socket[kReset] = true } - let pause - try { - pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false - } catch (err) { - util.destroy(socket, err) + const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false + + if (request.aborted) { return -1 } @@ -968,13 +966,8 @@ class Parser { this.bytesRead += buf.length - try { - if (request.onData(buf) === false) { - return constants.ERROR.PAUSED - } - } catch (err) { - util.destroy(socket, err) - return -1 + if (request.onData(buf) === false) { + return constants.ERROR.PAUSED } } @@ -1015,11 +1008,7 @@ class Parser { return -1 } - try { - request.onComplete(headers) - } catch (err) { - errorRequest(client, request, err) - } + request.onComplete(headers) client[kQueue][client[kRunningIdx]++] = null @@ -1805,13 +1794,17 @@ function writeH2 (client, session, request) { }) stream.on('data', (chunk) => { - if (request.onData(chunk) === false) stream.pause() + if (request.onData(chunk) === false) { + stream.pause() + } }) stream.once('close', () => { h2State.openStreams -= 1 // TODO(HTTP/2): unref only if current streams count is 0 - if (h2State.openStreams === 0) session.unref() + if (h2State.openStreams === 0) { + session.unref() + } }) stream.once('error', function (err) { diff --git a/deps/undici/src/lib/core/request.js b/deps/undici/src/lib/core/request.js index fbbe45a6d9c4fa..3697e6a3acccd5 100644 --- a/deps/undici/src/lib/core/request.js +++ b/deps/undici/src/lib/core/request.js @@ -229,7 +229,11 @@ class Request { onBodySent (chunk) { if (this[kHandler].onBodySent) { - return this[kHandler].onBodySent(chunk) + try { + return this[kHandler].onBodySent(chunk) + } catch (err) { + this.abort(err) + } } } @@ -239,7 +243,11 @@ class Request { } if (this[kHandler].onRequestSent) { - return this[kHandler].onRequestSent() + try { + return this[kHandler].onRequestSent() + } catch (err) { + this.abort(err) + } } } @@ -263,14 +271,23 @@ class Request { channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) } - return this[kHandler].onHeaders(statusCode, headers, resume, statusText) + try { + return this[kHandler].onHeaders(statusCode, headers, resume, statusText) + } catch (err) { + this.abort(err) + } } onData (chunk) { assert(!this.aborted) assert(!this.completed) - return this[kHandler].onData(chunk) + try { + return this[kHandler].onData(chunk) + } catch (err) { + this.abort(err) + return false + } } onUpgrade (statusCode, headers, socket) { @@ -289,7 +306,13 @@ class Request { if (channels.trailers.hasSubscribers) { channels.trailers.publish({ request: this, trailers }) } - return this[kHandler].onComplete(trailers) + + try { + return this[kHandler].onComplete(trailers) + } catch (err) { + // TODO (fix): This might be a bad idea? + this.onError(err) + } } onError (error) { @@ -303,6 +326,7 @@ class Request { return } this.aborted = true + return this[kHandler].onError(error) } diff --git a/deps/undici/src/lib/fetch/request.js b/deps/undici/src/lib/fetch/request.js index 336d361ce20b16..3b813aa77df9d1 100644 --- a/deps/undici/src/lib/fetch/request.js +++ b/deps/undici/src/lib/fetch/request.js @@ -10,7 +10,8 @@ const { isValidHTTPToken, sameOrigin, normalizeMethod, - makePolicyContainer + makePolicyContainer, + normalizeMethodRecord } = require('./util') const { forbiddenMethodsSet, @@ -183,8 +184,10 @@ class Request { urlList: [...request.urlList] }) + const initHasKey = Object.keys(init).length !== 0 + // 13. If init is not empty, then: - if (Object.keys(init).length > 0) { + if (initHasKey) { // 1. If request’s mode is "navigate", then set it to "same-origin". if (request.mode === 'navigate') { request.mode = 'same-origin' @@ -315,16 +318,16 @@ class Request { // 2. If method is not a method or method is a forbidden method, then // throw a TypeError. - if (!isValidHTTPToken(init.method)) { - throw new TypeError(`'${init.method}' is not a valid HTTP method.`) + if (!isValidHTTPToken(method)) { + throw new TypeError(`'${method}' is not a valid HTTP method.`) } if (forbiddenMethodsSet.has(method.toUpperCase())) { - throw new TypeError(`'${init.method}' HTTP method is unsupported.`) + throw new TypeError(`'${method}' HTTP method is unsupported.`) } // 3. Normalize method. - method = normalizeMethod(init.method) + method = normalizeMethodRecord[method] ?? normalizeMethod(method) // 4. Set request’s method to method. request.method = method @@ -415,25 +418,25 @@ class Request { } // 32. If init is not empty, then: - if (Object.keys(init).length !== 0) { + if (initHasKey) { + /** @type {HeadersList} */ + const headersList = this[kHeaders][kHeadersList] // 1. Let headers be a copy of this’s headers and its associated header // list. - let headers = new Headers(this[kHeaders]) - // 2. If init["headers"] exists, then set headers to init["headers"]. - if (init.headers !== undefined) { - headers = init.headers - } + const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList) // 3. Empty this’s headers’s header list. - this[kHeaders][kHeadersList].clear() + headersList.clear() // 4. If headers is a Headers object, then for each header in its header // list, append header’s name/header’s value to this’s headers. - if (headers.constructor.name === 'Headers') { + if (headers instanceof HeadersList) { for (const [key, val] of headers) { - this[kHeaders].append(key, val) + headersList.append(key, val) } + // Note: Copy the `set-cookie` meta-data. + headersList.cookies = headers.cookies } else { // 5. Otherwise, fill this’s headers with headers. fillHeaders(this[kHeaders], headers) diff --git a/deps/undici/src/lib/fetch/util.js b/deps/undici/src/lib/fetch/util.js index bc6fd50c68a08c..b12142c7f42505 100644 --- a/deps/undici/src/lib/fetch/util.js +++ b/deps/undici/src/lib/fetch/util.js @@ -698,11 +698,30 @@ function isCancelled (fetchParams) { fetchParams.controller.state === 'terminated' } -// https://fetch.spec.whatwg.org/#concept-method-normalize +const normalizeMethodRecord = { + delete: 'DELETE', + DELETE: 'DELETE', + get: 'GET', + GET: 'GET', + head: 'HEAD', + HEAD: 'HEAD', + options: 'OPTIONS', + OPTIONS: 'OPTIONS', + post: 'POST', + POST: 'POST', + put: 'PUT', + PUT: 'PUT' +} + +// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. +Object.setPrototypeOf(normalizeMethodRecord, null) + +/** + * @see https://fetch.spec.whatwg.org/#concept-method-normalize + * @param {string} method + */ function normalizeMethod (method) { - return /^(DELETE|GET|HEAD|OPTIONS|POST|PUT)$/i.test(method) - ? method.toUpperCase() - : method + return normalizeMethodRecord[method.toLowerCase()] ?? method } // https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string @@ -1047,5 +1066,6 @@ module.exports = { urlIsLocal, urlHasHttpsScheme, urlIsHttpHttpsScheme, - readAllBytes + readAllBytes, + normalizeMethodRecord } diff --git a/deps/undici/src/package-lock.json b/deps/undici/src/package-lock.json index d3360f32b9f9a4..d4498d439c288f 100644 --- a/deps/undici/src/package-lock.json +++ b/deps/undici/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "undici", - "version": "5.28.0", + "version": "5.28.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "undici", - "version": "5.28.0", + "version": "5.28.1", "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" @@ -83,9 +83,9 @@ "dev": true }, "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { "@babel/highlight": "^7.23.4", @@ -167,30 +167,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", - "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -238,12 +238,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", - "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "dev": true, "dependencies": { - "@babel/types": "^7.23.4", + "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -394,23 +394,23 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", - "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.4", - "@babel/types": "^7.23.4" + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" }, "engines": { "node": ">=6.9.0" @@ -502,9 +502,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", - "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -691,9 +691,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", - "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -717,19 +717,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", - "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.23.4", - "@babel/generator": "^7.23.4", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.4", - "@babel/types": "^7.23.4", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -761,9 +761,9 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", - "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -1003,9 +1003,9 @@ } }, "node_modules/@httptoolkit/httpolyglot/node_modules/@types/node": { - "version": "16.18.65", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.65.tgz", - "integrity": "sha512-5E9WgTy95B7i90oISjui9U5Zu7iExUPfU4ygtv4yXEy6zJFE3oQYHCnh5H1jZRPkjphJt2Ml3oQW6M0qtK534A==", + "version": "16.18.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.66.tgz", + "integrity": "sha512-sePmD/imfKvC4re/Wwos1NEcXYm6O96CAG5gQVY53nmDb8ePQ4qPku6uruN7n6TJ0t5FhcoUc2+yvE2/UZVDZw==", "dev": true }, "node_modules/@httptoolkit/subscriptions-transport-ws": { @@ -1764,9 +1764,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.18.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", - "integrity": "sha512-vXYZGRrSCreZmq1rEjMRLXJhiy8MrIeVasx+PCVlP414N7CJLHnMf+juVvjdprHyH+XRy3zKZLHeNueOpJCn0g==", + "version": "18.18.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.14.tgz", + "integrity": "sha512-iSOeNeXYNYNLLOMDSVPvIFojclvMZ/HDY2dU17kUlcsOsSQETbWIslJbYLZgA+ox8g2XQwSHKTkght1a5X26lQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1827,6 +1827,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", "dev": true }, "node_modules/abort-controller": { @@ -2952,9 +2953,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001564", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", - "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", "dev": true, "funding": [ { @@ -4148,6 +4149,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", "dev": true, "dependencies": { "webidl-conversions": "^7.0.0" @@ -4193,9 +4195,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.594", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz", - "integrity": "sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==", + "version": "1.4.597", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.597.tgz", + "integrity": "sha512-0XOQNqHhg2YgRVRUrS4M4vWjFCFIP2ETXcXe/0KIQBjXE9Cpy+tgzzYfuq6HGai3hWq0YywtG+5XK8fyG08EjA==", "dev": true }, "node_modules/emittery": { diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json index a4d2d622737b58..f30f5070ff27fa 100644 --- a/deps/undici/src/package.json +++ b/deps/undici/src/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "5.28.0", + "version": "5.28.1", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { diff --git a/deps/undici/undici.js b/deps/undici/undici.js index 7b762bbe0b0a3a..7cfe0e013390c8 100644 --- a/deps/undici/undici.js +++ b/deps/undici/undici.js @@ -1406,8 +1406,23 @@ var require_util2 = __commonJS({ return fetchParams.controller.state === "aborted" || fetchParams.controller.state === "terminated"; } __name(isCancelled, "isCancelled"); + var normalizeMethodRecord = { + delete: "DELETE", + DELETE: "DELETE", + get: "GET", + GET: "GET", + head: "HEAD", + HEAD: "HEAD", + options: "OPTIONS", + OPTIONS: "OPTIONS", + post: "POST", + POST: "POST", + put: "PUT", + PUT: "PUT" + }; + Object.setPrototypeOf(normalizeMethodRecord, null); function normalizeMethod(method) { - return /^(DELETE|GET|HEAD|OPTIONS|POST|PUT)$/i.test(method) ? method.toUpperCase() : method; + return normalizeMethodRecord[method.toLowerCase()] ?? method; } __name(normalizeMethod, "normalizeMethod"); function serializeJavascriptValueToJSONString(value) { @@ -1600,7 +1615,8 @@ var require_util2 = __commonJS({ urlIsLocal, urlHasHttpsScheme, urlIsHttpHttpsScheme, - readAllBytes + readAllBytes, + normalizeMethodRecord }; } }); @@ -5869,7 +5885,8 @@ var require_request = __commonJS({ isValidHTTPToken, sameOrigin, normalizeMethod, - makePolicyContainer + makePolicyContainer, + normalizeMethodRecord } = require_util2(); var { forbiddenMethodsSet, @@ -5993,7 +6010,8 @@ var require_request = __commonJS({ // URL list A clone of request’s URL list. urlList: [...request.urlList] }); - if (Object.keys(init).length > 0) { + const initHasKey = Object.keys(init).length !== 0; + if (initHasKey) { if (request.mode === "navigate") { request.mode = "same-origin"; } @@ -6063,13 +6081,13 @@ var require_request = __commonJS({ } if (init.method !== void 0) { let method = init.method; - if (!isValidHTTPToken(init.method)) { - throw new TypeError(`'${init.method}' is not a valid HTTP method.`); + if (!isValidHTTPToken(method)) { + throw new TypeError(`'${method}' is not a valid HTTP method.`); } if (forbiddenMethodsSet.has(method.toUpperCase())) { - throw new TypeError(`'${init.method}' HTTP method is unsupported.`); + throw new TypeError(`'${method}' HTTP method is unsupported.`); } - method = normalizeMethod(init.method); + method = normalizeMethodRecord[method] ?? normalizeMethod(method); request.method = method; } if (init.signal !== void 0) { @@ -6120,16 +6138,15 @@ var require_request = __commonJS({ } this[kHeaders][kGuard] = "request-no-cors"; } - if (Object.keys(init).length !== 0) { - let headers = new Headers(this[kHeaders]); - if (init.headers !== void 0) { - headers = init.headers; - } - this[kHeaders][kHeadersList].clear(); - if (headers.constructor.name === "Headers") { + if (initHasKey) { + const headersList = this[kHeaders][kHeadersList]; + const headers = init.headers !== void 0 ? init.headers : new HeadersList(headersList); + headersList.clear(); + if (headers instanceof HeadersList) { for (const [key, val] of headers) { - this[kHeaders].append(key, val); + headersList.append(key, val); } + headersList.cookies = headers.cookies; } else { fillHeaders(this[kHeaders], headers); } @@ -7205,7 +7222,11 @@ var require_request2 = __commonJS({ } onBodySent(chunk) { if (this[kHandler].onBodySent) { - return this[kHandler].onBodySent(chunk); + try { + return this[kHandler].onBodySent(chunk); + } catch (err) { + this.abort(err); + } } } onRequestSent() { @@ -7213,7 +7234,11 @@ var require_request2 = __commonJS({ channels.bodySent.publish({ request: this }); } if (this[kHandler].onRequestSent) { - return this[kHandler].onRequestSent(); + try { + return this[kHandler].onRequestSent(); + } catch (err) { + this.abort(err); + } } } onConnect(abort) { @@ -7232,12 +7257,21 @@ var require_request2 = __commonJS({ if (channels.headers.hasSubscribers) { channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }); } - return this[kHandler].onHeaders(statusCode, headers, resume, statusText); + try { + return this[kHandler].onHeaders(statusCode, headers, resume, statusText); + } catch (err) { + this.abort(err); + } } onData(chunk) { assert(!this.aborted); assert(!this.completed); - return this[kHandler].onData(chunk); + try { + return this[kHandler].onData(chunk); + } catch (err) { + this.abort(err); + return false; + } } onUpgrade(statusCode, headers, socket) { assert(!this.aborted); @@ -7251,7 +7285,11 @@ var require_request2 = __commonJS({ if (channels.trailers.hasSubscribers) { channels.trailers.publish({ request: this, trailers }); } - return this[kHandler].onComplete(trailers); + try { + return this[kHandler].onComplete(trailers); + } catch (err) { + this.onError(err); + } } onError(error) { this.onFinally(); @@ -8811,11 +8849,8 @@ var require_client = __commonJS({ } else { socket[kReset] = true; } - let pause; - try { - pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false; - } catch (err) { - util.destroy(socket, err); + const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false; + if (request.aborted) { return -1; } if (request.method === "HEAD") { @@ -8849,13 +8884,8 @@ var require_client = __commonJS({ return -1; } this.bytesRead += buf.length; - try { - if (request.onData(buf) === false) { - return constants.ERROR.PAUSED; - } - } catch (err) { - util.destroy(socket, err); - return -1; + if (request.onData(buf) === false) { + return constants.ERROR.PAUSED; } } onMessageComplete() { @@ -8885,11 +8915,7 @@ var require_client = __commonJS({ util.destroy(socket, new ResponseContentLengthMismatchError()); return -1; } - try { - request.onComplete(headers); - } catch (err) { - errorRequest(client, request, err); - } + request.onComplete(headers); client[kQueue][client[kRunningIdx]++] = null; if (socket[kWriting]) { assert.strictEqual(client[kRunning], 0); @@ -9459,13 +9485,15 @@ upgrade: ${upgrade}\r request.onComplete([]); }); stream.on("data", (chunk) => { - if (request.onData(chunk) === false) + if (request.onData(chunk) === false) { stream.pause(); + } }); stream.once("close", () => { h2State.openStreams -= 1; - if (h2State.openStreams === 0) + if (h2State.openStreams === 0) { session.unref(); + } }); stream.once("error", function(err) { if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { diff --git a/doc/contributing/maintaining/maintaining-dependencies.md b/doc/contributing/maintaining/maintaining-dependencies.md index 00bd3d807def8e..3f7c715c2f3321 100644 --- a/doc/contributing/maintaining/maintaining-dependencies.md +++ b/doc/contributing/maintaining/maintaining-dependencies.md @@ -28,7 +28,7 @@ This a list of all the dependencies: * [openssl 3.0.8][] * [postject 1.0.0-alpha.6][] * [simdutf 4.0.4][] -* [undici 5.28.0][] +* [undici 5.28.1][] * [uvwasi 0.0.19][] * [V8 11.8.172.12][] * [zlib 1.2.13.1-motley-5daffc7][] @@ -291,7 +291,7 @@ The [postject](https://github.com/nodejs/postject) dependency is used for the The [simdutf](https://github.com/simdutf/simdutf) dependency is a C++ library for fast UTF-8 decoding and encoding. -### undici 5.28.0 +### undici 5.28.1 The [undici](https://github.com/nodejs/undici) dependency is an HTTP/1.1 client, written from scratch for Node.js.. @@ -345,7 +345,7 @@ performance improvements not currently available in standard zlib. [openssl 3.0.8]: #openssl-308 [postject 1.0.0-alpha.6]: #postject-100-alpha6 [simdutf 4.0.4]: #simdutf-404 -[undici 5.28.0]: #undici-5280 +[undici 5.28.1]: #undici-5281 [update-openssl-action]: ../../../.github/workflows/update-openssl.yml [uvwasi 0.0.19]: #uvwasi-0019 [v8 11.8.172.12]: #v8-11817212 diff --git a/src/undici_version.h b/src/undici_version.h index 70021854a77888..03d3b6bb7f9641 100644 --- a/src/undici_version.h +++ b/src/undici_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-undici.sh #ifndef SRC_UNDICI_VERSION_H_ #define SRC_UNDICI_VERSION_H_ -#define UNDICI_VERSION "5.28.0" +#define UNDICI_VERSION "5.28.1" #endif // SRC_UNDICI_VERSION_H_ From 32acafeeb661fbe9ce825df908a96a3e27536d3f Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 2 Dec 2023 23:49:21 +0100 Subject: [PATCH 27/38] fs: introduce `dirent.parentPath` The goal is to replace `dirent.path` using a name that's less likely to create confusion. `dirent.path` value has not been stable, moving it to a different property name should avoid breaking some upgrading user expectations. PR-URL: https://github.com/nodejs/node/pull/50976 Reviewed-By: Ethan Arrowood Reviewed-By: LiviaMedeiros --- doc/api/fs.md | 15 ++++++++++++++- lib/fs.js | 2 +- lib/internal/fs/dir.js | 2 +- lib/internal/fs/utils.js | 1 + test/parallel/test-fs-opendir.js | 8 +++++--- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index 50abf3678b6300..b989e064747e92 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -6614,6 +6614,19 @@ The file name that this {fs.Dirent} object refers to. The type of this value is determined by the `options.encoding` passed to [`fs.readdir()`][] or [`fs.readdirSync()`][]. +#### `dirent.parentPath` + + + +> Stability: 1 – Experimental + +* {string} + +The path to the parent directory of the file this {fs.Dirent} object refers to. + #### `dirent.path` -This configures Node.js to interpret string input as CommonJS or as an ES -module. String input is input via `--eval`, `--print`, or `STDIN`. +This configures Node.js to interpret `--eval` or `STDIN` input as CommonJS or +as an ES module. Valid values are `"commonjs"` or `"module"`. The default is +`"commonjs"` unless [`--experimental-default-type=module`][] is used. -Valid values are `"commonjs"` and `"module"`. The default is `"commonjs"`. - -The REPL does not support this option. +The REPL does not support this option. Usage of `--input-type=module` with +[`--print`][] will throw an error, as `--print` does not support ES module +syntax. ### `--insecure-http-parser` @@ -2864,6 +2865,7 @@ done [`--import`]: #--importmodule [`--openssl-config`]: #--openssl-configfile [`--preserve-symlinks`]: #--preserve-symlinks +[`--print`]: #-p---print-script [`--redirect-warnings`]: #--redirect-warningsfile [`--require`]: #-r---require-module [`Atomics.wait()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait From 1e7d101428e8098a12b9004c21e465958ba664da Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 4 Dec 2023 13:29:39 +0100 Subject: [PATCH 37/38] src: make ModifyCodeGenerationFromStrings more robust MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Fallback to true when the context is not (yet) initialized with the kAllowCodeGenerationFromStrings field. 2. Fallback to true when the Environment isn't assigned to the context or when the Environment cannot call into JavaScript. PR-URL: https://github.com/nodejs/node/pull/50763 Refs: https://github.com/nodejs/node/issues/50761 Reviewed-By: Vinícius Lourenço Claro Cardoso Reviewed-By: James M Snell Reviewed-By: Chengzhong Wu --- src/node_errors.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/node_errors.cc b/src/node_errors.cc index 4dfecbaa5a94f7..50618e6c716f0b 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -608,8 +608,18 @@ v8::ModifyCodeGenerationFromStringsResult ModifyCodeGenerationFromStrings( bool is_code_like) { HandleScope scope(context->GetIsolate()); + if (context->GetNumberOfEmbedderDataFields() <= + ContextEmbedderIndex::kAllowCodeGenerationFromStrings) { + // The context is not (yet) configured by Node.js for this. We don't + // have enough information to make a decision, just allow it which is + // the default. + return {true, {}}; + } Environment* env = Environment::GetCurrent(context); - if (env->source_maps_enabled()) { + if (env == nullptr) { + return {true, {}}; + } + if (env->source_maps_enabled() && env->can_call_into_js()) { // We do not expect the maybe_cache_generated_source_map to throw any more // exceptions. If it does, just ignore it. errors::TryCatchScope try_catch(env); From 67ada40a3bdd75ee4f9e6c88c4073e234680f795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Mon, 4 Dec 2023 13:47:52 +0100 Subject: [PATCH 38/38] 2023-12-05, Version 21.4.0 (Current) Notable changes: fs: * (SEMVER-MINOR) introduce `dirent.parentPath` (Antoine du Hamel) https://github.com/nodejs/node/pull/50976 * use default w flag for writeFileSync with utf8 encoding (Murilo Kakazu) https://github.com/nodejs/node/pull/50990 PR-URL: https://github.com/nodejs/node/pull/51043 --- CHANGELOG.md | 3 +- doc/api/fs.md | 2 +- doc/changelogs/CHANGELOG_V21.md | 53 +++++++++++++++++++++++++++++++++ src/node_version.h | 6 ++-- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fcd4cdc184978..f777ea59bfe239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,8 @@ release. -21.3.0
+21.4.0
+21.3.0
21.2.0
21.1.0
21.0.0
diff --git a/doc/api/fs.md b/doc/api/fs.md index b989e064747e92..43177269e60e8b 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -6618,7 +6618,7 @@ value is determined by the `options.encoding` passed to [`fs.readdir()`][] or > Stability: 1 – Experimental diff --git a/doc/changelogs/CHANGELOG_V21.md b/doc/changelogs/CHANGELOG_V21.md index 9a91ef41e964b3..aadf867d4549ee 100644 --- a/doc/changelogs/CHANGELOG_V21.md +++ b/doc/changelogs/CHANGELOG_V21.md @@ -8,6 +8,7 @@ +21.4.0
21.3.0
21.2.0
21.1.0
@@ -39,6 +40,58 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2023-12-05, Version 21.4.0 (Current), @targos + +### Notable Changes + +This release fixes a regression introduced in v21.3.0 that caused the `fs.writeFileSync` +method to throw when called with `'utf8'` encoding, no flag option, and if the target file didn't exist yet. + +* \[[`32acafeeb6`](https://github.com/nodejs/node/commit/32acafeeb6)] - **(SEMVER-MINOR)** **fs**: introduce `dirent.parentPath` (Antoine du Hamel) [#50976](https://github.com/nodejs/node/pull/50976) +* \[[`724548674d`](https://github.com/nodejs/node/commit/724548674d)] - **fs**: use default w flag for writeFileSync with utf8 encoding (Murilo Kakazu) [#50990](https://github.com/nodejs/node/pull/50990) + +### Commits + +* \[[`b24ee15fb2`](https://github.com/nodejs/node/commit/b24ee15fb2)] - **benchmark**: update iterations in benchmark/crypto/hkdf.js (Lei Shi) [#50866](https://github.com/nodejs/node/pull/50866) +* \[[`f79b54e60e`](https://github.com/nodejs/node/commit/f79b54e60e)] - **benchmark**: update iterations in benchmark/crypto/get-ciphers.js (Lei Shi) [#50863](https://github.com/nodejs/node/pull/50863) +* \[[`dc049acbbb`](https://github.com/nodejs/node/commit/dc049acbbb)] - **benchmark**: update number of iterations for `util.inspect` (kylo5aby) [#50651](https://github.com/nodejs/node/pull/50651) +* \[[`d7c562ae38`](https://github.com/nodejs/node/commit/d7c562ae38)] - **deps**: update googletest to 76bb2af (Node.js GitHub Bot) [#50555](https://github.com/nodejs/node/pull/50555) +* \[[`59a45ddbef`](https://github.com/nodejs/node/commit/59a45ddbef)] - **deps**: update googletest to b10fad3 (Node.js GitHub Bot) [#50555](https://github.com/nodejs/node/pull/50555) +* \[[`099ebdb781`](https://github.com/nodejs/node/commit/099ebdb781)] - **deps**: update undici to 5.28.1 (Node.js GitHub Bot) [#50975](https://github.com/nodejs/node/pull/50975) +* \[[`4b1bed04f7`](https://github.com/nodejs/node/commit/4b1bed04f7)] - **deps**: update undici to 5.28.0 (Node.js GitHub Bot) [#50915](https://github.com/nodejs/node/pull/50915) +* \[[`b281e98b1e`](https://github.com/nodejs/node/commit/b281e98b1e)] - **doc**: add additional details about `--input-type` (Shubham Pandey) [#50796](https://github.com/nodejs/node/pull/50796) +* \[[`b7036f2028`](https://github.com/nodejs/node/commit/b7036f2028)] - **doc**: add procedure when CVEs don't get published (Rafael Gonzaga) [#50945](https://github.com/nodejs/node/pull/50945) +* \[[`7adf239af0`](https://github.com/nodejs/node/commit/7adf239af0)] - **doc**: fix some errors in esm resolution algorithms (Christopher Jeffrey (JJ)) [#50898](https://github.com/nodejs/node/pull/50898) +* \[[`759ebcaead`](https://github.com/nodejs/node/commit/759ebcaead)] - **doc**: reserve 121 for Electron 29 (Shelley Vohr) [#50957](https://github.com/nodejs/node/pull/50957) +* \[[`cedc3427fa`](https://github.com/nodejs/node/commit/cedc3427fa)] - **doc**: run license-builder (github-actions\[bot]) [#50926](https://github.com/nodejs/node/pull/50926) +* \[[`30a6f19769`](https://github.com/nodejs/node/commit/30a6f19769)] - **doc**: document non-node\_modules-only runtime deprecation (Joyee Cheung) [#50748](https://github.com/nodejs/node/pull/50748) +* \[[`eecab883f0`](https://github.com/nodejs/node/commit/eecab883f0)] - **doc**: add doc for Unix abstract socket (theanarkh) [#50904](https://github.com/nodejs/node/pull/50904) +* \[[`ec74b93b38`](https://github.com/nodejs/node/commit/ec74b93b38)] - **doc**: remove flicker on page load on dark theme (Dima Demakov) [#50942](https://github.com/nodejs/node/pull/50942) +* \[[`724548674d`](https://github.com/nodejs/node/commit/724548674d)] - **fs**: use default w flag for writeFileSync with utf8 encoding (Murilo Kakazu) [#50990](https://github.com/nodejs/node/pull/50990) +* \[[`32acafeeb6`](https://github.com/nodejs/node/commit/32acafeeb6)] - **(SEMVER-MINOR)** **fs**: introduce `dirent.parentPath` (Antoine du Hamel) [#50976](https://github.com/nodejs/node/pull/50976) +* \[[`c1ee506454`](https://github.com/nodejs/node/commit/c1ee506454)] - **fs**: remove workaround for `esm` package (Yagiz Nizipli) [#50907](https://github.com/nodejs/node/pull/50907) +* \[[`1cf087dfb3`](https://github.com/nodejs/node/commit/1cf087dfb3)] - **lib**: refactor to use validateFunction in diagnostics\_channel (Deokjin Kim) [#50955](https://github.com/nodejs/node/pull/50955) +* \[[`c37d18d5e1`](https://github.com/nodejs/node/commit/c37d18d5e1)] - **lib**: streamline process.binding() handling (Joyee Cheung) [#50773](https://github.com/nodejs/node/pull/50773) +* \[[`246cf73631`](https://github.com/nodejs/node/commit/246cf73631)] - **lib,src**: replace toUSVString with `toWellFormed()` (Yagiz Nizipli) [#47342](https://github.com/nodejs/node/pull/47342) +* \[[`9bc79173a0`](https://github.com/nodejs/node/commit/9bc79173a0)] - **loader**: speed up line length calc used by moduleProvider (Mudit) [#50969](https://github.com/nodejs/node/pull/50969) +* \[[`812ab9e4f8`](https://github.com/nodejs/node/commit/812ab9e4f8)] - **meta**: bump step-security/harden-runner from 2.6.0 to 2.6.1 (dependabot\[bot]) [#50999](https://github.com/nodejs/node/pull/50999) +* \[[`1dbe1af19a`](https://github.com/nodejs/node/commit/1dbe1af19a)] - **meta**: bump github/codeql-action from 2.22.5 to 2.22.8 (dependabot\[bot]) [#50998](https://github.com/nodejs/node/pull/50998) +* \[[`bed1b93f8a`](https://github.com/nodejs/node/commit/bed1b93f8a)] - **meta**: move one or more collaborators to emeritus (Node.js GitHub Bot) [#50931](https://github.com/nodejs/node/pull/50931) +* \[[`1e7d101428`](https://github.com/nodejs/node/commit/1e7d101428)] - **src**: make ModifyCodeGenerationFromStrings more robust (Joyee Cheung) [#50763](https://github.com/nodejs/node/pull/50763) +* \[[`709ac479eb`](https://github.com/nodejs/node/commit/709ac479eb)] - **src**: disable uncaught exception abortion for ESM syntax detection (Yagiz Nizipli) [#50987](https://github.com/nodejs/node/pull/50987) +* \[[`f6ff11c9f9`](https://github.com/nodejs/node/commit/f6ff11c9f9)] - **src**: fix backtrace with tail \[\[noreturn]] abort (Chengzhong Wu) [#50849](https://github.com/nodejs/node/pull/50849) +* \[[`74f5a1cbc9`](https://github.com/nodejs/node/commit/74f5a1cbc9)] - **src**: print MKSNAPSHOT debug logs to stderr (Joyee Cheung) [#50759](https://github.com/nodejs/node/pull/50759) +* \[[`3a1c664a97`](https://github.com/nodejs/node/commit/3a1c664a97)] - **test**: replace forEach to for.. test-webcrypto-export-import-cfrg.js (Angelo Parziale) [#50785](https://github.com/nodejs/node/pull/50785) +* \[[`ac3a6eefe3`](https://github.com/nodejs/node/commit/ac3a6eefe3)] - **test**: log more information in SEA tests (Joyee Cheung) [#50759](https://github.com/nodejs/node/pull/50759) +* \[[`94462d42f5`](https://github.com/nodejs/node/commit/94462d42f5)] - **test**: consolidate utf8 text fixtures in tests (Joyee Cheung) [#50732](https://github.com/nodejs/node/pull/50732) +* \[[`8e1a70a347`](https://github.com/nodejs/node/commit/8e1a70a347)] - **tools**: add triggers to update release links workflow (Moshe Atlow) [#50974](https://github.com/nodejs/node/pull/50974) +* \[[`ca10cbb774`](https://github.com/nodejs/node/commit/ca10cbb774)] - **tools**: update lint-md-dependencies to rollup\@4.5.2 (Node.js GitHub Bot) [#50913](https://github.com/nodejs/node/pull/50913) +* \[[`1e40c4a366`](https://github.com/nodejs/node/commit/1e40c4a366)] - **tools**: fix current version check (Marco Ippolito) [#50951](https://github.com/nodejs/node/pull/50951) +* \[[`3faed331e1`](https://github.com/nodejs/node/commit/3faed331e1)] - **typings**: fix JSDoc in `internal/modules/esm/hooks` (Alex Yang) [#50887](https://github.com/nodejs/node/pull/50887) +* \[[`6a087ceffa`](https://github.com/nodejs/node/commit/6a087ceffa)] - **url**: throw error if argument length of revokeObjectURL is 0 (DylanTet) [#50433](https://github.com/nodejs/node/pull/50433) + ## 2023-11-30, Version 21.3.0 (Current), @RafaelGSS diff --git a/src/node_version.h b/src/node_version.h index b5706cce0cc40a..98966cbd9e21f3 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 21 -#define NODE_MINOR_VERSION 3 -#define NODE_PATCH_VERSION 1 +#define NODE_MINOR_VERSION 4 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)