diff --git a/.eslintrc.js b/.eslintrc.js index 9c3a78d81cd27a..8347d066ed22ec 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -156,8 +156,13 @@ module.exports = { ], /* eslint-disable max-len */ // If this list is modified, please copy the change to lib/.eslintrc.yaml + // and test/.eslintrc.yaml. 'no-restricted-syntax': [ 'error', + { + selector: "CallExpression[callee.object.name='assert'][callee.property.name='deepStrictEqual'][arguments.2.type='Literal']", + message: 'Do not use a literal for the third argument of assert.deepStrictEqual()' + }, { selector: "CallExpression[callee.object.name='assert'][callee.property.name='doesNotThrow']", message: 'Please replace `assert.doesNotThrow()` and add a comment next to the code instead.' @@ -166,6 +171,10 @@ module.exports = { selector: "CallExpression[callee.object.name='assert'][callee.property.name='rejects'][arguments.length<2]", message: 'assert.rejects() must be invoked with at least two arguments.', }, + { + selector: "CallExpression[callee.object.name='assert'][callee.property.name='strictEqual'][arguments.2.type='Literal']", + message: 'Do not use a literal for the third argument of assert.strictEqual()' + }, { selector: "CallExpression[callee.object.name='assert'][callee.property.name='throws'][arguments.1.type='Literal']:not([arguments.1.regex])", message: 'Use an object as second argument of assert.throws()', diff --git a/.mailmap b/.mailmap index 6f8f98d022ddfb..f5462dbb992482 100644 --- a/.mailmap +++ b/.mailmap @@ -131,6 +131,7 @@ Gabriel de Perthuis Gareth Ellis Garwah Lam Geoffrey Bugaisky gbugaisky +Gerhard Stoebich Gibson Fahnestock Gil Pedersen Graham Fairweather Xotic750 @@ -204,6 +205,7 @@ Jérémy Lal Juan Sebastian Velez Posada Kai Sasaki Lewuathe Karl Skomski +Kat Marchán Kathy Truong k3kathy Kazuyuki Yamada Keith M Wesolowski @@ -238,6 +240,7 @@ Matheus Marchini Matheus Marchini Matt Lang matt-in-a-hat Matt Reed matthewreed26 +Matteo Collina Matthias Bastian piepmatz Mathias Buus Mathias Pettersson @@ -364,6 +367,7 @@ Tadashi SAWADA Takahiro ANDO Tarun Batra Tarun Ted Young +Teppei Sato Thomas Hunter II Thomas Lee Thomas Reggi @@ -391,7 +395,8 @@ Vladimir de Turckheim vsemozhetbyt Vse Mozhet Byt Wang Xinyong Weijia Wang <381152119@qq.com> -Weijia Wang <381152119@qq.com> starkewang +Weijia Wang <381152119@qq.com> +Weijia Wang <381152119@qq.com> Wei-Wei Wu Willi Eggeling Will Hayslett diff --git a/AUTHORS b/AUTHORS index 68469ee76329e2..299800b059fe21 100644 --- a/AUTHORS +++ b/AUTHORS @@ -650,7 +650,7 @@ Micleusanu Nicu Alejandro Oviedo Garcia Ben Burns Julian Duque -teppeis +Teppei Sato Rudi Cilibrasi Tim Ruffles CGavrila @@ -754,14 +754,14 @@ Felipe Batista Rebecca Turner Tyler Anton João Reis -Kat Marchán +Kat Marchán Ryan Petschek Pierre Inglebert Ivan Yan Sangmin Yoon Mark Plomer Phillip Johnsen -Matteo Collina +Matteo Collina jomo Gireesh Punathil Lucien Greathouse @@ -1432,23 +1432,25 @@ Ahmad Nassri Tom Atkinson Tobias Nießen Joseph Gentle +Arunesh Chandra +Gabriel Schulhof +Ian Halliday +Sampson Gao +Taylor Woll Zero King Raphael Okon JR McEntee Lovell Fuller Jason Marsh Vinay Hiremath -Gabriel Schulhof alejandro dave-k Steven Uppinder Chugh Karl Cheng -Taylor Woll Tarun Batra Nao YONASHIRO Christopher Luke -Sampson Gao John Paul Bamberg Cody Deckard Fabio Campinho @@ -1488,7 +1490,7 @@ Madara Uchiha Gil Tayar Glenn Schlereth Artur G Vieira -Flarna +Gerhard Stoebich Sreepurna Jasti Rafael Fragoso Andrei Cioromila @@ -1658,6 +1660,8 @@ Piotr Mionskowski Cyril Lakech Eduard Bondarenko Adina Shanholtz +Guy Bedford +Jan Krems Miguel Martins Yury Popov George Bezerra @@ -1670,7 +1674,6 @@ Alex Gresnel <31708810+agresnel@users.noreply.github.com> Will Young Martijn Schrage Halil İbrahim Şener -Guy Bedford Antoine Amara Mani Maghsoudlou Bartek Szczepański @@ -1884,7 +1887,6 @@ Ashish Kaila c0b <14798161+c0b@users.noreply.github.com> Damian Alec Perkins -Teppei Sato Jinwoo Lee Peter Marton Erwin W. Ramadhan @@ -2154,9 +2156,7 @@ Nick Filatov Jesse Gorzinski Pieter Mees Malcolm White -Gerhard Stoebich Matei Copot -ikasumiwt Gurin, Sebastian Indranil Dasgupta Harry Sarson @@ -2187,7 +2187,6 @@ Kyle Martin Denis Fäcke Daylor Yanes Carrie Coxwell -BeniCheni Masashi Hirano Brandon Ruggles Allen Yonghuang Wang @@ -2218,6 +2217,7 @@ Abhimanyu Vashisht Sagir Khan Kael Zhang Unknown +Krzysztof Taborski Blaine Bublitz Shailesh Shekhawat Davis Okoth @@ -2236,5 +2236,86 @@ Shelley Vohr Deepjyoti Mondal Brett Kiefer Kevin Thomas +ZaneHannanAU +Fernando Doglio +Renée Kooi +Jo Colina +itaysabato +Victor Belozyorov +Joonas Rouhiainen +GauthamBanasandra +Hugo Josefson +Sam Ruby +Haroon Khan +Developer Davo +Jacek Pospychała +MaleDong +iwko +Sohail Rajdev +Niicck +Denys Otrishko +Sergey Zelenov +Travis Fischer +Dominic Farolino +Octavian Soldea +XhmikosR +AdityaSrivast +Javier Gonzalez +RidgeA +Ryuichi Sakagami +hectorcoronado +Petras <15868923+kimberlake@users.noreply.github.com> +Kevin Lacabane <5239883+klacabane@users.noreply.github.com> +Simionescu, Radu +mariotsi +prayag21 <10997858+prayag21@users.noreply.github.com> +Bruno Pinho +Anto Aravinth +Helio Frota <00hf11@gmail.com> +Tim Ruffles +Jacob Page +sagulati +conectado +Vitor Bruno de Oliveira Barth +cclauss +James Ide +MaleDong +bhavayAnand9 +Brandon Lee <40652534+brandonlwt@users.noreply.github.com> +Oryan Moshe +Michael Sommer +Eugene Y. Q. Shen +Rishabh Singh +Marco Levrero +Ouyang Yadong +yahavfuchs +Thomas Leah +Musa Hamwala +James Bromwell +Jeremy Apthorp +Eugen Cazacu <32613393+oygen87@users.noreply.github.com> +James Bromwell <943160+thw0rted@users.noreply.github.com> +Csaba Palfi +Ryan Petrich +Andreas Girgensohn +Caleb Sander +Dzmitry_Prudnikau +Ian McKellar +Jennifer Bland +Kyle Fuller +ZYSzys +Neeraj Laad +Scott Van Gilder +Yaniv Friedensohn +Lars-Magnus Skog +Lucas Woo +Troels Liebe Bentsen +pranshuchittora +lakamsani +Chris White +Ben Newman +Szymon Marczak +Tessei Kameyama +Chakravarthy S M -# Generated by tools/update-authors.sh +# Generated by tools/update-authors.js diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 478908c8b1d023..c073c07a7f0996 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -21,6 +21,7 @@ - [When Breaking Changes Actually Break Things](#when-breaking-changes-actually-break-things) - [Reverting commits](#reverting-commits) - [Introducing New Modules](#introducing-new-modules) + - [Additions to N-API](#additions-to-n-api) - [Deprecations](#deprecations) - [Involving the TSC](#involving-the-tsc) * [Landing Pull Requests](#landing-pull-requests) @@ -411,6 +412,18 @@ For new modules that involve significant effort, non-trivial additions to Node.js or significant new capabilities, an [Enhancement Proposal][] is recommended but not required. +### Additions to N-API + +N-API provides an ABI stable API that we will have to support in future +versions without the usual option to modify or remove existing APIs on +SemVer boundaries. Therefore, additions need to be managed carefully. + +This +[guide](https://github.com/nodejs/node/blob/master/doc/guides/adding-new-napi-api.md) +outlines the requirements and principles that we should follow when +approving and landing new N-API APIs (any additions to `node_api.h` and +`node_api_types.h`). + ### Deprecations [_Deprecation_][] is "the discouragement of use of some … feature … or practice, diff --git a/Makefile b/Makefile index 5325abe40c0307..5fc2bb0c58f553 100644 --- a/Makefile +++ b/Makefile @@ -1087,7 +1087,8 @@ tools/.docmdlintstamp: $(LINT_MD_DOC_FILES) LINT_MD_TARGETS = src lib benchmark test tools/doc tools/icu LINT_MD_ROOT_DOCS := $(wildcard *.md) LINT_MD_MISC_FILES := $(shell find $(LINT_MD_TARGETS) -type f \ - -not -path '*node_modules*' -name '*.md') $(LINT_MD_ROOT_DOCS) + -not -path '*node_modules*' -not -path 'test/fixtures/*' -name '*.md') \ + $(LINT_MD_ROOT_DOCS) run-lint-misc-md = tools/lint-md.js -q -f $(LINT_MD_MISC_FILES) # Lint other changed markdown files maintained by us tools/.miscmdlintstamp: $(LINT_MD_MISC_FILES) diff --git a/README.md b/README.md index de923e9408a0ea..15cbb2133351f3 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,8 @@ For more information about the governance of the Node.js project, see **Franziska Hinkelmann** <franziska.hinkelmann@gmail.com> (she/her) * [Fishrock123](https://github.com/Fishrock123) - **Jeremiah Senkpiel** <fishrock123@rocketmail.com> +* [gabrielschulhof](https://github.com/gabrielschulhof) - +**Gabriel Schulhof** <gabriel.schulhof@intel.com> * [gibfahn](https://github.com/gibfahn) - **Gibson Fahnestock** <gibfahn@gmail.com> (he/him) * [jasnell](https://github.com/jasnell) - @@ -331,6 +333,8 @@ For more information about the governance of the Node.js project, see **Benedikt Meurer** <benedikt.meurer@gmail.com> * [bnoordhuis](https://github.com/bnoordhuis) - **Ben Noordhuis** <info@bnoordhuis.nl> +* [boneskull](https://github.com/boneskull) - +**Christopher Hiller** <boneskull@boneskull.com> (he/him) * [brendanashworth](https://github.com/brendanashworth) - **Brendan Ashworth** <brendan.ashworth@me.com> * [BridgeAR](https://github.com/BridgeAR) - diff --git a/benchmark/fs/bench-mkdirp.js b/benchmark/fs/bench-mkdirp.js new file mode 100644 index 00000000000000..96a792c35a48e4 --- /dev/null +++ b/benchmark/fs/bench-mkdirp.js @@ -0,0 +1,23 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const tmpdir = require('../../test/common/tmpdir'); +tmpdir.refresh(); +let dirc = 0; + +const bench = common.createBenchmark(main, { + n: [1e4], +}); + +function main({ n }) { + bench.start(); + (function r(cntr) { + if (cntr-- <= 0) + return bench.end(n); + const pathname = `${tmpdir.path}/${++dirc}/${++dirc}/${++dirc}/${++dirc}`; + fs.mkdir(pathname, { createParents: true }, (err) => { + r(cntr); + }); + }(n)); +} diff --git a/common.gypi b/common.gypi index 9f1ae6a4d656e5..39afdc4d95a28d 100644 --- a/common.gypi +++ b/common.gypi @@ -29,7 +29,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.25', + 'v8_embedder_string': '-node.29', # Enable disassembler for `--print-code` v8 options 'v8_enable_disassembler': 1, diff --git a/deps/v8/include/v8-inspector.h b/deps/v8/include/v8-inspector.h index 6de8234fb83bcf..cb5ceff037b131 100644 --- a/deps/v8/include/v8-inspector.h +++ b/deps/v8/include/v8-inspector.h @@ -214,6 +214,11 @@ class V8_EXPORT V8InspectorClient { virtual bool canExecuteScripts(int contextGroupId) { return true; } virtual void maxAsyncCallStackDepthChanged(int depth) {} + + virtual std::unique_ptr resourceNameToUrl( + const StringView& resourceName) { + return nullptr; + } }; // These stack trace ids are intended to be passed between debuggers and be diff --git a/deps/v8/src/field-type.cc b/deps/v8/src/field-type.cc index 3b51095323c06b..2eebebe3d616ea 100644 --- a/deps/v8/src/field-type.cc +++ b/deps/v8/src/field-type.cc @@ -78,6 +78,7 @@ void FieldType::PrintTo(std::ostream& os) { os << "None"; } else { DCHECK(IsClass()); + HandleScope scope(Map::cast(this)->GetIsolate()); os << "Class(" << static_cast(*AsClass()) << ")"; } } diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.cc b/deps/v8/src/inspector/v8-debugger-agent-impl.cc index 6b3c0ab88708b7..6edf59445f92c4 100644 --- a/deps/v8/src/inspector/v8-debugger-agent-impl.cc +++ b/deps/v8/src/inspector/v8-debugger-agent-impl.cc @@ -1444,7 +1444,7 @@ void V8DebuggerAgentImpl::didParseSource( protocol::StringUtil::parseJSON(inspected->auxData())); } bool isLiveEdit = script->isLiveEdit(); - bool hasSourceURL = script->hasSourceURL(); + bool hasSourceURLComment = script->hasSourceURLComment(); bool isModule = script->isModule(); String16 scriptId = script->scriptId(); String16 scriptURL = script->sourceURL(); @@ -1464,7 +1464,8 @@ void V8DebuggerAgentImpl::didParseSource( Maybe executionContextAuxDataParam( std::move(executionContextAuxData)); const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; - const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; + const bool* hasSourceURLParam = + hasSourceURLComment ? &hasSourceURLComment : nullptr; const bool* isModuleParam = isModule ? &isModule : nullptr; std::unique_ptr stack = V8StackTraceImpl::capture(m_inspector->debugger(), contextGroupId, 1); diff --git a/deps/v8/src/inspector/v8-debugger-script.cc b/deps/v8/src/inspector/v8-debugger-script.cc index d632df3f66c747..3ceb2af65202c8 100644 --- a/deps/v8/src/inspector/v8-debugger-script.cc +++ b/deps/v8/src/inspector/v8-debugger-script.cc @@ -6,6 +6,7 @@ #include "src/inspector/inspected-context.h" #include "src/inspector/string-util.h" +#include "src/inspector/v8-inspector-impl.h" #include "src/inspector/wasm-translation.h" #include "src/utils.h" @@ -110,41 +111,11 @@ class ActualScript : public V8DebuggerScript { public: ActualScript(v8::Isolate* isolate, v8::Local script, - bool isLiveEdit) + bool isLiveEdit, V8InspectorClient* client) : V8DebuggerScript(isolate, String16::fromInteger(script->Id()), - GetNameOrSourceUrl(script)), + GetScriptURL(script, client)), m_isLiveEdit(isLiveEdit) { - v8::Local tmp; - if (script->SourceURL().ToLocal(&tmp)) m_sourceURL = toProtocolString(tmp); - if (script->SourceMappingURL().ToLocal(&tmp)) - m_sourceMappingURL = toProtocolString(tmp); - m_startLine = script->LineOffset(); - m_startColumn = script->ColumnOffset(); - std::vector lineEnds = script->LineEnds(); - CHECK(lineEnds.size()); - int source_length = lineEnds[lineEnds.size() - 1]; - if (lineEnds.size()) { - m_endLine = static_cast(lineEnds.size()) + m_startLine - 1; - if (lineEnds.size() > 1) { - m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1; - } else { - m_endColumn = source_length + m_startColumn; - } - } else { - m_endLine = m_startLine; - m_endColumn = m_startColumn; - } - - USE(script->ContextId().To(&m_executionContextId)); - - if (script->Source().ToLocal(&tmp)) { - m_source = toProtocolString(tmp); - } - - m_isModule = script->IsModule(); - - m_script.Reset(m_isolate, script); - m_script.AnnotateStrongRetainer(kGlobalDebuggerScriptHandleLabel); + Initialize(script); } bool isLiveEdit() const override { return m_isLiveEdit; } @@ -248,10 +219,18 @@ class ActualScript : public V8DebuggerScript { } private: - String16 GetNameOrSourceUrl(v8::Local script) { - v8::Local name; - if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) - return toProtocolString(name); + String16 GetScriptURL(v8::Local script, + V8InspectorClient* client) { + v8::Local sourceURL; + if (script->SourceURL().ToLocal(&sourceURL) && sourceURL->Length() > 0) + return toProtocolString(sourceURL); + v8::Local v8Name; + if (script->Name().ToLocal(&v8Name) && v8Name->Length() > 0) { + String16 name = toProtocolString(v8Name); + std::unique_ptr url = + client->resourceNameToUrl(toStringView(name)); + return url ? toString16(url->string()) : name; + } return String16(); } @@ -259,6 +238,41 @@ class ActualScript : public V8DebuggerScript { return m_script.Get(m_isolate); } + void Initialize(v8::Local script) { + v8::Local tmp; + m_hasSourceURLComment = + script->SourceURL().ToLocal(&tmp) && tmp->Length() > 0; + if (script->SourceMappingURL().ToLocal(&tmp)) + m_sourceMappingURL = toProtocolString(tmp); + m_startLine = script->LineOffset(); + m_startColumn = script->ColumnOffset(); + std::vector lineEnds = script->LineEnds(); + CHECK(lineEnds.size()); + int source_length = lineEnds[lineEnds.size() - 1]; + if (lineEnds.size()) { + m_endLine = static_cast(lineEnds.size()) + m_startLine - 1; + if (lineEnds.size() > 1) { + m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1; + } else { + m_endColumn = source_length + m_startColumn; + } + } else { + m_endLine = m_startLine; + m_endColumn = m_startColumn; + } + + USE(script->ContextId().To(&m_executionContextId)); + + if (script->Source().ToLocal(&tmp)) { + m_source = toProtocolString(tmp); + } + + m_isModule = script->IsModule(); + + m_script.Reset(m_isolate, script); + m_script.AnnotateStrongRetainer(kGlobalDebuggerScriptHandleLabel); + } + String16 m_sourceMappingURL; bool m_isLiveEdit = false; bool m_isModule = false; @@ -392,9 +406,9 @@ class WasmVirtualScript : public V8DebuggerScript { std::unique_ptr V8DebuggerScript::Create( v8::Isolate* isolate, v8::Local scriptObj, - bool isLiveEdit) { + bool isLiveEdit, V8InspectorClient* client) { return std::unique_ptr( - new ActualScript(isolate, scriptObj, isLiveEdit)); + new ActualScript(isolate, scriptObj, isLiveEdit, client)); } std::unique_ptr V8DebuggerScript::CreateWasm( @@ -412,12 +426,11 @@ V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, V8DebuggerScript::~V8DebuggerScript() {} -const String16& V8DebuggerScript::sourceURL() const { - return m_sourceURL.isEmpty() ? m_url : m_sourceURL; -} - void V8DebuggerScript::setSourceURL(const String16& sourceURL) { - m_sourceURL = sourceURL; + if (sourceURL.length() > 0) { + m_hasSourceURLComment = true; + m_url = sourceURL; + } } bool V8DebuggerScript::setBreakpoint(const String16& condition, @@ -425,5 +438,4 @@ bool V8DebuggerScript::setBreakpoint(const String16& condition, v8::HandleScope scope(m_isolate); return script()->SetBreakpoint(toV8String(m_isolate, condition), loc, id); } - } // namespace v8_inspector diff --git a/deps/v8/src/inspector/v8-debugger-script.h b/deps/v8/src/inspector/v8-debugger-script.h index 3e3885ed52e1fd..ceaa5076c79bba 100644 --- a/deps/v8/src/inspector/v8-debugger-script.h +++ b/deps/v8/src/inspector/v8-debugger-script.h @@ -40,13 +40,14 @@ namespace v8_inspector { // Forward declaration. +class V8InspectorClient; class WasmTranslation; class V8DebuggerScript { public: static std::unique_ptr Create( v8::Isolate* isolate, v8::Local script, - bool isLiveEdit); + bool isLiveEdit, V8InspectorClient* client); static std::unique_ptr CreateWasm( v8::Isolate* isolate, WasmTranslation* wasmTranslation, v8::Local underlyingScript, String16 id, @@ -55,9 +56,9 @@ class V8DebuggerScript { virtual ~V8DebuggerScript(); const String16& scriptId() const { return m_id; } - const String16& url() const { return m_url; } - bool hasSourceURL() const { return !m_sourceURL.isEmpty(); } - const String16& sourceURL() const; + bool hasSourceURLComment() const { return m_hasSourceURLComment; } + const String16& sourceURL() const { return m_url; } + virtual const String16& sourceMappingURL() const = 0; virtual const String16& source() const = 0; virtual const String16& hash() const = 0; @@ -95,7 +96,7 @@ class V8DebuggerScript { String16 m_id; String16 m_url; - String16 m_sourceURL; + bool m_hasSourceURLComment = false; int m_executionContextId = 0; v8::Isolate* m_isolate; diff --git a/deps/v8/src/inspector/v8-debugger.cc b/deps/v8/src/inspector/v8-debugger.cc index 28212a19938629..6e4e6a1752e3ab 100644 --- a/deps/v8/src/inspector/v8-debugger.cc +++ b/deps/v8/src/inspector/v8-debugger.cc @@ -227,13 +227,15 @@ void V8Debugger::getCompiledScripts( v8::Local script = scripts.Get(i); if (!script->WasCompiled()) continue; if (script->IsEmbedded()) { - result.push_back(V8DebuggerScript::Create(m_isolate, script, false)); + result.push_back(V8DebuggerScript::Create(m_isolate, script, false, + m_inspector->client())); continue; } int contextId; if (!script->ContextId().To(&contextId)) continue; if (m_inspector->contextGroupId(contextId) != contextGroupId) continue; - result.push_back(V8DebuggerScript::Create(m_isolate, script, false)); + result.push_back(V8DebuggerScript::Create(m_isolate, script, false, + m_inspector->client())); } } @@ -542,13 +544,14 @@ void V8Debugger::ScriptCompiled(v8::Local script, }); } else if (m_ignoreScriptParsedEventsCounter == 0) { v8::Isolate* isolate = m_isolate; + V8InspectorClient* client = m_inspector->client(); m_inspector->forEachSession( m_inspector->contextGroupId(contextId), - [&isolate, &script, &has_compile_error, - &is_live_edited](V8InspectorSessionImpl* session) { + [&isolate, &script, &has_compile_error, &is_live_edited, + &client](V8InspectorSessionImpl* session) { if (!session->debuggerAgent()->enabled()) return; session->debuggerAgent()->didParseSource( - V8DebuggerScript::Create(isolate, script, is_live_edited), + V8DebuggerScript::Create(isolate, script, is_live_edited, client), !has_compile_error); }); } diff --git a/deps/v8/src/inspector/v8-profiler-agent-impl.cc b/deps/v8/src/inspector/v8-profiler-agent-impl.cc index 59a99d79d54c2f..f14815fdc4b031 100644 --- a/deps/v8/src/inspector/v8-profiler-agent-impl.cc +++ b/deps/v8/src/inspector/v8-profiler-agent-impl.cc @@ -7,6 +7,7 @@ #include #include "src/base/atomicops.h" +#include "src/debug/debug-interface.h" #include "src/flags.h" // TODO(jgruber): Remove include and DEPS entry. #include "src/inspector/protocol/Protocol.h" #include "src/inspector/string-util.h" @@ -31,6 +32,15 @@ static const char typeProfileStarted[] = "typeProfileStarted"; namespace { +String16 resourceNameToUrl(V8InspectorImpl* inspector, + v8::Local v8Name) { + String16 name = toProtocolString(v8Name); + if (!inspector) return name; + std::unique_ptr url = + inspector->client()->resourceNameToUrl(toStringView(name)); + return url ? toString16(url->string()) : name; +} + std::unique_ptr> buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) { unsigned lineCount = node->GetHitLineCount(); @@ -51,13 +61,14 @@ buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) { } std::unique_ptr buildInspectorObjectFor( - v8::Isolate* isolate, const v8::CpuProfileNode* node) { + V8InspectorImpl* inspector, const v8::CpuProfileNode* node) { + v8::Isolate* isolate = inspector->isolate(); v8::HandleScope handleScope(isolate); auto callFrame = protocol::Runtime::CallFrame::create() .setFunctionName(toProtocolString(node->GetFunctionName())) .setScriptId(String16::fromInteger(node->GetScriptId())) - .setUrl(toProtocolString(node->GetScriptResourceName())) + .setUrl(resourceNameToUrl(inspector, node->GetScriptResourceName())) .setLineNumber(node->GetLineNumber() - 1) .setColumnNumber(node->GetColumnNumber() - 1) .build(); @@ -107,18 +118,19 @@ std::unique_ptr> buildInspectorObjectForTimestamps( return array; } -void flattenNodesTree(v8::Isolate* isolate, const v8::CpuProfileNode* node, +void flattenNodesTree(V8InspectorImpl* inspector, + const v8::CpuProfileNode* node, protocol::Array* list) { - list->addItem(buildInspectorObjectFor(isolate, node)); + list->addItem(buildInspectorObjectFor(inspector, node)); const int childrenCount = node->GetChildrenCount(); for (int i = 0; i < childrenCount; i++) - flattenNodesTree(isolate, node->GetChild(i), list); + flattenNodesTree(inspector, node->GetChild(i), list); } std::unique_ptr createCPUProfile( - v8::Isolate* isolate, v8::CpuProfile* v8profile) { + V8InspectorImpl* inspector, v8::CpuProfile* v8profile) { auto nodes = protocol::Array::create(); - flattenNodesTree(isolate, v8profile->GetTopDownRoot(), nodes.get()); + flattenNodesTree(inspector, v8profile->GetTopDownRoot(), nodes.get()); return protocol::Profiler::Profile::create() .setNodes(std::move(nodes)) .setStartTime(static_cast(v8profile->GetStartTime())) @@ -320,7 +332,7 @@ std::unique_ptr createCoverageRange( } Response coverageToProtocol( - v8::Isolate* isolate, const v8::debug::Coverage& coverage, + V8InspectorImpl* inspector, const v8::debug::Coverage& coverage, std::unique_ptr>* out_result) { std::unique_ptr> result = @@ -361,8 +373,10 @@ Response coverageToProtocol( } String16 url; v8::Local name; - if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) { + if (script->SourceURL().ToLocal(&name) && name->Length()) { url = toProtocolString(name); + } else if (script->Name().ToLocal(&name) && name->Length()) { + url = resourceNameToUrl(inspector, name); } result->addItem(protocol::Profiler::ScriptCoverage::create() .setScriptId(String16::fromInteger(script->Id())) @@ -384,7 +398,7 @@ Response V8ProfilerAgentImpl::takePreciseCoverage( } v8::HandleScope handle_scope(m_isolate); v8::debug::Coverage coverage = v8::debug::Coverage::CollectPrecise(m_isolate); - return coverageToProtocol(m_isolate, coverage, out_result); + return coverageToProtocol(m_session->inspector(), coverage, out_result); } Response V8ProfilerAgentImpl::getBestEffortCoverage( @@ -393,12 +407,12 @@ Response V8ProfilerAgentImpl::getBestEffortCoverage( v8::HandleScope handle_scope(m_isolate); v8::debug::Coverage coverage = v8::debug::Coverage::CollectBestEffort(m_isolate); - return coverageToProtocol(m_isolate, coverage, out_result); + return coverageToProtocol(m_session->inspector(), coverage, out_result); } namespace { std::unique_ptr> -typeProfileToProtocol(v8::Isolate* isolate, +typeProfileToProtocol(V8InspectorImpl* inspector, const v8::debug::TypeProfile& type_profile) { std::unique_ptr> result = protocol::Array::create(); @@ -426,8 +440,10 @@ typeProfileToProtocol(v8::Isolate* isolate, } String16 url; v8::Local name; - if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) { + if (script->SourceURL().ToLocal(&name) && name->Length()) { url = toProtocolString(name); + } else if (script->Name().ToLocal(&name) && name->Length()) { + url = resourceNameToUrl(inspector, name); } result->addItem(protocol::Profiler::ScriptTypeProfile::create() .setScriptId(String16::fromInteger(script->Id())) @@ -462,7 +478,7 @@ Response V8ProfilerAgentImpl::takeTypeProfile( v8::HandleScope handle_scope(m_isolate); v8::debug::TypeProfile type_profile = v8::debug::TypeProfile::Collect(m_isolate); - *out_result = typeProfileToProtocol(m_isolate, type_profile); + *out_result = typeProfileToProtocol(m_session->inspector(), type_profile); return Response::OK(); } @@ -491,7 +507,7 @@ std::unique_ptr V8ProfilerAgentImpl::stopProfiling( m_profiler->StopProfiling(toV8String(m_isolate, title)); std::unique_ptr result; if (profile) { - if (serialize) result = createCPUProfile(m_isolate, profile); + if (serialize) result = createCPUProfile(m_session->inspector(), profile); profile->Delete(); } --m_startedProfilesCount; diff --git a/deps/v8/src/inspector/v8-stack-trace-impl.cc b/deps/v8/src/inspector/v8-stack-trace-impl.cc index 8c208aaf8a26c2..8d385d0d6d8ad7 100644 --- a/deps/v8/src/inspector/v8-stack-trace-impl.cc +++ b/deps/v8/src/inspector/v8-stack-trace-impl.cc @@ -7,6 +7,7 @@ #include #include "src/inspector/v8-debugger.h" +#include "src/inspector/v8-inspector-impl.h" #include "src/inspector/wasm-translation.h" namespace v8_inspector { @@ -71,7 +72,10 @@ std::unique_ptr buildInspectorObjectCommon( std::unique_ptr> inspectorFrames = protocol::Array::create(); for (size_t i = 0; i < frames.size(); i++) { - inspectorFrames->addItem(frames[i]->buildInspectorObject()); + V8InspectorClient* client = nullptr; + if (debugger && debugger->inspector()) + client = debugger->inspector()->client(); + inspectorFrames->addItem(frames[i]->buildInspectorObject(client)); } std::unique_ptr stackTrace = protocol::Runtime::StackTrace::create() @@ -115,7 +119,9 @@ StackFrame::StackFrame(v8::Local v8Frame) m_scriptId(String16::fromInteger(v8Frame->GetScriptId())), m_sourceURL(toProtocolString(v8Frame->GetScriptNameOrSourceURL())), m_lineNumber(v8Frame->GetLineNumber() - 1), - m_columnNumber(v8Frame->GetColumn() - 1) { + m_columnNumber(v8Frame->GetColumn() - 1), + m_hasSourceURLComment(v8Frame->GetScriptName() != + v8Frame->GetScriptNameOrSourceURL()) { DCHECK_NE(v8::Message::kNoLineNumberInfo, m_lineNumber + 1); DCHECK_NE(v8::Message::kNoColumnInfo, m_columnNumber + 1); } @@ -135,12 +141,20 @@ int StackFrame::lineNumber() const { return m_lineNumber; } int StackFrame::columnNumber() const { return m_columnNumber; } -std::unique_ptr StackFrame::buildInspectorObject() - const { +std::unique_ptr StackFrame::buildInspectorObject( + V8InspectorClient* client) const { + String16 frameUrl = m_sourceURL; + if (client && !m_hasSourceURLComment && frameUrl.length() > 0) { + std::unique_ptr url = + client->resourceNameToUrl(toStringView(m_sourceURL)); + if (url) { + frameUrl = toString16(url->string()); + } + } return protocol::Runtime::CallFrame::create() .setFunctionName(m_functionName) .setScriptId(m_scriptId) - .setUrl(m_sourceURL) + .setUrl(frameUrl) .setLineNumber(m_lineNumber) .setColumnNumber(m_columnNumber) .build(); diff --git a/deps/v8/src/inspector/v8-stack-trace-impl.h b/deps/v8/src/inspector/v8-stack-trace-impl.h index 87d2b0f0270823..513aa41b909c52 100644 --- a/deps/v8/src/inspector/v8-stack-trace-impl.h +++ b/deps/v8/src/inspector/v8-stack-trace-impl.h @@ -33,7 +33,8 @@ class StackFrame { const String16& sourceURL() const; int lineNumber() const; // 0-based. int columnNumber() const; // 0-based. - std::unique_ptr buildInspectorObject() const; + std::unique_ptr buildInspectorObject( + V8InspectorClient* client) const; bool isEqual(StackFrame* frame) const; private: @@ -42,6 +43,7 @@ class StackFrame { String16 m_sourceURL; int m_lineNumber; // 0-based. int m_columnNumber; // 0-based. + bool m_hasSourceURLComment; }; class V8StackTraceImpl : public V8StackTrace { diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc index bb50ae493d5eea..0bdfef5e81b319 100644 --- a/deps/v8/src/isolate.cc +++ b/deps/v8/src/isolate.cc @@ -1661,8 +1661,17 @@ void Isolate::PrintCurrentStackTrace(FILE* out) { Handle receiver(frame->receiver(), this); Handle function(frame->function(), this); - Handle code(AbstractCode::cast(frame->LookupCode()), this); - const int offset = static_cast(frame->pc() - code->InstructionStart()); + Handle code; + int offset; + if (frame->is_interpreted()) { + InterpretedFrame* interpreted_frame = InterpretedFrame::cast(frame); + code = handle(AbstractCode::cast(interpreted_frame->GetBytecodeArray()), + this); + offset = interpreted_frame->GetBytecodeOffset(); + } else { + code = handle(AbstractCode::cast(frame->LookupCode()), this); + offset = static_cast(frame->pc() - code->InstructionStart()); + } JSStackFrame site(this, receiver, function, code, offset); Handle line = site.ToString().ToHandleChecked(); diff --git a/deps/v8/src/libplatform/tracing/tracing-controller.cc b/deps/v8/src/libplatform/tracing/tracing-controller.cc index b4aa7baf724d4f..e0a6a1234c5970 100644 --- a/deps/v8/src/libplatform/tracing/tracing-controller.cc +++ b/deps/v8/src/libplatform/tracing/tracing-controller.cc @@ -63,13 +63,15 @@ uint64_t TracingController::AddTraceEvent( const uint64_t* arg_values, std::unique_ptr* arg_convertables, unsigned int flags) { - uint64_t handle; - TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle); - if (trace_object) { - trace_object->Initialize( - phase, category_enabled_flag, name, scope, id, bind_id, num_args, - arg_names, arg_types, arg_values, arg_convertables, flags, - CurrentTimestampMicroseconds(), CurrentCpuTimestampMicroseconds()); + uint64_t handle = 0; + if (mode_ != DISABLED) { + TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle); + if (trace_object) { + trace_object->Initialize( + phase, category_enabled_flag, name, scope, id, bind_id, num_args, + arg_names, arg_types, arg_values, arg_convertables, flags, + CurrentTimestampMicroseconds(), CurrentCpuTimestampMicroseconds()); + } } return handle; } @@ -81,13 +83,15 @@ uint64_t TracingController::AddTraceEventWithTimestamp( const uint64_t* arg_values, std::unique_ptr* arg_convertables, unsigned int flags, int64_t timestamp) { - uint64_t handle; - TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle); - if (trace_object) { - trace_object->Initialize(phase, category_enabled_flag, name, scope, id, - bind_id, num_args, arg_names, arg_types, - arg_values, arg_convertables, flags, timestamp, - CurrentCpuTimestampMicroseconds()); + uint64_t handle = 0; + if (mode_ != DISABLED) { + TraceObject* trace_object = trace_buffer_->AddTraceEvent(&handle); + if (trace_object) { + trace_object->Initialize(phase, category_enabled_flag, name, scope, id, + bind_id, num_args, arg_names, arg_types, + arg_values, arg_convertables, flags, timestamp, + CurrentCpuTimestampMicroseconds()); + } } return handle; } diff --git a/deps/v8/test/inspector/debugger/resource-name-to-url-expected.txt b/deps/v8/test/inspector/debugger/resource-name-to-url-expected.txt new file mode 100644 index 00000000000000..2e6e589b2517d3 --- /dev/null +++ b/deps/v8/test/inspector/debugger/resource-name-to-url-expected.txt @@ -0,0 +1,122 @@ +Tests V8InspectorClient::resourceNameToUrl. +Check script with url: +{ + method : Debugger.scriptParsed + params : { + endColumn : 16 + endLine : 0 + executionContextId : + hasSourceURL : false + hash : 033b33d191ed51ed823355d865eb871d811403e2 + isLiveEdit : false + isModule : false + length : 16 + scriptId : + sourceMapURL : + startColumn : 0 + startLine : 0 + url : prefix://url + } +} +Check script with sourceURL comment: +{ + method : Debugger.scriptParsed + params : { + endColumn : 37 + endLine : 0 + executionContextId : + hasSourceURL : true + hash : 06c136ce206c5f505f32af524e6ec71b5baa0bbb + isLiveEdit : false + isModule : false + length : 37 + scriptId : + sourceMapURL : + startColumn : 0 + startLine : 0 + url : foo.js + } +} +Check script failed to parse: +{ + method : Debugger.scriptFailedToParse + params : { + endColumn : 15 + endLine : 0 + executionContextId : + hasSourceURL : false + hash : 033b33d191ed51ed1f44cd0465eb871d811403e2 + isModule : false + length : 15 + scriptId : + sourceMapURL : + startColumn : 0 + startLine : 0 + url : prefix://url + } +} +Check script failed to parse with sourceURL comment: +{ + method : Debugger.scriptFailedToParse + params : { + endColumn : 36 + endLine : 0 + executionContextId : + hasSourceURL : true + hash : 23a2885951475580023e2a742563d78876d8f05e + isModule : false + length : 36 + scriptId : + sourceMapURL : + startColumn : 0 + startLine : 0 + url : foo.js + } +} +Test runtime stack trace: +{ + method : Runtime.consoleAPICalled + params : { + args : [ + [0] : { + description : 42 + type : number + value : 42 + } + ] + executionContextId : + stackTrace : { + callFrames : [ + [0] : { + columnNumber : 14 + functionName : foo + lineNumber : 2 + scriptId : + url : prefix://url + } + [1] : { + columnNumber : 0 + functionName : + lineNumber : 0 + scriptId : + url : boo.js + } + [2] : { + columnNumber : 4 + functionName : + lineNumber : 4 + scriptId : + url : prefix://url + } + ] + } + timestamp : + type : log + } +} +Test debugger stack trace: +[ + [0] : prefix://url + [1] : boo.js + [2] : prefix://url +] diff --git a/deps/v8/test/inspector/debugger/resource-name-to-url.js b/deps/v8/test/inspector/debugger/resource-name-to-url.js new file mode 100644 index 00000000000000..620c7a2864b406 --- /dev/null +++ b/deps/v8/test/inspector/debugger/resource-name-to-url.js @@ -0,0 +1,49 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let {session, contextGroup, Protocol} = InspectorTest.start( + 'Tests V8InspectorClient::resourceNameToUrl.'); + +(async function test(){ + Protocol.Runtime.enable(); + await Protocol.Debugger.enable(); + contextGroup.addScript(`inspector.setResourceNamePrefix('prefix://')`); + await Protocol.Debugger.onceScriptParsed(); + + InspectorTest.log('Check script with url:'); + contextGroup.addScript('function foo(){}', 0, 0, 'url'); + InspectorTest.logMessage(await Protocol.Debugger.onceScriptParsed()); + + InspectorTest.log('Check script with sourceURL comment:'); + contextGroup.addScript('function foo(){} //# sourceURL=foo.js', 0, 0, 'url'); + InspectorTest.logMessage(await Protocol.Debugger.onceScriptParsed()); + + InspectorTest.log('Check script failed to parse:'); + contextGroup.addScript('function foo(){', 0, 0, 'url'); + InspectorTest.logMessage(await Protocol.Debugger.onceScriptFailedToParse()); + + InspectorTest.log('Check script failed to parse with sourceURL comment:'); + contextGroup.addScript('function foo(){ //# sourceURL=foo.js', 0, 0, 'url'); + InspectorTest.logMessage(await Protocol.Debugger.onceScriptFailedToParse()); + + InspectorTest.log('Test runtime stack trace:'); + contextGroup.addScript(` + function foo() { + console.log(42); + } + eval('foo(); //# sourceURL=boo.js'); + `, 0, 0, 'url'); + InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled()); + + InspectorTest.log('Test debugger stack trace:'); + contextGroup.addScript(` + function foo() { + debugger; + } + eval('foo(); //# sourceURL=boo.js'); + `, 0, 0, 'url'); + const {params:{callFrames}} = await Protocol.Debugger.oncePaused(); + InspectorTest.logMessage(callFrames.map(frame => frame.url)); + InspectorTest.completeTest(); +})(); diff --git a/deps/v8/test/inspector/inspector-test.cc b/deps/v8/test/inspector/inspector-test.cc index 668a9463d5b9cf..93a8b1d3f21880 100644 --- a/deps/v8/test/inspector/inspector-test.cc +++ b/deps/v8/test/inspector/inspector-test.cc @@ -712,6 +712,9 @@ class InspectorExtension : public IsolateData::SetupGlobalTask { ToV8String(isolate, "setAllowCodeGenerationFromStrings"), v8::FunctionTemplate::New( isolate, &InspectorExtension::SetAllowCodeGenerationFromStrings)); + inspector->Set(ToV8String(isolate, "setResourceNamePrefix"), + v8::FunctionTemplate::New( + isolate, &InspectorExtension::SetResourceNamePrefix)); global->Set(ToV8String(isolate, "inspector"), inspector); } @@ -973,6 +976,18 @@ class InspectorExtension : public IsolateData::SetupGlobalTask { args.GetIsolate()->GetCurrentContext()->AllowCodeGenerationFromStrings( args[0].As()->Value()); } + + static void SetResourceNamePrefix( + const v8::FunctionCallbackInfo& args) { + if (args.Length() != 1 || !args[0]->IsString()) { + fprintf(stderr, "Internal error: setResourceNamePrefix('prefix')."); + Exit(); + } + v8::Isolate* isolate = args.GetIsolate(); + v8::Local context = isolate->GetCurrentContext(); + IsolateData* data = IsolateData::FromContext(context); + data->SetResourceNamePrefix(v8::Local::Cast(args[0])); + } }; bool RunExtraCode(v8::Isolate* isolate, v8::Local context, diff --git a/deps/v8/test/inspector/isolate-data.cc b/deps/v8/test/inspector/isolate-data.cc index a18ef90ca04b98..04c449927eb767 100644 --- a/deps/v8/test/inspector/isolate-data.cc +++ b/deps/v8/test/inspector/isolate-data.cc @@ -422,3 +422,32 @@ void IsolateData::maxAsyncCallStackDepthChanged(int depth) { if (!log_max_async_call_stack_depth_changed_) return; fprintf(stdout, "maxAsyncCallStackDepthChanged: %d\n", depth); } + +void IsolateData::SetResourceNamePrefix(v8::Local prefix) { + resource_name_prefix_.Reset(v8::Isolate::GetCurrent(), prefix); +} + +namespace { +class StringBufferImpl : public v8_inspector::StringBuffer { + public: + StringBufferImpl(v8::Isolate* isolate, v8::Local string) + : data_(ToVector(string)), + view_(data_.start(), data_.length()) {} + const v8_inspector::StringView& string() override { return view_; } + + private: + v8::internal::Vector data_; + v8_inspector::StringView view_; +}; +} // anonymous namespace + +std::unique_ptr IsolateData::resourceNameToUrl( + const v8_inspector::StringView& resourceName) { + if (resource_name_prefix_.IsEmpty()) return nullptr; + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope handle_scope(isolate); + v8::Local name = ToString(isolate, resourceName); + v8::Local prefix = resource_name_prefix_.Get(isolate); + v8::Local url = v8::String::Concat(prefix, name); + return std::unique_ptr(new StringBufferImpl(isolate, url)); +} diff --git a/deps/v8/test/inspector/isolate-data.h b/deps/v8/test/inspector/isolate-data.h index 5eb9803a7416fb..d0a263e573827c 100644 --- a/deps/v8/test/inspector/isolate-data.h +++ b/deps/v8/test/inspector/isolate-data.h @@ -76,6 +76,7 @@ class IsolateData : public v8_inspector::V8InspectorClient { void FireContextCreated(v8::Local context, int context_group_id); void FireContextDestroyed(v8::Local context); void FreeContext(v8::Local context); + void SetResourceNamePrefix(v8::Local prefix); private: struct VectorCompare { @@ -114,6 +115,8 @@ class IsolateData : public v8_inspector::V8InspectorClient { v8_inspector::V8StackTrace*) override; bool isInspectableHeapObject(v8::Local) override; void maxAsyncCallStackDepthChanged(int depth) override; + std::unique_ptr resourceNameToUrl( + const v8_inspector::StringView& resourceName) override; // The isolate gets deleted by its {Dispose} method, not by the default // deleter. Therefore we have to define a custom deleter for the unique_ptr to @@ -141,6 +144,7 @@ class IsolateData : public v8_inspector::V8InspectorClient { bool log_console_api_message_calls_ = false; bool log_max_async_call_stack_depth_changed_ = false; v8::Global not_inspectable_private_; + v8::Global resource_name_prefix_; DISALLOW_COPY_AND_ASSIGN(IsolateData); }; diff --git a/doc/api/addons.md b/doc/api/addons.md index 483f2ad27d7feb..5e06336a85a4a0 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -848,6 +848,13 @@ console.log(obj.plusOne()); // Prints: 13 ``` +The destructor for a wrapper object will run when the object is +garbage-collected. For destructor testing, there are command-line flags that +can be used to make it possible to force garbage collection. These flags are +provided by the underlying V8 JavaScript engine. They are subject to change +or removal at any time. They are not documented by Node.js or V8, and they +should never be used outside of testing. + ### Factory of wrapped objects Alternatively, it is possible to use a factory pattern to avoid explicitly diff --git a/doc/api/crypto.md b/doc/api/crypto.md index a027efba85e7df..2331af12aceae7 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1124,6 +1124,8 @@ changes: * `privateKey` {string | Object} - `key` {string} - `passphrase` {string} + - `padding` {integer} + - `saltLength` {integer} * `outputFormat` {string} * Returns: {Buffer | string} @@ -1806,6 +1808,9 @@ otherwise `err` will be `null`. By default, the successfully generated `derivedKey` will be passed to the callback as a [`Buffer`][]. An error will be thrown if any of the input arguments specify invalid values or types. +If `digest` is `null`, `'sha1'` will be used. This behavior will be deprecated +in a future version of Node.js. + The `iterations` argument must be a number set as high as possible. The higher the number of iterations, the more secure the derived key will be, but will take a longer amount of time to complete. @@ -1869,6 +1874,9 @@ applied to derive a key of the requested byte length (`keylen`) from the If an error occurs an `Error` will be thrown, otherwise the derived key will be returned as a [`Buffer`][]. +If `digest` is `null`, `'sha1'` will be used. This behavior will be deprecated +in a future version of Node.js. + The `iterations` argument must be a number set as high as possible. The higher the number of iterations, the more secure the derived key will be, but will take a longer amount of time to complete. @@ -1910,7 +1918,8 @@ added: v0.11.14 * `buffer` {Buffer | TypedArray | DataView} * Returns: {Buffer} A new `Buffer` with the decrypted content. -Decrypts `buffer` with `privateKey`. +Decrypts `buffer` with `privateKey`. `buffer` was previously encrypted using +the corresponding public key, for example using [`crypto.publicEncrypt()`][]. `privateKey` can be an object or a string. If `privateKey` is a string, it is treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`. @@ -1928,7 +1937,8 @@ added: v1.1.0 * `buffer` {Buffer | TypedArray | DataView} * Returns: {Buffer} A new `Buffer` with the encrypted content. -Encrypts `buffer` with `privateKey`. +Encrypts `buffer` with `privateKey`. The returned data can be decrypted using +the corresponding public key, for example using [`crypto.publicDecrypt()`][]. `privateKey` can be an object or a string. If `privateKey` is a string, it is treated as the key with no passphrase and will use `RSA_PKCS1_PADDING`. @@ -1946,7 +1956,8 @@ added: v1.1.0 * `buffer` {Buffer | TypedArray | DataView} * Returns: {Buffer} A new `Buffer` with the decrypted content. -Decrypts `buffer` with `key`. +Decrypts `buffer` with `key`.`buffer` was previously encrypted using +the corresponding private key, for example using [`crypto.privateEncrypt()`][]. `key` can be an object or a string. If `key` is a string, it is treated as the key with no passphrase and will use `RSA_PKCS1_PADDING`. @@ -1969,7 +1980,8 @@ added: v0.11.14 * Returns: {Buffer} A new `Buffer` with the encrypted content. Encrypts the content of `buffer` with `key` and returns a new -[`Buffer`][] with encrypted content. +[`Buffer`][] with encrypted content. The returned data can be decrypted using +the corresponding private key, for example using [`crypto.privateDecrypt()`][]. `key` can be an object or a string. If `key` is a string, it is treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`. @@ -2763,6 +2775,10 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. [`crypto.createVerify()`]: #crypto_crypto_createverify_algorithm_options [`crypto.getCurves()`]: #crypto_crypto_getcurves [`crypto.getHashes()`]: #crypto_crypto_gethashes +[`crypto.privateDecrypt()`]: #crypto_crypto_privatedecrypt_privatekey_buffer +[`crypto.privateEncrypt()`]: #crypto_crypto_privateencrypt_privatekey_buffer +[`crypto.publicDecrypt()`]: #crypto_crypto_publicdecrypt_key_buffer +[`crypto.publicEncrypt()`]: #crypto_crypto_publicencrypt_key_buffer [`crypto.randomBytes()`]: #crypto_crypto_randombytes_size_callback [`crypto.randomFill()`]: #crypto_crypto_randomfill_buffer_offset_size_callback [`crypto.scrypt()`]: #crypto_crypto_scrypt_password_salt_keylen_options_callback diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 2c30cd9619596a..3e880a0cc68218 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -40,6 +40,17 @@ However, the deprecation identifier will not be modified. ### DEP0001: http.OutgoingMessage.prototype.flush + Type: Runtime @@ -48,6 +59,18 @@ The `OutgoingMessage.prototype.flush()` method is deprecated. Use ### DEP0002: require('\_linklist') + Type: End-of-Life @@ -55,6 +78,17 @@ The `_linklist` module is deprecated. Please use a userland alternative. ### DEP0003: \_writableState.buffer + Type: Runtime @@ -63,6 +97,20 @@ The `_writableState.buffer` property is deprecated. Use the ### DEP0004: CryptoStream.prototype.readyState + Type: End-of-Life @@ -70,6 +118,18 @@ The `CryptoStream.prototype.readyState` property was removed. ### DEP0005: Buffer() constructor + Type: Runtime (supports [`--pending-deprecation`][]) @@ -98,6 +158,18 @@ outside `node_modules` in order to better target developers, rather than users. ### DEP0006: child\_process options.customFds + Type: Runtime @@ -107,6 +179,21 @@ option should be used instead. ### DEP0007: Replace cluster worker.suicide with worker.exitedAfterDisconnect + Type: End-of-Life @@ -119,6 +206,15 @@ precisely describe the actual semantics and was unnecessarily emotion-laden. ### DEP0008: require('constants') + Type: Documentation-only @@ -129,6 +225,18 @@ to the `constants` property exposed by the relevant module. For instance, ### DEP0009: crypto.pbkdf2 without digest + Type: End-of-Life @@ -140,6 +248,17 @@ undefined `digest` will throw a `TypeError`. ### DEP0010: crypto.createCredentials + Type: Runtime @@ -148,6 +267,17 @@ The [`crypto.createCredentials()`][] API is deprecated. Please use ### DEP0011: crypto.Credentials + Type: Runtime @@ -156,6 +286,20 @@ instead. ### DEP0012: Domain.dispose + Type: End-of-Life @@ -164,6 +308,15 @@ explicitly via error event handlers set on the domain instead. ### DEP0013: fs asynchronous function without callback + Type: End-of-Life @@ -172,6 +325,23 @@ in Node.js 10.0.0 onwards. (See https://github.com/nodejs/node/pull/12562.) ### DEP0014: fs.read legacy String interface + Type: End-of-Life @@ -180,6 +350,23 @@ API as mentioned in the documentation instead. ### DEP0015: fs.readSync legacy String interface + Type: End-of-Life @@ -188,6 +375,15 @@ The [`fs.readSync()`][] legacy `String` interface is deprecated. Use the ### DEP0016: GLOBAL/root + Type: Runtime @@ -196,6 +392,15 @@ and should no longer be used. ### DEP0017: Intl.v8BreakIterator + Type: End-of-Life @@ -204,6 +409,12 @@ See [`Intl.Segmenter`](https://github.com/tc39/proposal-intl-segmenter). ### DEP0018: Unhandled promise rejections + Type: Runtime @@ -213,6 +424,17 @@ code. ### DEP0019: require('.') resolved outside directory + Type: Runtime @@ -222,6 +444,17 @@ release. ### DEP0020: Server.connections + Type: Runtime @@ -230,6 +463,17 @@ The [`Server.connections`][] property is deprecated. Please use the ### DEP0021: Server.listenFD + Type: Runtime @@ -238,6 +482,12 @@ The `Server.listenFD()` method is deprecated. Please use ### DEP0022: os.tmpDir() + Type: Runtime @@ -245,6 +495,17 @@ The `os.tmpDir()` API is deprecated. Please use [`os.tmpdir()`][] instead. ### DEP0023: os.getNetworkInterfaces() + Type: Runtime @@ -253,6 +514,15 @@ The `os.getNetworkInterfaces()` method is deprecated. Please use the ### DEP0024: REPLServer.prototype.convertToContext() + Type: End-of-Life @@ -260,6 +530,17 @@ The `REPLServer.prototype.convertToContext()` API has been removed. ### DEP0025: require('sys') + Type: Runtime @@ -267,6 +548,17 @@ The `sys` module is deprecated. Please use the [`util`][] module instead. ### DEP0026: util.print() + Type: Runtime @@ -275,6 +567,17 @@ instead. ### DEP0027: util.puts() + Type: Runtime @@ -282,6 +585,17 @@ The [`util.puts()`][] API is deprecated. Please use [`console.log()`][] instead. ### DEP0028: util.debug() + Type: Runtime @@ -290,6 +604,17 @@ instead. ### DEP0029: util.error() + Type: Runtime @@ -298,6 +623,15 @@ instead. ### DEP0030: SlowBuffer + Type: Documentation-only @@ -306,6 +640,15 @@ The [`SlowBuffer`][] class is deprecated. Please use ### DEP0031: ecdh.setPublicKey() + Type: Documentation-only @@ -314,6 +657,17 @@ API is not useful. ### DEP0032: domain module + Type: Documentation-only @@ -321,6 +675,17 @@ The [`domain`][] module is deprecated and should not be used. ### DEP0033: EventEmitter.listenerCount() + Type: Documentation-only @@ -329,6 +694,17 @@ deprecated. Please use [`emitter.listenerCount(eventName)`][] instead. ### DEP0034: fs.exists(path, callback) + Type: Documentation-only @@ -337,6 +713,16 @@ The [`fs.exists(path, callback)`][] API is deprecated. Please use ### DEP0035: fs.lchmod(path, mode, callback) + Type: Documentation-only @@ -344,13 +730,74 @@ The [`fs.lchmod(path, mode, callback)`][] API is deprecated. ### DEP0036: fs.lchmodSync(path, mode) + Type: Documentation-only The [`fs.lchmodSync(path, mode)`][] API is deprecated. + +### DEP0037: fs.lchown(path, uid, gid, callback) + + +Type: Deprecation revoked + +The [`fs.lchown(path, uid, gid, callback)`][] API is deprecated. + + +### DEP0038: fs.lchownSync(path, uid, gid) + + +Type: Deprecation revoked + +The [`fs.lchownSync(path, uid, gid)`][] API is deprecated. + ### DEP0039: require.extensions + Type: Documentation-only @@ -358,6 +805,12 @@ The [`require.extensions`][] property is deprecated. ### DEP0040: punycode module + Type: Documentation-only @@ -366,6 +819,20 @@ instead. ### DEP0041: NODE\_REPL\_HISTORY\_FILE environment variable + Type: End-of-Life @@ -374,6 +841,20 @@ The `NODE_REPL_HISTORY_FILE` environment variable was removed. Please use ### DEP0042: tls.CryptoStream + Type: End-of-Life @@ -382,6 +863,26 @@ The [`tls.CryptoStream`][] class was removed. Please use ### DEP0043: tls.SecurePair + Type: Documentation-only @@ -390,6 +891,19 @@ The [`tls.SecurePair`][] class is deprecated. Please use ### DEP0044: util.isArray() + Type: Documentation-only @@ -398,6 +912,19 @@ instead. ### DEP0045: util.isBoolean() + Type: Documentation-only @@ -405,6 +932,19 @@ The [`util.isBoolean()`][] API is deprecated. ### DEP0046: util.isBuffer() + Type: Documentation-only @@ -413,6 +953,19 @@ The [`util.isBuffer()`][] API is deprecated. Please use ### DEP0047: util.isDate() + Type: Documentation-only @@ -420,6 +973,19 @@ The [`util.isDate()`][] API is deprecated. ### DEP0048: util.isError() + Type: Documentation-only @@ -427,6 +993,19 @@ The [`util.isError()`][] API is deprecated. ### DEP0049: util.isFunction() + Type: Documentation-only @@ -434,6 +1013,19 @@ The [`util.isFunction()`][] API is deprecated. ### DEP0050: util.isNull() + Type: Documentation-only @@ -441,6 +1033,19 @@ The [`util.isNull()`][] API is deprecated. ### DEP0051: util.isNullOrUndefined() + Type: Documentation-only @@ -448,6 +1053,19 @@ The [`util.isNullOrUndefined()`][] API is deprecated. ### DEP0052: util.isNumber() + Type: Documentation-only @@ -455,6 +1073,19 @@ The [`util.isNumber()`][] API is deprecated. ### DEP0053 util.isObject() + Type: Documentation-only @@ -462,6 +1093,19 @@ The [`util.isObject()`][] API is deprecated. ### DEP0054: util.isPrimitive() + Type: Documentation-only @@ -469,6 +1113,19 @@ The [`util.isPrimitive()`][] API is deprecated. ### DEP0055: util.isRegExp() + Type: Documentation-only @@ -476,6 +1133,19 @@ The [`util.isRegExp()`][] API is deprecated. ### DEP0056: util.isString() + Type: Documentation-only @@ -483,6 +1153,19 @@ The [`util.isString()`][] API is deprecated. ### DEP0057: util.isSymbol() + Type: Documentation-only @@ -490,6 +1173,19 @@ The [`util.isSymbol()`][] API is deprecated. ### DEP0058: util.isUndefined() + Type: Documentation-only @@ -497,6 +1193,15 @@ The [`util.isUndefined()`][] API is deprecated. ### DEP0059: util.log() + Type: Documentation-only @@ -504,6 +1209,15 @@ The [`util.log()`][] API is deprecated. ### DEP0060: util.\_extend() + Type: Documentation-only @@ -511,6 +1225,15 @@ The [`util._extend()`][] API is deprecated. ### DEP0061: fs.SyncWriteStream + Type: Runtime @@ -519,6 +1242,12 @@ API. No alternative API is available. Please use a userland alternative. ### DEP0062: node --debug + Type: Runtime @@ -528,6 +1257,12 @@ instead. ### DEP0063: ServerResponse.prototype.writeHeader() + Type: Documentation-only @@ -539,6 +1274,26 @@ officially supported API. ### DEP0064: tls.createSecurePair() + Type: Runtime @@ -547,6 +1302,15 @@ The `tls.createSecurePair()` API was deprecated in documentation in Node.js ### DEP0065: repl.REPL_MODE_MAGIC and NODE_REPL_MODE=magic + Type: End-of-Life @@ -561,6 +1325,12 @@ removed. Please use `sloppy` instead. ### DEP0066: outgoingMessage.\_headers, outgoingMessage.\_headerNames + Type: Documentation-only @@ -576,6 +1346,12 @@ were never documented as officially supported properties. ### DEP0067: OutgoingMessage.prototype.\_renderHeaders + Type: Documentation-only @@ -587,6 +1363,12 @@ an officially supported API. ### DEP0068: node debug + Type: Runtime @@ -595,6 +1377,18 @@ a V8-inspector based CLI debugger available through `node inspect`. ### DEP0069: vm.runInDebugContext(string) + Type: End-of-Life @@ -604,6 +1398,15 @@ DebugContext was an experimental API. ### DEP0070: async_hooks.currentId() + Type: End-of-Life @@ -614,6 +1417,15 @@ This change was made while `async_hooks` was an experimental API. ### DEP0071: async_hooks.triggerId() + Type: End-of-Life @@ -624,6 +1436,15 @@ This change was made while `async_hooks` was an experimental API. ### DEP0072: async_hooks.AsyncResource.triggerId() + Type: End-of-Life @@ -634,6 +1455,15 @@ This change was made while `async_hooks` was an experimental API. ### DEP0073: Several internal properties of net.Server + Type: End-of-Life @@ -645,6 +1475,12 @@ code, no replacement API is provided. ### DEP0074: REPLServer.bufferedCommand + Type: Runtime @@ -653,6 +1489,12 @@ The `REPLServer.bufferedCommand` property was deprecated in favor of ### DEP0075: REPLServer.parseREPLKeyword() + Type: Runtime @@ -660,6 +1502,15 @@ Type: Runtime ### DEP0076: tls.parseCertString() + Type: Runtime @@ -683,6 +1534,12 @@ difference is that `querystring.parse()` does url decoding: ### DEP0077: Module.\_debug() + Type: Runtime @@ -693,6 +1550,12 @@ supported API. ### DEP0078: REPLServer.turnOffEditorMode() + Type: Runtime @@ -700,6 +1563,15 @@ Type: Runtime ### DEP0079: Custom inspection function on Objects via .inspect() + Type: Runtime @@ -710,6 +1582,12 @@ may be specified. ### DEP0080: path.\_makeLong() + Type: Documentation-only @@ -719,6 +1597,12 @@ and replaced with an identical, public `path.toNamespacedPath()` method. ### DEP0081: fs.truncate() using a file descriptor + Type: Runtime @@ -728,6 +1612,12 @@ file descriptors. ### DEP0082: REPLServer.prototype.memory() + Type: Runtime @@ -736,6 +1626,12 @@ the `REPLServer` itself. Do not use this function. ### DEP0083: Disabling ECDH by setting ecdhCurve to false + Type: Runtime @@ -746,6 +1642,12 @@ the client. Use the `ciphers` parameter instead. ### DEP0084: requiring bundled internal dependencies + Type: Runtime @@ -777,6 +1679,17 @@ code modification is necessary if that is done. ### DEP0085: AsyncHooks Sensitive API + Type: End-of-Life @@ -786,6 +1699,17 @@ API instead. ### DEP0086: Remove runInAsyncIdScope + Type: End-of-Life @@ -795,6 +1719,14 @@ details. ### DEP0089: require('assert') + Type: Documentation-only @@ -804,6 +1736,12 @@ same as the legacy assert but it will always use strict equality checks. ### DEP0090: Invalid GCM authentication tag lengths + Type: Runtime @@ -816,6 +1754,12 @@ is not included in this list will be considered invalid in compliance with ### DEP0091: crypto.DEFAULT_ENCODING + Type: Runtime @@ -823,6 +1767,12 @@ The [`crypto.DEFAULT_ENCODING`][] property is deprecated. ### DEP0092: Top-level `this` bound to `module.exports` + Type: Documentation-only @@ -832,6 +1782,12 @@ or `module.exports` instead. ### DEP0093: crypto.fips is deprecated and replaced. + Type: Documentation-only @@ -840,6 +1796,12 @@ and `crypto.getFips()` instead. ### DEP0094: Using `assert.fail()` with more than one argument. + Type: Runtime @@ -849,6 +1811,12 @@ method. ### DEP0095: timers.enroll() + Type: Runtime @@ -857,6 +1825,12 @@ Type: Runtime ### DEP0096: timers.unenroll() + Type: Runtime @@ -865,6 +1839,12 @@ Type: Runtime ### DEP0097: MakeCallback with domain property + Type: Runtime @@ -874,6 +1854,15 @@ should start using the `async_context` variant of `MakeCallback` or ### DEP0098: AsyncHooks Embedder AsyncResource.emitBefore and AsyncResource.emitAfter APIs + Type: Runtime @@ -887,6 +1876,12 @@ https://github.com/nodejs/node/pull/18513 for more details. ### DEP0099: async context-unaware node::MakeCallback C++ APIs + Type: Compile-time @@ -896,6 +1891,14 @@ parameter. ### DEP0100: process.assert() + Type: Runtime @@ -905,6 +1908,12 @@ This was never a documented feature. ### DEP0101: --with-lttng + Type: End-of-Life @@ -912,6 +1921,12 @@ The `--with-lttng` compile-time option has been removed. ### DEP0102: Using `noAssert` in Buffer#(read|write) operations. + Type: End-of-Life @@ -921,6 +1936,15 @@ could lead to hard to find errors and crashes. ### DEP0103: process.binding('util').is[...] typechecks + Type: Documentation-only (supports [`--pending-deprecation`][]) @@ -932,6 +1956,12 @@ This deprecation has been superseded by the deprecation of the ### DEP0104: process.env string coercion + Type: Documentation-only (supports [`--pending-deprecation`][]) @@ -943,6 +1973,12 @@ assigning it to `process.env`. ### DEP0105: decipher.finaltol + Type: Runtime @@ -952,6 +1988,12 @@ is recommended to use [`decipher.final()`][] instead. ### DEP0106: crypto.createCipher and crypto.createDecipher + Type: Documentation-only @@ -964,6 +2006,12 @@ initialization vectors. It is recommended to derive a key using ### DEP0107: tls.convertNPNProtocols() + Type: Runtime @@ -972,6 +2020,12 @@ core and obsoleted by the removal of NPN (Next Protocol Negotiation) support. ### DEP0108: zlib.bytesRead + Type: Documentation-only @@ -982,6 +2036,12 @@ expose values under these names. ### DEP0110: vm.Script cached data + Type: Documentation-only @@ -990,6 +2050,12 @@ The `produceCachedData` option is deprecated. Use ### DEP0111: process.binding() + Type: Documentation-only @@ -1033,6 +2099,8 @@ only. Use of `process.binding()` by userland code is unsupported. [`fs.exists(path, callback)`]: fs.html#fs_fs_exists_path_callback [`fs.lchmod(path, mode, callback)`]: fs.html#fs_fs_lchmod_path_mode_callback [`fs.lchmodSync(path, mode)`]: fs.html#fs_fs_lchmodsync_path_mode +[`fs.lchown(path, uid, gid, callback)`]: fs.html#fs_fs_lchown_path_uid_gid_callback +[`fs.lchownSync(path, uid, gid)`]: fs.html#fs_fs_lchownsync_path_uid_gid [`fs.read()`]: fs.html#fs_fs_read_fd_buffer_offset_length_position_callback [`fs.readSync()`]: fs.html#fs_fs_readsync_fd_buffer_offset_length_position [`fs.stat()`]: fs.html#fs_fs_stat_path_options_callback diff --git a/doc/api/dns.md b/doc/api/dns.md index 1d988d8b574e23..cbe0e8628d71f7 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -1078,7 +1078,7 @@ implications for some applications, see the [`UV_THREADPOOL_SIZE`][] documentation for more information. Note that various networking APIs will call `dns.lookup()` internally to resolve -host names. If that is an issue, consider resolving the hostname to and address +host names. If that is an issue, consider resolving the hostname to an address using `dns.resolve()` and using the address instead of a host name. Also, some networking APIs (such as [`socket.connect()`][] and [`dgram.createSocket()`][]) allow the default resolver, `dns.lookup()`, to be replaced. diff --git a/doc/api/fs.md b/doc/api/fs.md index 25cb3fc7f87ee2..338569a4deb445 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -2139,7 +2139,7 @@ changes: Synchronous lstat(2). -## fs.mkdir(path[, mode], callback) +## fs.mkdir(path[, options], callback) * `path` {string|Buffer|URL} -* `mode` {integer} Not supported on Windows. **Default:** `0o777`. +* `options` {Object|integer} + * `recursive` {boolean} **Default:** `false` + * `mode` {integer} Not supported on Windows. **Default:** `0o777`. * `callback` {Function} * `err` {Error} Asynchronously creates a directory. No arguments other than a possible exception are given to the completion callback. +The optional `options` argument can be an integer specifying mode (permission +and sticky bits), or an object with a `mode` property and a `recursive` +property indicating whether parent folders should be created. + +```js +// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist. +fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => { + if (err) throw err; +}); +``` + See also: mkdir(2). -## fs.mkdirSync(path[, mode]) +## fs.mkdirSync(path[, options]) * `path` {string|Buffer|URL} -* `mode` {integer} Not supported on Windows. **Default:** `0o777`. +* `options` {Object|integer} + * `recursive` {boolean} **Default:** `false` + * `mode` {integer} Not supported on Windows. **Default:** `0o777`. Synchronously creates a directory. Returns `undefined`. This is the synchronous version of [`fs.mkdir()`][]. @@ -2380,6 +2395,9 @@ a `Promise` for an `Object` with `bytesRead` and `buffer` properties. * `path` {string|Buffer|URL} -* `mode` {integer} **Default:** `0o777` +* `options` {Object|integer} + * `recursive` {boolean} **Default:** `false` + * `mode` {integer} Not supported on Windows. **Default:** `0o777`. * Returns: {Promise} Asynchronously creates a directory then resolves the `Promise` with no arguments upon success. +The optional `options` argument can be an integer specifying mode (permission +and sticky bits), or an object with a `mode` property and a `recursive` +property indicating whether parent folders should be created. + ### fsPromises.mkdtemp(prefix[, options]) * `path` {string|Buffer|URL} * `options` {string|Object} * `encoding` {string} **Default:** `'utf8'` + * `withFileTypes` {boolean} **Default:** `false` * Returns: {Promise} Reads the contents of a directory then resolves the `Promise` with an array @@ -4179,6 +4211,9 @@ object with an `encoding` property specifying the character encoding to use for the filenames. If the `encoding` is set to `'buffer'`, the filenames returned will be passed as `Buffer` objects. +If `options.withFileTypes` is set to `true`, the resolved array will contain +[`fs.Dirent`][] objects. + ### fsPromises.readFile(path[, options]) + +* {boolean} + +Set the `true` if the `END_STREAM` flag was set in the request or response +HEADERS frame received, indicating that no additional data should be received +and the readable side of the `Http2Stream` will be closed. + #### http2stream.pending + +* `msecs` {number} **Default:** `120000` (2 minutes) +* `callback` {Function} +* Returns: {Http2Server} + +Used to set the timeout value for http2 server requests, +and sets a callback function that is called when there is no activity +on the `Http2Server` after `msecs` milliseconds. + +The given callback is registered as a listener on the `'timeout'` event. + +In case of no callback function were assigned, a new `ERR_INVALID_CALLBACK` +error will be thrown. + ### Class: Http2SecureServer + +* `msecs` {number} **Default:** `120000` (2 minutes) +* `callback` {Function} +* Returns: {Http2SecureServer} + +Used to set the timeout value for http2 secure server requests, +and sets a callback function that is called when there is no activity +on the `Http2SecureServer` after `msecs` milliseconds. + +The given callback is registered as a listener on the `'timeout'` event. + +In case of no callback function were assigned, a new `ERR_INVALID_CALLBACK` +error will be thrown. + ### http2.createServer(options[, onRequestHandler]) + +* `filename` {string} Filename to be used to construct the relative require + function. +* Returns: {[`require`][]} Require function + +```js +const { createRequireFromPath } = require('module'); +const requireUtil = createRequireFromPath('../src/utils'); + +// require `../src/utils/some-tool` +requireUtil('./some-tool'); +``` + [`__dirname`]: #modules_dirname [`__filename`]: #modules_filename [`Error`]: errors.html#errors_class_error [`module` object]: #modules_the_module_object [`path.dirname()`]: path.html#path_path_dirname_path [GLOBAL_FOLDERS]: #modules_loading_from_the_global_folders +[`require`]: #modules_require [exports shortcut]: #modules_exports_shortcut [module resolution]: #modules_all_together [module wrapper]: #modules_the_module_wrapper diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 4f27d8c55223d6..3bee50b7f6d4ca 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -3238,6 +3238,11 @@ JavaScript functions from native code. One can either call a function like a regular JavaScript function call, or as a constructor function. +Any non-`NULL` data which is passed to this API via the `data` field of the +`napi_property_descriptor` items can be associated with `object` and freed +whenever `object` is garbage-collected by passing both `object` and the data to +[`napi_add_finalizer`][]. + ### napi_call_function +```C +napi_status napi_add_finalizer(napi_env env, + napi_value js_object, + void* native_object, + napi_finalize finalize_cb, + void* finalize_hint, + napi_ref* result); +``` + + - `[in] env`: The environment that the API is invoked under. + - `[in] js_object`: The JavaScript object to which the native data will be + attached. + - `[in] native_object`: The native data that will be attached to the JavaScript + object. + - `[in] finalize_cb`: Native callback that will be used to free the + native data when the JavaScript object is ready for garbage-collection. + - `[in] finalize_hint`: Optional contextual hint that is passed to the + finalize callback. + - `[out] result`: Optional reference to the JavaScript object. + +Returns `napi_ok` if the API succeeded. + +Adds a `napi_finalize` callback which will be called when the JavaScript object +in `js_object` is ready for garbage collection. This API is similar to +`napi_wrap()` except that +* the native data cannot be retrieved later using `napi_unwrap()`, +* nor can it be removed later using `napi_remove_wrap()`, and +* the API can be called multiple times with different data items in order to + attach each of them to the JavaScript object. + +*Caution*: The optional returned reference (if obtained) should be deleted via +[`napi_delete_reference`][] ONLY in response to the finalize callback +invocation. If it is deleted before then, then the finalize callback may never +be invoked. Therefore, when obtaining a reference a finalize callback is also +required in order to enable correct disposal of the reference. + ## Simple Asynchronous Operations Addon modules often need to leverage async helpers from libuv as part of their @@ -4559,6 +4616,7 @@ This API may only be called from the main thread. [Working with JavaScript Values]: #n_api_working_with_javascript_values [Working with JavaScript Values - Abstract Operations]: #n_api_working_with_javascript_values_abstract_operations +[`napi_add_finalizer`]: #n_api_napi_add_finalizer [`napi_async_init`]: #n_api_napi_async_init [`napi_cancel_async_work`]: #n_api_napi_cancel_async_work [`napi_close_escapable_handle_scope`]: #n_api_napi_close_escapable_handle_scope diff --git a/doc/api/os.md b/doc/api/os.md index a0ff5e7ff17bf0..ad5736d7690016 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -371,6 +371,9 @@ priority classes, `priority` is mapped to one of six priority constants in mapping may cause the return value to be slightly different on Windows. To avoid confusion, it is recommended to set `priority` to one of the priority constants. +On Windows setting priority to `PRIORITY_HIGHEST` requires elevated user, +otherwise the set priority will be silently reduced to `PRIORITY_HIGH`. + ## os.tmpdir() -* `buffer` {Buffer} A `Buffer` containing the bytes to decode. +* `buffer` {Buffer|TypedArray|DataView} A `Buffer`, or `TypedArray`, or + `DataView` containing the bytes to decode. * Returns: {string} Returns any remaining input stored in the internal buffer as a string. Bytes @@ -79,10 +80,11 @@ changes: character instead of one for each individual byte. --> -* `buffer` {Buffer} A `Buffer` containing the bytes to decode. +* `buffer` {Buffer|TypedArray|DataView} A `Buffer`, or `TypedArray`, or + `DataView` containing the bytes to decode. * Returns: {string} Returns a decoded string, ensuring that any incomplete multibyte characters at -the end of the `Buffer` are omitted from the returned string and stored in an -internal buffer for the next call to `stringDecoder.write()` or -`stringDecoder.end()`. + the end of the `Buffer`, or `TypedArray`, or `DataView` are omitted from the + returned string and stored in an internal buffer for the next call to + `stringDecoder.write()` or `stringDecoder.end()`. diff --git a/doc/api/url.md b/doc/api/url.md index 571c3bdfdbfabb..cd817bf304b19e 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -880,6 +880,28 @@ console.log(url.domainToUnicode('xn--iñvalid.com')); // Prints an empty string ``` +### url.fileURLToPath(url) + +* `url` {URL | string} The file URL string or URL object to convert to a path. +* Returns: {string} The fully-resolved platform-specific Node.js file path. + +This function ensures the correct decodings of percent-encoded characters as +well as ensuring a cross-platform valid absolute path string. + +```js +new URL('file:///C:/path/').pathname; // Incorrect: /C:/path/ +fileURLToPath('file:///C:/path/'); // Correct: C:\path\ (Windows) + +new URL('file://nas/foo.txt').pathname; // Incorrect: /foo.txt +fileURLToPath('file://nas/foo.txt'); // Correct: \\nas\foo.txt (Windows) + +new URL('file:///你好.txt').pathname; // Incorrect: /%E4%BD%A0%E5%A5%BD.txt +fileURLToPath('file:///你好.txt'); // Correct: /你好.txt (POSIX) + +new URL('file:///hello world').pathname; // Incorrect: /hello%20world +fileURLToPath('file:///hello world'); // Correct: /hello world (POSIX) +``` + ### url.format(URL[, options])